Thursday, August 25, 2005

I've just done a webcast, which was effectively a repeat of my MEDC'05 presentation on hosting ActiveX controls in CF 2.0. It can be seen here

Update (09/03/2005). It is apparently not entirely clear from the webcast, where the source code is. It can be found here

Update 2 (09/03/2005). The source code will not compile on beta 2 of Visual Studio because of Marshal.AllocHGlobal/FreeHGlobal that were not introduced until July CTP. Simply replace them with AllocCoTaskMem/FreeCoTaskMem

Update 3 (09/03/2005). TO be able to host WMP in Pocket PC application you must have WMP10. WMP9 did not have an ActiveX interface. Some (but not all) of the 2003SE device have WMP10. All WM5 devices will have WMP10

8/25/2005 4:40:44 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [3]  | 
 Thursday, August 04, 2005

I live in California. It is quite common to see things here written in both English and Spanish. I suspect that there might be even a law that mandates having Spanish translation available for certain public establishments. Having said this, I admit I did a double-take when I saw a list of services offered by the Customer Service department of out local supermarket:

Notice “Check cashing” and immediately after it “Cheque cashing”. Apparently we here have a lot of respect for our neighbors across the pond and their cute if peculilar way to spell things.

8/4/2005 6:54:18 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [0]  | 
 Tuesday, August 02, 2005

