Wednesday, June 14, 2006

What do you do if the application you develop using .NET CF requires you to transform XML with some XSL and you know that .NET CF doesn't support that? You are not completelly out of luck here. Did you know that the native Microsoft XML Parser MSXML2 is included in all Windows Mobile devices and in most custom Windows CE devices as well? Of course it's a COM component, but CF v2 has added support for COM interop. So, here are 2 steps to enable MSXML2 usage in your CF application:

1. Open Visual Studio 2005 Command prompt, navigate to the ..\Include\Armv4i directory of the Windows Mobile SDK, and execute the following line:

midl msxml2.idl 

The result of this execution will be creation of the msxml2.tlb library.

2. Copy the msxml2.tlb into your project's directory and add the reference to it by browsing. The Visual Studio will recognize that this is a type libabry and will generate the MSXML2 interop assembly.

Now you can create an instance of the DOMDocumentClass and use its XSL transformation functionality:

MSXML2.DOMDocument doc = new MSXML2.DOMDocumentClass();
// Load XML document.
doc.load(“customer.xml"));

MSXML2.DOMDocument xsl = new MSXML2.DOMDocumentClass();
// Load XSLT document.
xsl.load(“customer.xslt"));
// Transform XML data.
string temp = doc.transformNode(xsl);

6/14/2006 3:12:38 AM (GMT Daylight Time, UTC+01:00)  #     | 
 Friday, June 09, 2006

Microsoft just made the SQL Server Everywere Edition CTP available for download:

SQL Server Everywere Edition CTP Runtime

SQL Server Everywere Edition CTP Book Online

Keep in mind that these are the runtime binary files for desktop computers only.

6/9/2006 10:29:14 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Wednesday, June 07, 2006

Questions about how to make the Label control in CF transparent come up on the newsgroups or forums all the time. People want to have a transparent label on a top of an image. The answer to that is that transparency in the controls is not supported on the OS level. But what is the Label control? It is just a text drawn on a graphic surface. So this is what I've been doing -  drawing a text string on a top of an image. But not loose the design time goodness that you get with the Label, I was using the Label's properties (Text, Font, Location, Size etc..) to draw the required string in the location instead of the Label:

private void DrawLabel(Label label, Graphics grx)

{

      if (label.TextAlign == ContentAlignment.TopLeft)

      {

           gxOff.DrawString(label.Text, label.Font, new SolidBrush(label.ForeColor), label.Bounds);

      }

      else if (label.TextAlign == ContentAlignment.TopCenter)

      {

           SizeF size = grx.MeasureString(label.Text, label.Font);

           int left = this.Width / 2 - (int)size.Width / 2;

           Rectangle rect = new Rectangle(left, label.Top,  (int)size.Width, (int)label.Height);

           gxOff.DrawString(label.Text, label.Font, new SolidBrush(label.ForeColor), rect);

      }

      else if (label.TextAlign == ContentAlignment.TopRight)

      {

           SizeF size = grx.MeasureString(label.Text, label.Font);

           int left = label.Width - (int)size.Width + label.Left;

           Rectangle rect = new Rectangle(left, label.Top, (int)size.Width, (int)size.Height);

           gxOff.DrawString(label.Text, label.Font, new SolidBrush(label.ForeColor), rect);

      }

 }

In order to use this method you can assign an image to the PictureBox, drop a Label control on a top of a PictureBox, set Label 's Visible proprerty to false and call the DrawLabel method in the Paint event of the PictureBox.

6/7/2006 4:51:53 PM (GMT Daylight Time, UTC+01:00)  #     | 

Check it out at: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag2/html/MCSFLP.asp

It has got a lot of useful stuff for WM and Windows CE development especially for enterprize mobile developlment.

6/7/2006 2:13:31 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Tuesday, May 16, 2006

In order to minimize the size of the CAB size for the game, include the WM Smartphone 2003 as well as reduce the steps required to install the Mobile Kombat on the user’s devices, one of the main requirements was to use CF v1. We also decided not to use the SQL CE 2.0 for the same purposes. One of the data files used in the game was a set of questions and answers for the trivia on mobile programming.  The obvious solution was to use DataSet for the data files, but don’t forget that it loads the whole Xml data file into memory and we were trying really hard to reduce a memory footprint of the game as much as possible. Let’s say we have 2 tables defined: Answer and Question. Here’s how the xml data looked like:

 

<NewDataSet>

  <Question>

    <QuestionID>1</QuestionID>

    <Text>Which is a new .NET Compact Framework 2.0 namespace?</Text>

    <CorrectAnswer>2</CorrectAnswer>

  </Question>

  <Question>

    <QuestionID>2</QuestionID>

    <Text>What operating system runs on Ultra Mobile PCs?</Text>

    <CorrectAnswer>0</CorrectAnswer>

  </Question>

 

<Answer>

    <QuestionID>1QuestionID>

    <Text>Sockets</Text>

  </Answer>

  <Answer>

    <QuestionID>1QuestionID>

    <Text>Collections</Text>

  </Answer>

  <Answer>

    <QuestionID>1QuestionID>

    <Text>Cryptography</Text>

  </Answer>

 

So I came up with the solution of creating a forward only lightweight XmlDataReader that would move from one xml node to another and will create an instance of the appropriate class based on the xml data. Take a look at the class diagram:

  

Well… you could say that XmlSerializer can just do that. But remember that we had to use the CF v1, which doesn’t provide the XmlSerializer. Considering the time constraints that would be required to create a generic XmlSerializer, my solution was that all classes would have to implement the IXmlDataFormat interface:

 

interface IXmlDataFormat

{

    void ReadXml(XmlNodeList nodeList);

}

 

So the XmlDataReader when deserializing the objects will delegate the population of their properties to the object itself. Here’s how the object’s instance creation looks:

 

 

 

 

///

/// Creates an instance of the type if it implements the IXmlDataFormat interface.

///

/// The XmlNode.

///

private object GetValue(XmlNode node)

{           

     ConstructorInfo info = null;

     // Make sure that the type implements IXmlDataFormat interface.

     if (ImplementsInterface(type, typeof(IXmlDataFormat)))

     {

        info = type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new Type[0], null);

        if (info == null)

        {

             throw new ArgumentException("No constructor");

        }

        // Create an instance

        IXmlDataFormat objValue = info.Invoke(null) as IXmlDataFormat;

        if (objValue != null)

        {

            // Call the interface method

            objValue.ReadXml(node.ChildNodes);

        }

        return objValue;

     }

     return null;

  } 

 

And here’s how an actual class would implement the IXmlDataFormat interface:

 

public void ReadXml(XmlNodeList nodeList)

{

    foreach (XmlNode node in nodeList)

    {

        XmlElement element = node as XmlElement;

        if (element != null)

        {

            switch (element.LocalName)

            {

                case "QuestionID":

                {

                    this.questionID = Convert.ToInt32(element.InnerText);

                    continue;

                }

                case "Text":

                {

                    this.text = element.InnerText;

                    continue;

                }

                case "CorrectAnswer":

                {

                    this.correctAnswer = Convert.ToInt32(element.InnerText);

                    continue;

                 }

            }

         }

      }

   }

 

The code above just simply iterates through xml nodes and populates the object’s properties with the values from xml data.

 

I’ve also created the XmlDataManager class. This class implements a few useful helper methods that wrap calls to the XmlDataReader. Here’s some sample code that will retrieve all answers from xml data file by a certain question id:

 

// Create an instance of the XmlDataReader

XmlDataReader answersReader = new XmlDataReader(this.triviaFilePath, typeof(Answer));

// Create an instance of the XmlDataManager by passing the XmlDataReader

XmlDataManager answersManager = new XmlDataManager(answersReader);

// Retreive the list of anwers

IList answersList = answersManager.GetObjectList("QuestionID", QID);

 

You can download the sample project and the source code for the XmlDataReader here:

 

 

XmlDataReaderTest.zip (48.11 KB)
5/16/2006 7:25:27 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Monday, May 15, 2006
I am back from MEDC in Vegas. As I anticipated it, the conference was an unending mini twister of different events, sessions, meeting old friends, fellow MVP’s, OpenNETCF team, Microsoft’s guys from CF and other teams and new people, sumobot competition, Mobile Kombat game we’ve developed for MEDC that Nick described in his blog. In the next few posts I’ll describe a few interesting solutions I had to come up with to make the game to have a minimal memory footprint and appropriate performance.

5/15/2006 3:41:05 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Friday, May 05, 2006

I am off to Las Vegas for MEDC 2006. The last year was a blast, but this year I anticipate it be a storm . I've been doing a very cool stuff for MEDC. Hopefully it's going to become a really big hit among the attendies. So if anybody wants to meet me, you will be able to find me in the usual company of really cool people from OpenNETCF and Infusion.

5/5/2006 3:24:08 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Friday, March 17, 2006

I would like to refer you to these great reads that explain the intricacies of the persistent storage in the Windows CE 5.0 devices:

http://blogs.msdn.com/windowsmobile/archive/2006/03/16/552996.aspx

http://blogs.msdn.com/ce_base/archive/2006/03/15/IncreaseFSThroughput.aspx

The first one is from Mike Caligaro from Windows Mobile Team and the second is form Ariane Jensen who is a member of the Windows CE core team. A must read for both.

 

3/17/2006 3:00:46 PM (GMT Standard Time, UTC+00:00)  #    Comments [34]  | 
 Thursday, March 09, 2006

So, everybody have been talking about Origami lately. It's started from the first Microsoft's unobscure marketing pitch on this site and finaly culminated after offical CeBIT announcements. I would agree with many people that the UMPC devices are a hardly revolutional idea, but it has got a great potential to become a new trend in the way people would use the computer, making it more usable for the average Joe.

So what's about the developer story for these devices? Since it runs Windows XP, it is a full .NET, baby! But consider a screen size, resolution and relatively less powerful processor - what does it remind you? Right, it is a pumped up version of the Windows Mobile device. And the people who have been developing for Windows CE based devices should feel themselves right at home. Need to create a smaller screen, touch driven user interface application? No problem here. 800x480 screen size is a football field for us and we know how to utilize it without cramping up the whole screen, draining the battery and making functional and easy to use. So WM and Windows CE developers suddenly have become experts in developing for UMPC! By the way, the beta of the UMPC emulator is already available for download here. It enables you to test your application's layout and screen behavior as it appears on UMPC's. But remember it is not a hardware emulator. It just puts the UMPC skin on your screen and resizes your desktop work area to the resolution on the UMPC (800x480).

Update: Don't forget to check the Origami team blog. I am subscribed!

3/9/2006 4:10:19 PM (GMT Standard Time, UTC+00:00)  #    Comments [32]  |