Wednesday, August 13, 2008
Today I saw two separate posts on pretty much teh same question.  How can you determine if the foreground window changes in a WinMo application?  Moreover, how can you determine if the new foreground window is your own, or in some other process?  My initial thoughts were to do some work in the Form's Deactivate event, but that would lead to having to plumb it into every Form, and then you'd still need special case handlers for MessageBoxes and Dialogs and it would be an unmaintainable pain in the ass. I decided to put some time aside this afternoon and see if I could come up with a better solution, and what I came up with is outlined in a new article entitled 'Determining Form and Process Changes in Windows CE'.

8/13/2008 6:14:58 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0]  | 
 Friday, August 01, 2008
It seems that every time I work on a project I get near the end and have to deal with actual deployment of the application and things go south.  Let's face it, Microsoft's wceload application sucks - and that's being generous. It's limited, it's got no object model, and it's behavior has changed over time without any of those changes being documented.

In a recent project I was trying to silently install an application to a directory that would change depending on the target hardware becasue different devices have their storage media named differently.  I wanted to do this without changing or having multiple CAB files, since the application was no different. Achieving this with wceload, I am convinced, is utterly impossible so I put on my reverse-engineering hat, downloaded the CAB spec (cabfmt.doc), and went to work.  Now, a few month later, and with the help of Alex Feinman, we've created a new product called the Windows CE CAB Installer SDK.  In addition to a new product, we went with a new pricing model as well.

The SDK comes with full source,  unit and integration tests designed for running under mstest, samples for generating compressed and uncompressed CAB (the SDK supports both), a template for creating custom installer DLLs and both VB and C# examples of using the SDK.

The main workhorse of the SDK is the WinCEInstallerFIle class, which looks like this:



An example of a custom installer looks like this (just to give you a flavor of how it works):

using System;

using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using OpenNETCF.Compression.CAB;

namespace System.Runtime.CompilerServices
{
public class ExtensionAttribute : Attribute
{
}
}

namespace ONCFInstall
{
public delegate void FileProgressHandler(int progressPercent);

public static class Extensions
{
public static string Find(this List list, string findString)
{
foreach (string file in list)
{
if (string.Compare(file, findString, true) == 0)
{
return file;
}
}
return null;
}
}

public class CustomCABInstaller : WinCEInstallerFile
{
private int m_fileCount = 0;
private CommandLineArgs m_args;

public event FileProgressHandler FileProgress;

public CustomCABInstaller(string cabFileName, CommandLineArgs args)
: base(cabFileName)
{
m_args = args;
SkipFileNames = m_args.SkipFiles ?? new List();
PathStringReplacements = m_args.PathStringReplacements ?? new Dictionary();
SkipOSVersionCheck = m_args.SkipOSVersionCheck;
}

/// /// List of file names to skip during installation /// public List SkipFileNames { get; set; }

/// /// List of path replacement strings /// public Dictionary PathStringReplacements { get; set; }

/// /// If true, the installer will not check to ensure the target meets the installer's version requirements
///
public bool SkipOSVersionCheck { get; set; } public override void OnInstallBegin() { m_fileCount = 0; } public override void OnTargetOSVersionCheck() { // check to see if we should skip the OS version check if (!SkipOSVersionCheck) { base.OnTargetOSVersionCheck(); } } public override void OnInstallFile(ref FileInstallInfo fileInfo, out bool skipped) { // check to see if it's a name we should skip if (SkipFileNames.Find(fileInfo.FileName) != null) { Utility.Output(string.Format("Skipping file '{0}'", fileInfo.FileName)); skipped = true; return; } // do any path replacements foreach (KeyValuePair val in PathStringReplacements)
{
fileInfo.DestinationFolder = fileInfo.DestinationFolder.Replace(val.Key, val.Value);
}

Utility.Output(string.Format("Installing '{0}' to '{1}'", fileInfo.FileName, fileInfo.DestinationFolder));

base.OnInstallFile(ref fileInfo, out skipped);

if (FileProgress != null)
{
FileProgress((++m_fileCount * 100) / FileCount);
}
}
}
}

8/1/2008 3:42:52 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0]  | 
 Monday, May 19, 2008
We've published a new article on the OpenNETCF Community Site titled "Native vs. Managed Code: GDI Performance"
 
 
In it, I look at the performance differences between native and managed code making GDI calls.
 