Yesterday Peter Foot has released his suite of Windows Mobile APIs for .NETCF (http://www.inthehand.com/1stAugust2005.aspx). This is an evolution of the PocketOutlook library which now incorporates Email and SMS functionality. Along with this are a selection of other assemblies for Configuration, System Status and Telephony. Very cool!

8/2/2005 9:07:56 AM (Pacific Daylight Time, UTC-07:00)  #    Comments [0]  | 
 Friday, July 01, 2005
Looking at the flash animation - "How it works" for Verizon in-home fiber-optic internet service... They offer speeds up to 30Mbps down/5 up
At some point they go to explain why is their service so fast (compared to traditional broadband providers). Apparently it is because "the light travels so quickly". Of course! Silly me. I totally forgot that an average speed of an electron in a copper wire is about 1.5 mm/s. That explains my sluggish internet connection.
 
On a related note. SBC at some point announced the plans to deploy fiber connectivity option to the consumers. The deployment project was called "Project Lightspeed". Catchy... Then they announced plans to accelerate the deployment (after FCC lifted some restrictions). Ars Technica suggests that the project should be now named "Project FTL"
Computers | Life | Rant
7/1/2005 4:20:32 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [27]  | 
 Tuesday, May 24, 2005

... or is it Superman?

The kind folks, who administer MSDN webcasts, sent me as one of the year 2005 presenters a shirt and a ... cape. Yes, a red cape.

5/24/2005 11:42:31 AM (Pacific Daylight Time, UTC-07:00)  #    Comments [0]  | 
 Wednesday, April 20, 2005

I've been asked for assistance with the following issue today. A developer has a CAB that he wants to install on the device without using CeAppMgr, from his own setup application. In addition he wanted to force the installation to the storage card if present.

This task involves several steps:

  1. Copy CAB to the device
  2. Detect storage card presence
  3. Launch wceload.exe to install the cab

1. Copying CAB to the device.

I would use cecopy (from Windows Mobile Developer Power Toys) or RAPI (CeCreateFile, CeWriteFile). If working with managed code, I suggest OpenNETCF.Communications library, or RapiDeploy tool

2. Detecting storage card presence.

While on the device side the preferred method is to use FindFirstFlashCard/FindNextFlashCard, these functions do not have Rapi equivalent. From the desktop side use CeFindAllFiles/FAF_FOLDERS_ONLY (or CeFindFirstFile/CeFindNextFile) to search the root directory and enumerate all files for having FILE_ATTRIBUTE_DIRECTORY and FILE_ATTRIBUTE_TEMPORARY combination of attributes (0x110).

3. Launch wceload.exe to install the cab

This is the interesting part. Here is a list of command-line switches that wceload.exe supports:

  • /delete - if value = 0 do not delete cab after install
  • /noui - perform a silent operation. Do not ask if it is ok to overwrite the exiting files
  • /nouninstall - do not create a .uninstall file. The applciation entry will not appear in Remove Programs list
  • /askdest - will force wceload to display a dialog that allows user to select installaltion location and some other things
  • /noaskdest - install specified applications to specified locations (see below)

 


Dialog displayed by wceload when /askdest is specified

The /noaskdest switch is the most inetersting of them all. When you specify it, wceload ignores the rest of the command line. Instead it checks the following registry location - [HKEY_LOCAL_MACHINE\SOFTWARE\Apps\Microsoft Application Installer\Install]

The key contents are key/value pairs:
[CAB file path] = [CAB destination directory]
e.g. \Storage Card\MyApp.CAB = \Storage Card\Program Files\My App

wceload will try to install the cab specified in the value name to the location specified in the value value. Below is the sample registry content:

To reiterate: in order to install a cab to the memory card, one needs to:

  1. Copy CAB to the device (e.g. to the memory card)
  2. Create a registry value on the device specifying the cab location and cab destination
  3. Launch wceload.exe with /noaskdest parameter
4/20/2005 5:52:05 PM (Pacific Daylight Time, UTC-07:00)  #    Comments [5]  | 
 Wednesday, March 09, 2005

Preface:
===========================
The President: C'mon, let me nuke that bastard.
Commander Gilmour: Are you suggesting that we blow up the moon?
The President: Would you miss it?
[looks around the table]
The President: Would you miss it?
============================ [Austin Powers, The Spy, Who Shagged Me] =========

The programming world has its panties in uproar. In just over two weeks Microsoft ends the support cycle of the VB6 and VBA products. A group of MVPs has initiated a petition asking Microsoft to stop this insanity. Not only they want for MS to rescind the end-of-support decision, but they actually demand continued development and, unbelievably, integration of VB6 into Visual Studio product alongside with .NET languages. I probably would not be able to state my opinion on this better than Geoff Appleby did, so I'll just say nothing. Except of maybe this.

What support? The VB6 support has been lately done by the MVPs - the people who have drafted and  signed the aforementioned petition. They are absolutely free to continue to do so. The future security patches will necessarily cover the VB components. But no new development (see preface).

I am not a VB-hater (does such category even exist?). But I know from my own newsgroup support experience the amount of harm a loose, poorly structured language like VB brings. I wrote my share of VB6 code and the company I work for uses it extensively, but I moved on and the company is moving on. Hey, I love my car, but I realize one day I will have to buy a new car.

Get over it. And learn some new tricks along the way. World does not stand in place. It moves along.

3/9/2005 11:14:57 PM (Pacific Standard Time, UTC-08:00)  #    Comments [26]  | 
 Thursday, February 24, 2005

The Toolbar control provided as a part of Compact Framework v1.0 does not support tooltips (they are shown when you tap and hold toolbar button). Here is how to add this missing functionality.

First of all, let's see how the tooltips are added. The proper way to do it is to create a tooltip control and pass its handle to the TB_SETTOOLTIPS message as wParam. This sounds pretty painful if we were to do this by means of CF. Fortunately there is an easier way listed in the documentation as legacy but supported all the way through CE 5.0. You can send TB_SETTOOLTIPS passing an array of tooltip strings as lParam and string count as wParam and the toolbar control will create a tooltip control for you. Finally one has to remember to modify toolbar style to include TBS_TOOLTIP and do all of the above before adding the buttons to the toolbar.

Armed with this knowledge we start with defining a few P/Invoke functions:


[DllImport("coredll")]

extern static IntPtr GetCapture();

[DllImport("coredll")]

extern static IntPtr LocalAlloc(int flags, int size);

[DllImport("coredll")]

extern static IntPtr LocalFree(IntPtr p);

[DllImport("aygshell")]

extern static IntPtr SHFindMenuBar(IntPtr hwnd);

[DllImport("coredll")]

extern static int SendMessage(IntPtr hWnd, int msg, int wParam, IntPtr lParam);

[DllImport("coredll")]

extern static int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

const int TB_SETTOOLTIPS = (WM_USER + 81);

const int TB_SETSTYLE = (WM_USER + 56);

const int TB_GETSTYLE = (WM_USER + 57);

const int TBSTYLE_TOOLTIPS = 0x0100;

const int WM_USER = 0x0400;

Now, that we are almost ready to set tooltips, there is one final step left. The control expects to receive an array of string pointers. The Compact Framework marshaller is not capable of creating one. Instead we write a special piece of code that would marshal an array of strings into a block of unmanaged memory.

To add tootlips we create a string array, convert it into unmanaged array and then use it as the LPARAM when sending a TB_SETTOOLTIPS message. Keep in mind that the tooltip control will expect this memory to be preserved throught the application lifetime. Release it when the form is closed (or the tooltips are changed).

private IntPtr m_pLabels;

private string[] m_labels = new string[]
{ "Button1", "Button2", "Another button" };

SendMessage(hWndToolbar, TB_SETSTYLE, 0, SendMessage(hWndToolbar, TB_GETSTYLE, 0, 0) | TBSTYLE_TOOLTIPS);

m_pLabels = AllocateStringArray(m_labels);

SendMessage(hWndToolbar, TB_SETTOOLTIPS, m_labels.Length, m_pLabels);

The end result looks like this:

The sample code can be found here.

2/24/2005 7:14:38 PM (Pacific Standard Time, UTC-08:00)  #    Comments [0]  |