Blog

  • 5 Things

    Daniel tagged me a couple of days ago and finally I’ve got round to posting. I’ve been enjoying some quality offline time over the Christmas break.



    1. I’m in the process of writing a .NET book with Daniel and fellow MVP Andy.

    2. I’m double jointed and can put my legs behind my head, but I’m getting a little rusty in my old age.

    3. While trying to buy a practical car I was let down twice by a dealership, so I went elsewhere and got myself a much more impractical 2 seat convertible and have thoroughly enjoyed it.

    4. Before studying Computer Science I briefly entered the world of bricks and mortar training as an architect.

    5. I enjoy travelling to new places, this year I spent a month in Australia, somewhere I’d definitely like to revisit.

    And finally to tag 5 new victims bloggers – Bill, Dave, Rob, João Paulo and John


  • Pastie McCode

    Is Pastie McCode the next Barry Scott? Well probably not, but if you are a UK business who is interested in getting up to speed with Vista and Office 2007 then you may want to find out more.


    http://ukvistaofficelaunchtour.spaces.live.com/

  • Make Individual TreeView Nodes Bold

    The full framework TreeView control supports setting a Font on a per-node basis, the Compact Framework control doesn’t support this, however with a little interop magic you can mark individual nodes as Bold. Because the .NETCF v2.0 TreeView control exposes it’s own window handle, and each TreeNode also exposes it’s handle, we have all the raw data we need to format the node. First we need to define a structure and a couple of enumerations:-


    internal struct TVITEM
    {
    public TVIF mask;
    public IntPtr hItem;
    public TVIS state;
    public TVIS stateMask;
    [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
    string pszText;
    int cchTextMax;
    int iImage;
    int iSelectedImage;
    int cChildren;
    int lParam;
    }

    [Flags()]
    internal enum TVIF
    {
    TEXT =0x0001,
    IMAGE =0x0002,
    PARAM =0x0004,
    STATE =0x0008,
    HANDLE =0x0010,
    SELECTEDIMAGE =0x0020,
    CHILDREN =0x0040,
    }

    [Flags()]
    internal enum TVIS
    {
    SELECTED =0x0002,
    CUT =0x0004,
    DROPHILITED =0x0008,
    BOLD =0x0010,
    EXPANDED =0x0020,
    EXPANDEDONCE =0x0040,
    EXPANDPARTIAL =0x0080,

    OVERLAYMASK =0x0F00,
    STATEIMAGEMASK =0xF000,
    USERMASK =0xF000,
    }


     


    Then I’ve created a single static method which can set the bold state of any node:-


    public static void SetNodeEmphasis(TreeNode n, bool bold)
    {
    //get the control and node handles
    IntPtr hTreeview = n.TreeView.Handle;
    IntPtr hNode = n.Handle;

    //create a TVITEM struct
    TVITEM t = new TVITEM();
    t.hItem = hNode;
    //mark only the handle and state members as valid
    t.mask = TVIF.HANDLE | TVIF.STATE;
    //set the state to bold if bold param was true
    t.state = bold ? TVIS.BOLD : 0;
    //set statemask to show we want to set the bold state
    t.stateMask = TVIS.BOLD;

    //pin the struct in memory
    GCHandle hTVITEM = GCHandle.Alloc(t, GCHandleType.Pinned);
    //create a TVM_SETITEM message with the handle of our pinned struct
    Microsoft.WindowsCE.Forms.Message m = Microsoft.WindowsCE.Forms.Message.Create(hTreeview, 0x113F, IntPtr.Zero, hTVITEM.AddrOfPinnedObject());
    //send the message to the treeview
    Microsoft.WindowsCE.Forms.MessageWindow.SendMessage(ref m);
    //free the pinned structure
    hTVITEM.Free();
    }


    The method is easy to reuse as you only need to pass the TreeNode in, it will grab the handle of the parent control from the node itself. After applying the formatting to a couple of nodes you’ll get something like this:-


     

  • Bluetooth DUN Profile Removed from WM5.0 AKU3

    While there have been some improvements to Bluetooth support through the version – like the addition of A2DP (Wireless Stereo) and most recently PAN in AKU3, at the same time the Dial Up Networking profile has been removed. This is a very widely supported profile for connectivity sharing. If you previously used your Windows Mobile device to share your GPRS connection you’ll no longer be able to do this with newer devices running AKU3 (or perhaps if any OEMs offer ROM updates to AKU3 for current devices). One scenario I’ve already encountered where this is a problem is using a TomTom ONE/Go unit – these use Bluetooth to use your phones connectivity to download traffic updates etc, and they support only the DUN profile.


    Read a discussion about these changes here on Smartphone Thoughts.

  • Using MessageInterceptor to launch an application on SMS

    First things first a disclaimer, the following code is written for Mobile In The Hand (Professional Edition), it does apply equally to a Windows Mobile 5.0 project with the Microsoft.WindowsMobile managed APIs, you’ll just need to change the namespaces and assembly references.


    A normal MessageInterceptor is valid only for the lifetime of your application, once you shut down you’ll no longer be able to respond to messages that match your rule. In many cases you’ll want a specific message to launch your application and then process as normal. The IApplicationLauncher interface which MessageInterceptor implements contains methods to set this up. This allows the system to start your application, optionally with command line arguments of your choosing. This is useful so that you can tell when your app was called by an incoming SMS and when launched manually. The following code snippet is called in Form_Load, it checks for an existing registration, if not present it sets up all the required settings. The ApplicationLaunchId is a string which is unique to your application, if you try to register with an id which is already in use you’ll receive an Exception.


    if (InTheHand.WindowsMobile.PocketOutlook.MessageInterception.MessageInterceptor.IsApplicationLauncherEnabled(“testapp”))
    {
        mi = new InTheHand.WindowsMobile.PocketOutlook.MessageInterception.MessageInterceptor(“testapp”);
    }
    else
    {
        mi = new InTheHand.WindowsMobile.PocketOutlook.MessageInterception.MessageInterceptor(InTheHand.WindowsMobile.PocketOutlook.MessageInterception.InterceptionAction.NotifyAndDelete);
        mi.MessageCondition = new InTheHand.WindowsMobile.PocketOutlook.MessageInterception.MessageCondition(InTheHand.WindowsMobile.PocketOutlook.MessageInterception.MessageProperty.Body, InTheHand.WindowsMobile.PocketOutlook.MessageInterception.MessagePropertyComparisonType.StartsWith, “test:”, false);

        mi.EnableApplicationLauncher(“testapp”,“Program FilesInterceptorTestInterceptorTest.exe”);
    }

    mi.MessageReceived += new InTheHand.WindowsMobile.PocketOutlook.MessageInterception.MessageInterceptorEventHandler(mi_MessageReceived);


    Finally the event handler just displays the message body in a MessageBox:-


    void mi_MessageReceived(object sender, InTheHand.WindowsMobile.PocketOutlook.MessageInterception.MessageInterceptorEventArgs e)
    {
        MessageBox.Show(((InTheHand.WindowsMobile.PocketOutlook.SmsMessage)e.Message).Body, “Message”);
    }

    Download the skeleton project: InterceptorTest.zip (11.08 KB)

  • .NET Framework 3.0 Released

    I’m still not a huge fan of the naming system used – v3.0 is the v2.0 framework with what was previously known as WinFX added – Windows Communication Foundation, Windows Presentation Foundation and Windows Workflow. You can download the redistributable here:-

     

    http://www.microsoft.com/downloads/details.aspx?familyid=10cc340b-f857-4a14-83f5-25634c3bf043&displaylang=en

  • Bluetooth Audio in Vista

    The Bluetooth functionality (and related APIs) are fundamentally unchanged between XP and Vista, however additional profile support has been added for Audio devices. Based on testing with the RC2 build Vista now supports:-

     

     

    • Handsfree
    • Headset
    • A2DP (Wireless Stereo)

     

    When Vista detects a new audio device it doesn’t automatically install support for the audio services, but it does recognise hands free devices based on their Class-of-Device:-

     

     

    If you select the device properties, and view the Services tag you can see and select the supported audio profiles and when you apply the settings a new Audio device will be installed.

     

     

    You can set these programmatically using 32feet.NET with the BluetoothDeviceInfo.SetServiceState method passing in either BluetoothService.Headset or Handsfree. The audio device appears in the Sounds control panel applet, but doesn’t override the default system audio. You are unlikely to want to do this with a headset anyway, although it’s more likely you’ll want to do this with stereo headphones. You can however select this audio device to use with audio conferencing software such as Skype or Windows Messenger or with Vista’s speech recognition.

  • Bug in GAC Installation from VS2005 Device CAB Projects

    I recently ran into a problem with a Smart Device CAB Project in Visual Studio 2005, which as it turns out is a known issue. You can build a CAB file which will register your .NETCF dlls into the GAC – the File System Editor has a standard folder called “Global Assembly Cache Folder” which you can put your files into. Behind the scenes this deploys the dlls to the windows folder and generates a .GAC text file with a list of paths to your dll(s). The problem is that the generated GAC file is a Unicode text file and doesn’t work on devices prior to Windows Mobile 5.0. I’m assuming the same is true with generic CE 4.2 devices versus CE 5.0. In itself this seems bizarre since CE is fully Unicode based so shouldn’t have any problem reading the file. It just so happens that when you are doing this the old fashioned way with notepad you get an ANSI text file which works just fine on all devices.


    The workaround is simple, don’t use the whizzy GAC support in the CAB project, place your dlls into the Windows Folder, and manually create a .GAC text file and place this in the Windows Folder also. The downside to this approach is that you must update your GAC file if you add or remove dlls from your setup project. I’d like to say thanks to fellow MVP Jan Yeh for helping to test the issue and to Manish Vasani from the Visual Studio for Devices team for following up with more details on the issue.

  • Hacking the Parrot 3000 Evolution Car Kit

    Recently I tried a different form of Bluetooth hacking, I purchased a simple car kit and wanted to install it myself. Alongside the kit itself I also purchased the required vehicle specific cable to sit between the vehicle wiring and the radio and connect in the Parrot loom. However I soon realised that it was going to be more difficult than originally anticipated because there wasn’t enough space behind the dash to accomodate all the bulky connectors, relaybox and oceans of cables. There were two issues, the adaptor cable passed through every single cable from the vehicle connector even though only a select few were actually used, the inline ISO connectors are rather chunky, the radio itself supports a phone input and mute trigger and so it seemed unnecessary to have the parrot amplify the audio and output it directly to the speakers.


    So I set about looking at what was happening before the relay box and was able to determine the pinouts on the Parrot unit itself. The next stage was to simplify the adapter cable to remove unnecessary passthrough wires and remove the inline ISO connectors. I had to directly solder in Power, Earth and Mute wires from the Parrot and connect up the mono phone input to the “raw” output from the Parrot. The only additional wiring required was vehicle specific as there isn’t an ignition switched power into the radio as it uses the CAN bus to change state. So I ran the ignition line for the Parrot into the connector with the vehicles cigar ligher socket (on some cars this is permanently powered on mine it’s only on with the ignition). I was then able to mount the Parrot box behind the dashboard and route all the wiring behind the vehicle trim. Using this approach has the added benefit of supporting the external volume adjustment through the radio (and hence steering wheel controls). For reference the pin out for the Parrot CK3000 Evolution is as below (Other Parrot models use rather different plugs so I doubt it’s transferrable).


    Aud-    Earth   Aud+   Mute


    White   Black   Red    Blue   Yellow


     X       X       X      X      X


     X       X       X


    Red     Yellow  Blue


    (used by control panel)


    The unused yellow wire is perhaps used by the optional flashing cable. The separate power connector contains three colour coded wires (which are labelled so I wont spell them out here)

  • SelectPictureDialog.LockDirectory property

    If you refer to the original Windows Mobile 5.0 documentation (or the Intellisense) when using this component you’ll notice it has a property called LockDirectory which is supposed to prevent the user from browsing outside of the folder you specified in InitialDirectory. To cut a long story short this property is not implemented and setting it will not affect the behaviour of the dialog. The online MSDN documentation has since been updated to indicate this.


    When faced with this problem my first thought was to look at the native API which this component uses (GetOpenFileNameEx) and P/Invoke it since the documentation still indicates that there is a flag to achieve this behaviour. However as it turns out this too is unimplemented. It was a late change in Windows Mobile 5.0 and hence the SDK and documentation were innacurate.