In case you missed them, our other recently published articles include:
 
- Performance Implications of Crossing the P/Invoke Boundary
- An Introduction to WCF for Device Developers
- Getting a Millisecond-Resolution DateTime under Windows CE
- Using GDI+ on Windows Mobile
- Sharing Windows Mobile Ink with the Desktop
- OpenNETCF Mobile Ink Library for Windows Mobile 6
- Improving Data Access Performance with Data Caching
- Developing Connected Smart Device Applications with sqlClient
- Debugging Without ActiveSync
- Image Manipulation in Windows Mobile 5.0
- Don't Fear the Garbage Collector
 
All of our articles are available online at:
http://community.OpenNETCF.com/articles
 
5/19/2008 12:27:16 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0]  | 
 Friday, April 18, 2008

Ever since learning how to use function pointers in C, I've always been a fan of using them to help make code a bit more usable, especially when you've got a state machine.  Today, as I'm working on a Wizard UI for a desktop application I came across a typical scenario for using a function pointer.  Depending on the stage of the Wizard you're in, a button will have to do separate things.

That got me to thinking that most managed developers simply don't understand the power and utility of delegates, but instead simply consider them a necessity when using Control.Invoke or creating custom events. Sure, in my case I could have a switch statement in the click handler and do logic there, or I could unhook the click handler from one method and hook it to another, but those all seem ugly and a pain in the ass to me.  A simple function pointer change is all you need.  So I decided I'd throw together a really simple example of how you would use a delegate to change the behavior of a Button click.

Let's assume that we have a button that we want to click, and when it's clicked it will do one of 4 things, depending on the state of our application.  We'll just use a messagebox here to give you the idea - what it does is up to you- it's a function after all.

public void FunctionA()
{
  MessageBox.Show("FunctionA");
}

public void FunctionB()
{
  MessageBox.Show("FunctionB");
}

public void FunctionC()
{
  MessageBox.Show("FunctionC");
}

public void FunctionD()
{
  MessageBox.Show("FunctionD");
}

To simulate the different "states" I simply added a ListBox (called functionList) to the Form and manually added the function names to it in the Form's constructor.  Sure, I could have used Reflection to be clever and populate the list, but I'm tryiong to keep it simple and show delegates.

functionList.Items.Add("FunctionA");
functionList.Items.Add("FunctionB");
functionList.Items.Add("FunctionC");
functionList.Items.Add("FunctionD");

Alright, so now we know that depending on which item is selected, we want to call one of our four functions.  Since they all have the same interface (and they have to to use a delegate) we simply define a delegate that matches them.  This delegate can be privately scoped inside your class.

delegate void FunctionDelegate();

And then we create an instance variable to hold the current function pointer we want to use:

private FunctionDelegate m_functionPointer = null;

We add an event handler for the SelectedIndexChanged event of the ListBox (in the Form constructor)

functionList.SelectedIndexChanged += new EventHandler(functionList_SelectedIndexChanged);

And implement the event handler.  It simply looks at the newly selected index in the list and changes the value stored in m_functionPointer appropriately.

void functionList_SelectedIndexChanged(object sender, EventArgs e)
{
  // determine which function pointer to store based on selection
  switch (functionList.SelectedIndex)
  {
    case 0:
      m_functionPointer = FunctionA;
      break;
    case 1:
      m_functionPointer = FunctionB;
      break;
    case 2:
      m_functionPointer = FunctionC;
      break;
    case 3:
      m_functionPointer = FunctionD;
      break;
    default:
      m_functionPointer = null;
      break;
  }
}

Next we wire up an event handler for our button (again the the Form constructor):

callButton.Click += new EventHandler(callButton_Click);

And finally the magic and simplicity of the state-dependent call

void callButton_Click(object sender, EventArgs e)
{
  // call our function (as long as it's not null)
  if (m_functionPointer != null)
  {
    m_functionPointer();
  }
}

That's all there is to it.  Run the application, select a function and click the button.

Get the full source here.

4/18/2008 6:07:46 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [3]  | 
 Thursday, December 06, 2007

So I picked up a cheap PTZ (pan/tilt/zoom) camera off eBay a couple weeks ago for doing some R&D on a project I'm working on.  My hope was I'd be able to hook it up and talk to it from a device and get streaming video into an app.  Well it turns out that it's not so simple.  All cameras appear to have some form of proprietary interface that obviously varies from OEM to OEM.

