Tuesday, December 09, 2003

You've probably noticed that some of the applications on Pocket PC 2003 and SmartPhones have this fancy looking gradient background. In all these cases it looks like a system list view control have been used... A quick search through a PPC 2003 SDK returns this result in the  List View Styles: "LVS_EX_GRADIENT Draws a background with a gradient. " Bingo! We're almost there. We know that ListView control in Compact Framework is just a wrapper for a native one, so here is the code that'll do the job:

//Some PInvokes and constants
[DllImport("coredll.dll")]
public static extern IntPtr GetCapture();

[DllImport("coredll.dll")]
private static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

const int LVS_EX_GRADIENT  =       0x20000000;
const int LVM_SETEXTENDEDLISTVIEWSTYLE  = 0x1000 + 54;

private void SetGradient(ListView listView)
{
     //Get a list view handle
     listView.Capture = true;
     IntPtr hList = GetCapture();
     //Apply extended style
     SendMessage(hList, (uint)LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRADIENT);
     listView.Capture = false;
     listView.Refresh();
}

12/9/2003 2:12:11 PM (GMT Standard Time, UTC+00:00)  #     | 
 Friday, December 05, 2003

VS.NET provides really sophisticated debugging options for developing SDP for Compact Framework. But sometimes there are situations when the only way to see what's happening in the code is to output some text/values to the Output window (or Console), but this option, as you know is missing from VS IDE. Although there's a solution to that - to implement System.Diagnostic.TraceListener and then to register it with the listeners collection. Take a look at this wonderful article on CodeProject.com. The sample from the article had successfully worked for me from devices and emulator with no problems.

12/5/2003 10:10:42 PM (GMT Standard Time, UTC+00:00)  #     | 
 Tuesday, December 02, 2003

There was a question on the CF newsgroups the other day on how to implement functionality of the Control.GetNextControl in the Compact Framework. Knowing that a tab order in the CF should correspond to the order of the controls added into the Form.Controls collection, I came up with the following snippet:

public Control GetNextControl(Control ctl,  bool forward)
{
   int currIndex = this.Controls.IndexOf(ctl);

   if (forward)
   {
       //check if it's the last control in the collection
       if (currIndex < this.Controls.Count)
               currIndex++;
      else
               currIndex = 0; //move to the first one
   }
   else //backwards
   {
       //check if it's the first control in the collection
       if (currIndex > 0)
             currIndex--;
      else
             currIndex = this.Controls.Count - 1; //move to the last one
   }
   return this.Controls[currIndex];
}

 

 

12/2/2003 3:34:44 PM (GMT Standard Time, UTC+00:00)  #     | 

As Neil has just announced (SDF) Smart Device Framework is available for beta testing. It included all of the stuff we've developed before plus a whole bunch of really cool things we've been working on in the background. The OpenNETCF.Windows.Forms workspace includes the Owner-Drawn List I've described in the article  which has evolved into a fully fledged ListBoxEx control with full design-time support, background bitmap and data binding, the colorfull CheckBox control, StatusBar and much more really cool controls. As Neil's pointed in the new classes there is a must have XmlSerializer and FileSystemWatcher etc... On a top of that Neil has done a tremendous work to create a installation that integrates into Visual Studio .NET. And of course everything will come with a complete source code...

12/2/2003 1:54:18 AM (GMT Standard Time, UTC+00:00)  #     | 
 Wednesday, November 26, 2003

There is no secret that SQL CE currently is not supported on a Smartphone platform. It means that the options for data storage on a Smartphone for .NET Compact Framework developers are generally limited to DataSet XML serialization/deserialization. This option has known deficiencies: you can read/write data in “all or nothing” way only and XML by itself bloats the data, all of which is a big downsize in the memory constrained Smartphone environment. So, what’s the solution? Write your own “a read from the file stream, save in binary form, fast forward-only reading” storage in CF. And this is what I’ve been working on for the last few weeks. The quick test I ran yesterday showed a really good speed/memory benchmarks. DataGrid population with 1000 (5 fields) records takes about 3 secs! Now, I just need to find some time to clean up the code and write up a whitepaper on it…

