Wednesday, June 01, 2005

Managed controls in the Compact Framework don't expose all available functionality of the native controls they wrap. And that is understandable since the CF team wanted to make them fast and small. For example, ComboBox control doesn't implement the DropDown event that could be quite helpfull to store a previouse value because it should fire before the SelectedIndexChanged event. So I've decided to implement this event using the NativeWindow class I blogged about the other day.

The Windows CE SDK documentation states that there's a CBN_DROPDOWN notification message that is send to the parent of the ComboBox when the listbox of a combo box is about to become visible. This message is sent in the form of WM_COMMAND.

A quick trip to the winuser.h file to pull out the values for the CBN_DROPDOWN and WM_COMMAND and here's the ComboSubclass class that catches this message and raises the DropDown event:

public class ComboSubclass : NativeWindow

{

    private const int WM_COMMAND = 0x111;

    private const int CBN_DROPDOWN   =  7;

 

    public event EventHandler DropDown;

 

    private ComboBox comboBox;

 

    public ComboSubclass(ComboBox comboBox, Control parent)

    {

        this.comboBox = comboBox;

        //Subclass parent form

        this.AssignHandle(parent.Handle);

    }

 

    protected override void WndProc(ref Message m)

    {

        if (m.Msg == WM_COMMAND)

        {

            // Make sure that's its our ComboBox

            if (m.LParam == comboBox.Handle)

            {

                if (DropDown != null)

                {

                    // Raise the event

                    DropDown(comboBox, null);

                }

            }

        }

        base.WndProc(ref m);

    }

}

The usage of this class should be pretty straightforward:

   comboSubclass = new ComboSubclass(comboBox1, this);

  comboSubclass.DropDown += new EventHandler(comboSubclass_DropDown);

           

 

  void comboSubclass_DropDown(object sender, EventArgs e)

  {

      prevIndex = ((ComboBox)sender).SelectedIndex;

  }

Update: You can achieve the same goal in the CF v1 by utilizing ApplicationEx class from SDF and WinProcFilter I posted last year.

6/1/2005 2:14:42 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Monday, May 23, 2005