I hooked up WireShark in hopes that I could reverse engineer the network commands fromthe packets, but it looks like it would take me weeks to get it figured out, and I don't have that kind of time (or desire) so I shot off an email to the OEM.  While I wait for them to reply (if they ever do) I went about reverse-engineering a kludge.

The device has a built in web server that allows you to control the camera, view video, etc.  So I opened up a page and looked at the source.  It contained a frameset, so I started navigating through frame pages and deconstructing the html to see what commands did what.  Unfortunately the video streaming piece appears to be in a compiled Java applet so getting at that turned out to be a dead-end, however it wasn't a total loss.  I did figure out how to send it commands to pan, tilt and capture single frames (well I figured out a lot more, but I limited my implementation to those functions for now).

So armed with what I knew, I slapped together the following class, basically simulating myself as a browser:

using System;
using System.Net;
using System.Net.Sockets;
using System.Drawing;
using System.IO;
using System.Threading;
using OpenNETCF.Peripherals.Camera;

namespace OpenNETCF.Peripherals
{
  public class MegaTecCamera : ICamera
  {
    private const int CMD_UP = 1;
    private const int CMD_DOWN = 2;
    private const int CMD_LEFT = 3;
    private const int CMD_RIGHT = 4;

    private string m_ip;
    private string m_username;
    private string m_password;

    public MegaTecCamera(IPAddress address, string username, string password)
    {
        m_ip = address.ToString();
        m_username = username;
        m_password = password;
    }

    public Image GetImage()
    {
        Image img = null;

        string command = string.Format(http://{0}/pda.cgi?user={1}&password={2}&page=image&cam=1
            m_ip, m_username, m_password);

        byte[] buffer = new byte[10000];
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(command);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        using (Stream stream = response.GetResponseStream())
        {
            try
            {
                img = new Bitmap(stream);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("Capture failed: " + ex.Message);
            }

            response.Close();
        }
        return img;
    }

    public void Pan(PanDirection direction)
    {
        if (direction == PanDirection.Left)
            SendHttpCommand(GetDirectionCommand(CMD_LEFT));
        else
            SendHttpCommand(GetDirectionCommand(CMD_RIGHT));
    }

    public void Tilt(TiltDirection direction)
    {
        if (direction == TiltDirection.Up)
            SendHttpCommand(GetDirectionCommand(CMD_UP));
        else
            SendHttpCommand(GetDirectionCommand(CMD_DOWN));
    }

    private string GetDirectionCommand(int direction)
    {
        return string.Format(http://{0}/pda.cgi?user={1}&password={2}&page=execute&cam=1&command={3},
            m_ip, m_username, m_password, direction);
    }

    private void SendHttpCommand(string command)
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object o)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(command);
            try
            {
                request.GetResponse().Close();
            }
            catch { }
        }));
    }
  }
}

The next obvious question is "What the hell do I do with this class that is of any use?"

Well that's the fun part!  I integrated it into a sample page on our demo Padarn server, so we now have images captured from an IP camera streamed back to a 200MHz Windows CE device that in turn serves up those images (and control of the camera) using an ASP.NET server.

The next step I'll add is the ability to turn on and off the light in the room via a web page.

 

12/6/2007 6:15:00 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Thursday, November 29, 2007
In case you missed it, I published a new article on our community site last week on how to get a DateTime.Now equivalent with the milliseconds field filled in.  Read it here.

11/29/2007 11:20:53 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Friday, September 28, 2007
Mark has just published a couple articles with just about everything you could want to know about inking:

Using the OpenNETCF Mobile Ink Library for Windows Mobile 6
Sharing Windows Mobile Ink with the Desktop

9/28/2007 4:37:14 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0]  | 
 Thursday, September 06, 2007

So we've already gotten a submission for this month's coding competiton called FlowFx, and I must say it's pretty damned nice.  I'd say this one sets the bar for the quality of what needs to be submitted.

Take a look at the video of the UI in action.

Enter your Windows Mobile or Embedded code for a change to win some cool prizes this month and every month at http://community.opennetcf.com

9/6/2007 6:29:24 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0]  | 
 Friday, June 08, 2007

A friend of mine is working on a project that he's been having some major stability problems with.  All of these issues seem to be related with interop to a Sybase database.

