Thursday, August 18, 2005

The .NetCF doesn't provide implementation for the DropDownWidth property for the ComboBox control. Even though it is just a simple call to send either CB_SETDROPPEDWIDTH or CB_GETDROPPEDWIDTH messages. So, following the extender pattern that I aleady used to create the ListBoxExtender I've created the ComboBoxExtender class that implements the DropDownWidth property:

public class ComboBoxExtender

{

      private ComboBox comboBox;

      private IntPtr handle;

 

      public ComboBoxExtender(ComboBox comboBox)

      {

            this.comboBox = comboBox;

            // Get native handle

            this.comboBox.Capture = true;

            this.handle = GetCapture();

            this.comboBox.Capture = false;

      }

 

      public int DropDownWidth

      {

            get

            {

                  return GetDropDownWidth();

            }

            set

            {

                  SetDropDownWidth(value);

            }

      }

 

      private void SetDropDownWidth(int width)

      {

            SendMessage(handle, CB_SETDROPPEDWIDTH, width, 0);

      }

 

      private int GetDropDownWidth()

      {

            return SendMessage(handle, CB_GETDROPPEDWIDTH, 0, 0);

      }

 

      #region P/Invokes

 

      const int CB_GETDROPPEDWIDTH    =      0x015f;

      const int CB_SETDROPPEDWIDTH    =      0x0160;

      [DllImport("coredll.dll")]

      static extern IntPtr GetCapture();

  

      [DllImport("coredll.dll")]

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

 

      #endregion

}

You would use this class:

private ComboBoxExtender comboExt;

 

comboExt = new ComboBoxExtender(comboBox1);

 

comboExt.DropDownWidth = 250;

 

8/18/2005 6:58:40 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Wednesday, August 17, 2005

The best way to test functionality and usability of a library is to use it for development for some real project. So I took the OpenNETCF.Rss library for a spin and created a RSS reader for Pocket PC. I gave it a name “OpenRSS”. During its development I discovered a few bugs and missing functionality in the OpenNETCF.Rss, so the time spend was worth it. Here are a few screenshots:

The OpenRSS is a work in progress. It doesn’t implement all functionality that would be required for a production ready RSS reader, so consider it as a sample or a starting point.

You can download the OpenRSS’s project with updated OpenNETCF.Rss bits here:

OpenRSS.zip (180.63 KB)

I’ve also uploaded the OpenNETCF.Rss into the Vault, which means it should become a part of SDF in the future release.

8/17/2005 5:06:07 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Friday, August 12, 2005

My current assignment with www.nymex.com is close to completion, so I am available for projects/job in Mobility/.NET Compact Framework/.NET Architect in NY/NJ (and not only) area. You can contact me at a.yakhnin@(REMOVETHIS)att.net

Little bit about myself here.

 

8/12/2005 8:45:07 PM (GMT Daylight Time, UTC+01:00)  #    Comments [26]  | 
 Tuesday, August 09, 2005

I've updated the OpenNETCF.Rss library I posted about last time. The IFeedStorage interface has been added. It exposes the following methods:

public interface IFeedStorage

{          

          ///

          /// Inits the storage provider.

          ///

          /// Represents a single node in the XML document

          void Init(XmlNode section);

 

          ///

          ///   Adds an element with the specified key and value into the storage.

          ///

          void Add (Feed feed);

           

          ///

          ///   Removes all elements from the storage.

          ///

          void Flush ();

           

          ///

          ///   Gets the element with the specified key.

          ///

          Feed GetFeed (string key);

           

          ///

          ///   Removes the element with the specified key.

          ///

          void Remove (string key);

           

          ///

          ///   Updates the element with the specified key.

          ///

          void Update (Feed feed);

           

          ///

          ///   Gets the number of elements actually contained in the storage.

          ///

          int Size{ get; }

}

 

I've also created the FeedFileStorage class, that inherits from IFeedStorage and implements the functionality to store RSS feeds in the file system. You can provide your own implementaion of the IFeedStorage that could store feeds in the database or in some other location. The FeedEngine class now has the Storage property:

public static IFeedStorage Storage

It will return the currently enabled feed storage which is dynamically loaded from the config file settings:

<storage>

      <provider name="fileStorage" enabled="true" type="OpenNETCF.Rss.FeedFileStorage,OpenNETCF.Rss,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null">

            <path value="C:\Temp\Channels" />

            <feedSizeLimit value="100" />

      </provider>

storage>

So in order to load your own feed storage you'd need to add a similar section to the config file and modify the enabled flag appropriately. The path and feedSizeLimit settings are specific to the file storage. You can provide your own parameters and load them in the IFeedStorage.Init method.

Here's the updated version of the library as well as test clients:

OpenNETCF.Rss1.zip (425.74 KB)
8/9/2005 8:00:06 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Thursday, August 04, 2005