As you probably know, the CF team has added the capability to use managed delegates as a native callbacks in the CF v2. It means that it’s become quite possible to use API’s that require a callback function such as EnumFonts, EnumWindows etc… The same goes true for been able to use SetWindowLong to subclass window procedure. The full .NET Framework includes a very useful NativeWindow class that wraps window subclassing and creating new windows functionality in the very usable and convenient package. A few months ago, I’d created a .NET Compact Framework v2 implementation of the NativeWindow class with exactly the same functionality (AssignHandle, CreateHandle, WndProc etc...

 

So what can you do with this class? Subclass any control and catch the messages that are not exposed as events, create your own versions of the native controls (EDIT, LISTBOX, ListView etc…)

 

You should expect the NativeWindow to become a part of the Smart Device Framework for CF v2.

 

You can download the NativeWindow class and a test project from here:

NativeWindowTest.zip (62.02 KB)
5/23/2005 5:28:13 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Thursday, May 12, 2005

Chris Tacke has officially announced release of the Smart Device Framework 1.3 at his presentation “OpenNETCF.org : Creating a Community-Driven Development Project” at MEDC. Take a look at these wonderful screenshots on the new integration in VS.NET features from Neil who is single-handedly has done a titanic job of redesigning dialogs and incorporating Application Blocks into SDF installation structure.

 

 

 

SDF
5/12/2005 9:03:07 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Saturday, May 07, 2005

I am getting prepared to go to MEDC. This conference promisses to be a blast with some major announcements coming in and many of us from OpenNETCF are going to be there, so do not hesitate to come over and say hi.

MDC
5/7/2005 2:45:23 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Thursday, May 05, 2005

One of my favorite new features available in the CF v2 is the XmlSerializer. Presence of it in the CF opens up a great possibilities in building a cross device/desktop communications (read WSE and such). But when you start using it you'd notice some lag when trying to serialize/deserialize your objects. It's explained by a way the XmlSerializer is designed. When you call its constructor:

new XmlSerializer(type, defaultNamespace)

the serializer walks the whole object graph using reflection and discovers all serializable properties and fields. Reflection as you know, due to its “late bound“ nature, is not the fastest part of .NET. So the solution could be caching the XmlSerializer for the object types that already have been used and re-use it for next time you need the serializer.

Here's the code for XmlSerializerCache class that you can use to achieve that:

public class XmlSerializerCache

{

      #region fields

 

      private static Hashtable table;

 

      #endregion // fields

           

      #region constructors

 

      static XmlSerializerCache()

      {

            XmlSerializerCache.table = new Hashtable();

      }

 

      private XmlSerializerCache()

      {

      }

 

      #endregion // constructors

 

     

      public static XmlSerializer GetXmlSerializer(Type type, string defaultNamespace)

      {

            XmlSerializer serializer;

            if (type == null)

            {

                  throw new ArgumentNullException("type");

            }

            // Make it thread safe

            lock (XmlSerializerCache.table.SyncRoot)

            {

                  string typeName;

                  if ((defaultNamespace == null) || (defaultNamespace.Length == 0))

                  {

                        typeName = type.FullName + "#";

                  }

                  else

                  {

                        typeName = type.FullName + "#" + defaultNamespace;

                  }

                  // Try to get the serializer from cache

                  object obj = XmlSerializerCache.table[typeName];

     

                  if (obj == null)

                  {

                        // We don't have it, create a new instance

                        obj = new XmlSerializer(type, defaultNamespace);

                        XmlSerializerCache.table.Add(typeName, obj);

                  }

                  serializer = obj as XmlSerializer;

            }

            return serializer;

      }

}

 

The usage of the XmlSerializerCache should be pretty straightforward:

 

XmlSerializer serializer = XmlSerializerCache.GetXmlSerializer(typeof(Order), "http://tempuri.org/");

 

serializer.Serialize(stream, order);

 

BTW, you can employ this class for the desktop .NET as well too and enjoy some speed improvements.

5/5/2005 4:31:20 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Wednesday, March 16, 2005

OK, I am back to the surface still alive and breathing after been drowned in the sea of project deadlines.

A few important links from this morning news scan:

1. The Indigo CTP documents are available at:

http://winfx.msdn.microsoft.com/library/default.asp?url=/library/en-us/indigo_con/html/503fae4b-014c-44df-a9c7-c76ec4ed4229.asp

And as Sam Gentile righfully mentiones - “Go read, get used to it, it's your future.“

2. Cool project at Codeproject.com:

Implement an explorer using .net compact flamework in Pocket PC

 

 

 

3/16/2005 3:12:51 PM (GMT Standard Time, UTC+00:00)  #    Comments [43]  | 
 Friday, February 04, 2005

In his recent post Mike Zintel divuldges some information on the past, present and future of evolution of the NetCF and asking some feedback on the priorities for v.Next. As I already pointed out in my previouse post, CF lacks essential support for developing SOA such as WS-* protocol suite or Indigo. So seeing that CF team is thinking on leveraging it is very encoraging sign. The only problem I see here is the timing. Mike mentions this in the context of V3, but we need it now. The project that I am working on is a real time trading system that utilizes desktop as well as CE devices clients. In the case of desktop the usage of WSE is no brainer and fits in the architecture that I designed pretty well. But in case of CE devices I have to go through some loops by utilizing a Web Service in the middle for outgoing messages and a custom UDP communication for incoming. Plus by the time the CF V3 will be coming out the Indigo should be available so it would make sence to implement Indigo for CF V3 as well. How about if CF team would release a WS-* for CF as and add-on not tied up to V3, but may be to some Service Pack for v2 of CF and provided a full support for Indigo in the V3. I think this should be a feasable option since MS already has the WSE in the v2.0 which is pretty stable and shouldn't pose a lot problems when porting the code to CF v2.

2/4/2005 3:32:23 PM (GMT Standard Time, UTC+00:00)  #     | 
 Friday, January 14, 2005

Check out the Neil's Call to Action... post. Make a donation if you appreciate not only the always growing SDF, but also the invaluable help, support, tips, tricks and code the we provide in our blogs. Remember that accordingly to the latest studies one of the main things that make you happy is being kind or helping to others, whether friends or strangers...

1/14/2005 2:17:15 PM (GMT Standard Time, UTC+00:00)  #    Comments [34]  |