After working on and off with him for the past few months, it seems that the root of the problems lie in the fact that a previous developer had written some functions in a "shim" native DLL that calls intoo Sybase, so instead of P/Invoking the Sybase stuff, the developer created a wrapper DLL that he P/Invoked.

After looking at some of the wrapper two things were obvious.  First, the Sybase functions were undecorated C functions, so the shim was unnecessary in the first place, and second, the developer's skill with C are terrible and the shim he created was likely the cause of the problems. So I recommended throwing out the shim, as it was garbage and it was completely unnecessary.

That lead to yet more questions - most notably "how do I marshal X or Y" type things along with "how the hell does one figure this stuff out" and "is this stuff documented anywhere?"  Well other than experience I know of little for figuring it out, and once you get beyond the capabilities of the CF's marshaler I also know of know real documentation.  So I decided I'd put together a fairly simple example of complex marshaling (yes, simple complex).

So first let's look at a typical scenario.  The Sybase stuff often takes in pointers to big, ugly structures.  These structures contain pointers.  Sometimes they are pointers to ASCII strings.  Well instead of wrapping one of these big nasty things, let's create a small representative example that you as a reader can expand upon.

The Native Side

Let's create a native DLL that exports one funtion that takes a fairly easy-to-grasp structure.  The function will simply present a MessageBox with the info.  So here's a structure:

typedef struct MESSAGE_INFO
{
    char *message;
    WORD length;
    DWORD number;
} MESSAGE_INFO;

Note that 'message' is a char *, indicating ASCII.  I'd never write a CE function like this, but this is an example of how to call an existing function, not a best-practices lesson.  Note also that 'length' is only a WORD (2-bytes) making 'number' not DWORD aligned, so there is actually an unused 2 bytes in this thing as well.  Again, I'm trying to show some ugliness that you will see in the wild, not cover how it should be done.

So let's look at the native function just as a reference.  I'll not explain the whole thing as it's simple and the comments should answer most questions:

__declspec(dllexport)
void ShowMessage(MESSAGE_INFO *info)
{
  TCHAR message[512];

  // create a buffer for the Unicode string
  wchar_t *wideString = (wchar_t *)LocalAlloc(LPTR, (info->length + 1) * sizeof(wchar_t));

  // convert the ASCII message to Unicode
  mbstowcs(wideString, info->message, info->length);

  // show a message box with the data
  _stprintf(message, _T("Message: %s\r\nNumber: %i"), wideString, info->number);

  MessageBox(NULL, message, NULL, 0);

  // free the Unicode buffer
  LocalFree(wideString);
}

The Managed Side

Ok, so the native side is pretty straightforward.  It's not ideal from a managed developer's perspective, but let's face it - native developers rarely think of making managed developer's lives easy when they write code.

We need to figure out how to create a MESSAGE_INFO "struct" and pass it in in a format that the API can use it.  First, we can safely rule out letting the CF marshaler handle this.  It would have no clue what to do with this.  We can also rule out creating this as a managed struct.  The interned char * is not blittable, so we'll have to hand-marshal this.  The pointer itself also means we'll have to manage some memory manually too, and that also means "Danger Will Robinson!" as we have the potential for a memory leak.  Don't fear that fact - just be aware of it.

So first, we need to understand what the native DLL is expecting.  It wants a pointer to a struct - so simply put a 4-byte address. At that address will be 12 bytes of data representing a MESSAGE_INFO struct.  The first 4 bytes of that is yet another address.  At that address is ASCII character data.  That's it.  Now lets convert that English to C#.

First we'll create a MESSAGE_INFO class (we choose a class instead of a struct becasue we'll be doing some work internally on it).  In the class we'll define a byte array that holds the 12 bytes that represent a native MESSAGE_INFO as well as some constants for member offsets and lengths for readability:

private const int MESSAGE_PTR_OFFSET = 0;
private const int MESSAGE_PTR_LENGTH = 4;
private const int LENGTH_OFFSET = MESSAGE_PTR_OFFSET + MESSAGE_PTR_LENGTH;
private const int LENGTH_LENGTH = 2;
// DWORD compiler alignment forces an unused 2-byte block here
private const int RESERVED_OFFSET = LENGTH_OFFSET + LENGTH_LENGTH;
private const int RESERVED_LENGTH = 2;
private const int NUMBER_OFFSET = RESERVED_OFFSET + RESERVED_LENGTH;
private const int NUMBER_LENGTH = 4;