11/26/2003 1:52:14 PM (GMT Standard Time, UTC+00:00)  #     | 
 Monday, November 24, 2003
I've spent the whole weekend listenning and watching presentations from recent PDC.  I've had a blast when watching MBL311 - Exploring New Features in .NET Compact Framework "Whidbey" Release presented by Seth Demsey a Co.  I can clearly see that they're really listenning to our vows. There's so much cool stuff's been added to the next version of CF that I just can't wait to get my hands on it.  But it's still at least a year away...
11/24/2003 7:17:24 PM (GMT Standard Time, UTC+00:00)  #    Comments [31]  | 
 Sunday, November 23, 2003
I've finally got around to start working on a port of the AtlasCE to SmartPhone. The first thing I realised when trying adapt a UI to the "tapless/mouseless" Smarphone environment is that I have to change the whole way of thinking when creating programs for it. The least to say that the screen is small (176x220), you should always keep in mind that the user must be able to get to the information in the smallest amount of joystick/button pressings. You need to try to be ahead of a user, predict what he'd want to see on the screen and give it to them even before they'd ask for it. Only then your program could make sense when running on a SmartPhone...
11/23/2003 3:47:32 AM (GMT Standard Time, UTC+00:00)  #    Comments [0]  | 
 Wednesday, November 19, 2003

Yeah... it's been a while I posted anything into this blog. I've been doing a lot of different things on CF (one of which is SDF on OpenNETCF.org) which I am going to tell you about later on...

Meanwhile, as an incentive to the loyal and new readers I am posting the function for drawing gradient colors in CF. As you know GradientBrush is not supported in CF and one of my recent projects required filling a background with a gradient colors, so I've put together the following function:

public static void DrawGradientVertical(Graphics g, Color color1, Color color2, Rectangle rect, int percent)
  {
   Pen pen = null;

   //calculate half color
   Color halfColor = Color.FromArgb((color1.R + color2.R) / 2, (color1.G + color2.G) / 2, (color1.B + color2.B) / 2);
   
   int R_color = color1.R;
   int G_color = color1.G;
   int B_color = color1.B;

   int R_step = 0;
   int G_step = 0;
   int B_step = 0;

   int sep1 = rect.Height / 2;
   int sep2 = rect.Height / 2;

   //calculate steps for changing between color1 and halfColor
   if (rect.Height > 0) //avoid 0 division
   {
    sep1 = rect.Height * percent / 100;
    R_step = (halfColor.R - color1.R) / sep1;
    G_step = (halfColor.G - color1.G) / sep1;
    B_step = (halfColor.B - color1.B) / sep1;
   }
   
   //draw the lines
   for(int i=0;i<sep1;i++)
   {
    pen = new Pen(Color.FromArgb(R_color,G_color,B_color));
    g.DrawLine(pen, rect.X, rect.Top + i, rect.Right, rect.Top + i);
    R_color = R_color+R_step;
    G_color = G_color+G_step;
    B_color = B_color+B_step;
   }

   //calculate steps for changing between halfColor and color2
   if (rect.Height > 0) //avoid 0 division
   {
    sep2 = rect.Height - sep1;
    R_step = (color2.R - halfColor.R) / sep2;
    G_step = (color2.G - halfColor.G) / sep2;
    B_step = (color2.B - halfColor.B) / sep2;
   }

   R_color = halfColor.R;
   G_color = halfColor.G;
   B_color = halfColor.B;

   //draw the lines
   for(int i=sep1;i<rect.Height;i++)
   {
    pen = new Pen(Color.FromArgb(R_color,G_color,B_color));
    g.DrawLine(pen, rect.X, rect.Top + i, rect.Right, rect.Top + i);
    R_color = R_color+R_step;
    G_color = G_color+G_step;
    B_color = B_color+B_step;
   }


  }

This function should fill the given rectangle with the gradient colors vertically. You can easily change it to make a filling in the horizontal direction.

 

11/19/2003 4:13:11 PM (GMT Standard Time, UTC+00:00)  #    Comments [32]  |