The “RSS”, “blogging”, “PODcasting”, “OPML” – these acronyms are becoming increasingly big in the technology world. Especially after Microsoft had announced about RSS support in the Longhorn err… Vista and IE7. The MSDN article mentions photo blogs, moblogs, and video blogs as well as calendar feeds. But wait a second. Why does it have to run on a desktop? I am pretty sure that all these usage scenarios are perfect fit Mobile devices as well. So here’s a hint for Mobile devices / developers teams at Microsoft – let’s extend the “RSS everywhere” paradigm to the Windows CE platform as well. Call me crazy, but I also think RSS feeds could become more then an XML over HTTP. RSS feeds and lists don’t have to be blogs. They could as well include any type of business information that needs to be updated on a regular basis. What prevents us to use RSS over different communication channels like UDP or TCP?

 

So having all these ideas in mind I have started on creation of Y.A.R.F (Yet Another RSS Framework). I know there’re a few .NET implementations available on the internet, but I didn’t like either of them – they’re not flexible or extensible enough. I wanted a framework that could be used on both .NetCF and full .NET, allowed usage of the configuration files and was able to process Atom feeds as well. So here it is – a technology preview of the OpenNETCF.Rss library. When designing the architecture for the framework I’ve tried to model it after a WSE which provides paradigms of “channels” or connections and “transports“ or protocols that’re used to transport the data. Here’s the class diagram of the OpenNETCF.Rss library:

When developing the OpenNETCF.Rss I’ve used some RSS and Atom parsing code from the most excellent Dare’s RSSBandit.

 

There're a few ways you can use this library to retreive a RSS feed.

 

1. Syncronously:

 

Feed feed = FeedEngine.Receive(new Uri(“http://myfeed/rss.aspx”));

 

2. Asyncronously through event handler:

 

FeedEngine.FeedReceived+=new FeedReceivedHandler(FeedEngine_FeedReceived);

FeedEngine.Subscribe(new Uri((“http://myfeed/rss.aspx”));

 

2. Asyncronously by providing an instance of your FeedReceiver:

 

public class MyFeedReceiver : FeedReceiver

{

      Form1 form;

 

      public AlexFeedReceiver(Form1 form)

      {

            this.form = form;

      }

     

//Implement the Receive

      public override void Receive(Feed feed)

      {

            form.ShowFeed(feed);

      }

}

 

...

 

FeedEngine.Subscribe(new Uri("http://www.engadget.com/rss.xml"), new MyFeedReceiver(this));

I'll elaborate on the OpenNETCF.Rss design in a later posts.

The OpenNETCF.Rss is in no way complete. I am planning on adding more functionality like FeedStorage and communications channels. Please do not hesitate to comment on the design and implementation. The VS.NET solution includes test projects for the desktop and PPC device.

OpenNETCF.Rss.zip (406.65 KB)

Documentation.chm (100.58 KB)
8/4/2005 3:36:22 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Wednesday, July 20, 2005

Be sure to visit all the options under "Configuration" in the Admin Menu Bar above. There are 16 themes to choose from, and you can also create your own.

 

7/20/2005 8:00:00 AM (GMT Daylight Time, UTC+01:00)  #    Comments [4]  | 
 Thursday, July 14, 2005

I've seen the request on the CF newsgroups for the control that would be able to scroll and zoom in(out) an image. Immediatedly remembered that I had this kind of control developed for my AtlasCE for Smartphone. So I pulled down the code, cleaned it up and created a sample client:

The ImageViewer control's code doesn't have a lot of comments, but I hope that the code is self explanatory enough for you to figure out how it works.

The ImageView has just a handfull of public methods properties:

You can download the control's source code and a sample from here:

ImageViewerClient.zip (76.15 KB)
7/14/2005 10:11:05 PM (GMT Daylight Time, UTC+01:00)  #     | 
 Tuesday, July 05, 2005

This question has just come up on the .NetCF newsgroup. P/Invoke is again to the rescue:

public void SaveTextBox(TextBox textBox, string fileName)

{

      StringBuilder buffer = new StringBuilder(" ", 255);

      // Get TextBox's native handle

      textBox.Capture = true;

      IntPtr handle = GetCapture();

      textBox.Capture = false;

     

      // The EM_GETLINE requires the length of the buffer in the first byte.

      buffer[0] = (char)255;

 

      using(StreamWriter writer = new StreamWriter(fileName))

      {

            // Get line count

            int lineCount = SendMessage(handle, EM_GETLINECOUNT, 0, 0);

 

            for(int i=0;i<lineCount;i++)

            {

                  SendMessage(handle, EM_GETLINE, i, buffer);

                  writer.WriteLine(buffer.ToString());

            }

            writer.Flush();

      }

 

}

 

Required P/Invoke declarations:

const int EM_GETLINECOUNT    =  0x00BA;

const int EM_GETLINE         =  0x00C4;

 

[DllImport("coredll.dll")]

static extern IntPtr GetCapture();

 

[DllImport("coredll.dll")]

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

 

[DllImport("coredll.dll")]

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

 

7/5/2005 9:57:45 PM (GMT Daylight Time, UTC+01:00)  #     |