public static int StructLength = NUMBER_OFFSET + NUMBER_LENGTH;

// in-memory representation of a native MESSAGE_INFO struct
private byte[] m_data = new byte[StructLength];

So when we call the API, we'll just pass it a byte array (a byte array is already a reference type and will get passes as a pointer) instead of a MESSAGE_INFO struct.  Remember, the native side just wants a 4-byte number.  All of the decorations we use of sturct names and all of that is simply for developer convenience.  As long as we know that our m_data byte array is arranged to match a native MESSAGE_INFO, it will all work.

So our P/Invoke declaration looks like this:

[DllImport("NativeLibrary.dll", SetLastError = true)]
internal static extern void ShowMessage(byte[] messageInfo);

Simple, right?  To call the native API, we simply call ShowMessage with our m_data bytes.  Of course that's a bit ugly and non-managed, so we'll provide an operator to get the m_data without having to expose it explicitly:

// provide an operator to turn a MESSAGE_INFO into a byte array for marshaling
public static implicit operator byte[](MESSAGE_INFO mi)
{
  return mi.m_data;
}

Now we can just call ShowMessage with a managed MESSAGE_INFO instance and we're done.  So far it's all been pretty simple.  The difficult part is actually populating the m_data bytes with the right info. 

First, let's start with an easy one - the numeric data.  The 'number' member is a publicly exported value, while 'length' is meant to be used internally as the length of the string data.  So let's expose a Number property for the managed MESSAGE_INFO class, with set and get accessors.  Instead of using a private member variable to hold the value, we'll hold it in the m_data array:

public int Number
{
  set
  {
    // copy the "value" bytes to our in-memory representation
    Buffer.BlockCopy(BitConverter.GetBytes(value), 0, m_data, NUMBER_OFFSET, NUMBER_LENGTH);
  }
  get
  {
    // get the number from our in-memory representation
    return BitConverter.ToInt32(m_data, NUMBER_OFFSET);
  }
}

Ok, so now the fun one.  The string.  Since we're passing just a pointer, we need to allocate memory for that pointer to "point to" plus we need to make sure that the GC isn't allowed to move that memory around in the event of a compaction.  There are a few ways to do this, but the "recommended" mechanism is a GCHandle. A fixed unsafe pointer would also work, but it assumes you'll only use C# and that you know a bit more about pointers than you might.

So we'll add a GCHandle private member to the class, plus a byte array for our actual message (the memory that the GCHandle will point to):

// GCHandle for our message string
private GCHandle m_messageHandle;

// byte array for the actual message data
private byte[] m_messageData;

Now we need to expose a Message string property.  In the set accessor we want to take the incoming string and put it's ASCII representation into the m_messageData member, get a GCHandle that points to it as m_messageHandle and then stuff that into our m_data.  We also want to make sure that we don't leak if someone sets the message twice.  The get accessor is a lot simpler - it just converts the m_messageData bytes back to a string. So the Message property looks like this:

public string Message
{
  set
  {
    // see if we already have allocated data
    if (m_messageHandle.IsAllocated)
    {
      m_messageHandle.Free();
    }

    // null check for safety
    if (value == null)
    {
      m_messageData = null;
      return;
    }

    // get the ASCII representation of the passed-in value (plus a null terminator)
    m_messageData = Encoding.ASCII.GetBytes(value + '\0');

    // pin it
    m_messageHandle = GCHandle.Alloc(m_messageData, GCHandleType.Pinned);

    // store the address of the pinned object into our 'struct'
    IntPtr dataPointer = m_messageHandle.AddrOfPinnedObject();
    byte[] pointerBytes = BitConverter.GetBytes(dataPointer.ToInt32());
    Buffer.BlockCopy(pointerBytes, 0, m_data, MESSAGE_PTR_OFFSET, MESSAGE_PTR_LENGTH);

    // store the length
    short length = (short)m_messageData.Length;
    Buffer.BlockCopy(BitConverter.GetBytes(length), 0, m_data, LENGTH_OFFSET, LENGTH_LENGTH);
  }
  get
  {
    // only return a string is something is allocated
    if (m_messageHandle.IsAllocated)