SQLCE Code Generator

Some time ago, I started a hobby project for generating data access layer code for SQL Compact Edition databases. I managed to get as far as creating a custom tool and generating a code behind data access layer file (currently only in C#) for every table in the database.

I’m having a bit of a hard time finding the time to work on the project so I published it on CodePlex. If you’re interested in the source code or if you want to contribute to the project then check it out at Github



How to toggle the Wi-fi radio

I had a task to complete today where I was to create an application to toggle the Wi-Fi radio. I had two major requirements for this task; I was supposed to not spend more an hour on this and it must run on older devices running Pocket PC 2003 (or older)

This is what I came up with, 1 function (the entry point) and it uses only 3 power management API calls; GetDevicePower, DevicePowerNotify, and SetDevicePower

Basically I spent most of the time finding the device name for the wireless device. It seems to be pretty used for Intermec devices as I tested it on 3 different devices (or it could also be that only those 3 devices used the same device name)

Anyway, here’s the code (works only for Intermec devices):

#include <windows.h>
#include <pm.h>
 
#define INTERMEC_WIFI_DEVICE    L"{98C5250D-C29A-4985-AE5F-AFE5367E5006}\\BCMCF1"
 
int _tmain(int argc, _TCHAR* argv[])
{
    CEDEVICE_POWER_STATE state;
    GetDevicePower(INTERMEC_WIFI_DEVICE, POWER_NAME, &state);
    CEDEVICE_POWER_STATE newState = (state == D0) ? D4 : D0;
 
    DevicePowerNotify(INTERMEC_WIFI_DEVICE, newState, POWER_NAME);
    SetDevicePower(INTERMEC_WIFI_DEVICE, POWER_NAME, newState);
}

Normally when I experiment with the platform SDK, I just create native console applications and test how the function works. Since my application was simple and didn’t need a UI, I just shipped it in native code.

But for the sake of sharing knowledge I ported my tiny application to the .NET Compact Framework. Here’s the code (works only for Intermec devices):

[DllImport("coredll.dll", SetLastError = true)]
static extern int DevicePowerNotify(string name, CEDEVICE_POWER_STATE state, int flags);
 
[DllImport("coredll.dll", SetLastError = true)]
static extern int SetDevicePower(string pvDevice, int dwDeviceFlags, CEDEVICE_POWER_STATE DeviceState);
 
[DllImport("coredll.dll", SetLastError = true)]
static extern int GetDevicePower(string pvDevice, int dwDeviceFlags, ref CEDEVICE_POWER_STATE pDeviceState);
 
enum CEDEVICE_POWER_STATE : int
{
    PwrDeviceUnspecified = -1,
    D0 = 0,
    D1 = 1,
    D2 = 2,
    D3 = 3,
    D4 = 4,
    PwrDeviceMaximum = 5
}
 
const int POWER_NAME = 0x00000001;
const string ADAPTER_NAME = "{98C5250D-C29A-4985-AE5F-AFE5367E5006}\\BCMCF1";
 
static void Main()
{
    CEDEVICE_POWER_STATE state = CEDEVICE_POWER_STATE.PwrDeviceUnspecified;
    GetDevicePower(ADAPTER_NAME, POWER_NAME, ref state);
    CEDEVICE_POWER_STATE newState = (state == CEDEVICE_POWER_STATE.D0)
        ? CEDEVICE_POWER_STATE.D4
        : CEDEVICE_POWER_STATE.D0;
 
    DevicePowerNotify(ADAPTER_NAME, newState, POWER_NAME);
    SetDevicePower(ADAPTER_NAME, POWER_NAME, newState);
}

There are smarter, better, and non-OEM specific ways to do this, both in native and managed code. In native code, one can use the wireless device functions (GetWirelessDevice, ChangeRadioState, FreeDeviceList) in the Wireless Device Power Management API (OSSVCS.dll) as described in this article. And in managed code, one can take advantage of the OpenNETCF Smart Device Framework.

Here’s an example of how to use the OpenNETCF.WindowsMobile namespace in the Smart Device Framework for toggling the state of wireless devices:

using System.Linq;
using OpenNETCF.WindowsMobile;
 
static class Program
{
    static void Main()
    {
        var wifi = from radio in Radios.GetRadios()
                   where radio.RadioType == RadioType.WiFi
                   select radio;
 
        foreach (var radio in wifi)
            radio.RadioState = (radio.RadioState == RadioState.On) ? RadioState.On : RadioState.Off;
    }
}

I hope you found this article useful



Semi-Transparent Controls in .NETCF

Some time ago, I wrote an article called Transparent Controls in .NETCF which describes how to accomplish transparency in the .NET Compact Framework. In this article I’d like to discuss how to control the opacity levels of transparent controls. This is made possible by alpha blending the parent controls background image with the child controls background color or image.

Here is an example of semi-transparent controls.

The screen shots above contain a semi-transparent PictureBox, Label, and Button controls. The button control is very Vista inspired, having 2 vertical fading gradient fills and then alpha blending it with the background image

Implementing Semi-Transparent Controls

The container or parent control will be the same code I used in my previous article.

Windows Mobile 5 and higher offers 2 ways of alpha blending, one through the function AlphaBlend (GDI) and through the Imaging API (COM). In this example let’s use the AlphaBlend function.

To begin with we need to define the BLENDFUNCTION structure that we’ll use as a parameter to AlphaBlend.

struct BLENDFUNCTION
{
    public byte BlendOp;
    public byte BlendFlags;
    public byte SourceConstantAlpha;
    public byte AlphaFormat;
}
 
enum BlendOperation : byte
{
    AC_SRC_OVER = 0x00
}
 
enum BlendFlags : byte
{
    Zero = 0x00
}
 
enum SourceConstantAlpha : byte
{
    Transparent = 0x00,
    Opaque = 0xFF
}
 
enum AlphaFormat : byte
{
    AC_SRC_ALPHA = 0x01
}

Next step is to define our P/Invoke declaration for AlphaBlend

[DllImport("coredll.dll")]
static extern bool AlphaBlend(
    IntPtr hdcDest,
    int xDest,
    int yDest,
    int cxDest,
    int cyDest,
    IntPtr hdcSrc,
    int xSrc,
    int ySrc,
    int cxSrc,
    int cySrc,
    BLENDFUNCTION blendfunction);

We’ll be using the GradientFill method as well in this example. For this we need to define 2 structures, TRIVERTEX and GRADIENT_RECT

struct TRIVERTEX
{
    private int x;
    private int y;
    private ushort Red;
    private ushort Green;
    private ushort Blue;
    private ushort Alpha;
 
    public TRIVERTEX(int x, int y, Color color)
        : this(x, y, color.R, color.G, color.B, color.A)
    {
    }
 
    public TRIVERTEX(
        int x, int y,
        ushort red, ushort green, ushort blue,
        ushort alpha)
    {
        this.x = x;
        this.y = y;
        Red = (ushort)(red << 8);
        Green = (ushort)(green << 8);
        Blue = (ushort)(blue << 8);
        Alpha = (ushort)(alpha << 8);
    }
}
 
struct GRADIENT_RECT
{
    private uint UpperLeft;
    private uint LowerRight;
 
    public GRADIENT_RECT(uint ul, uint lr)
    {
        UpperLeft = ul;
        LowerRight = lr;
    }
}

Using the 2 structures above we can now define our P/Invoke for GradientFill

[DllImport("coredll.dll")]
static extern bool GradientFill(
    IntPtr hdc,
    TRIVERTEX[] pVertex,
    uint dwNumVertex,
    GRADIENT_RECT[] pMesh,
    uint dwNumMesh,
    uint dwMode);

And then lets wrap those neatly in some extension methods to the Graphics class

public static class GraphicsExtension
{
    public static void AlphaBlend(this Graphics graphics, Image image, byte opacity)
    {
        AlphaBlend(graphics, image, opacity, Point.Empty);
    }
 
    public static void AlphaBlend(this Graphics graphics, Image image, byte opacity, Point location)
    {
        using (var imageSurface = Graphics.FromImage(image))
        {
            var hdcDst = graphics.GetHdc();
            var hdcSrc = imageSurface.GetHdc();
 
            try
            {
                var blendFunction = new BLENDFUNCTION
                {
                    BlendOp = ((byte)BlendOperation.AC_SRC_OVER),
                    BlendFlags = ((byte)BlendFlags.Zero),
                    SourceConstantAlpha = opacity,
                    AlphaFormat = 0
                };
                AlphaBlend(
                    hdcDst,
                    location.X == 0 ? 0 : -location.X,
                    location.Y == 0 ? 0 : -location.Y,
                    image.Width,
                    image.Height,
                    hdcSrc,
                    0,
                    0,
                    image.Width,
                    image.Height,
                    blendFunction);
            }
            finally
            {
                graphics.ReleaseHdc(hdcDst);
                imageSurface.ReleaseHdc(hdcSrc);
            }
        }
    }
 
    public static void GradientFill(
        this Graphics graphics,
        Rectangle rectangle,
        Color startColor,
        Color endColor,
        GradientFillDirection direction)
    {
        var tva = new TRIVERTEX[2];
        tva[0] = new TRIVERTEX(rectangle.Right, rectangle.Bottom, endColor);
        tva[1] = new TRIVERTEX(rectangle.X, rectangle.Y, startColor);
        var gra = new[] { new GRADIENT_RECT(0, 1) };
 
        var hdc = graphics.GetHdc();
        try
        {
            GradientFill(
                hdc,
                tva,
                (uint)tva.Length,
                gra,
                (uint)gra.Length,
                (uint)direction);
        }
        finally
        {
            graphics.ReleaseHdc(hdc);
        }
    }
 
    public enum GradientFillDirection
    {
        Horizontal = 0x00000000,
        Vertical = 0x00000001
    }
}

Now that we can call the AlphaBlend API we can start designing a simple UI. Let’s create a container to for the semi-transparent control that exposes its background image allowing the child control to alpha blend part of the background image. Before we create our alpha button control, let’s take a quick review on How to implement transparency in .NETCF.

In my old article I expose the background image through an interface that a container control must implement, I called it IControlBackground

interface IControlBackground
{
    Image BackgroundImage { get; }
}

Now that it’s possible to retrieve the parent controls background image through a child control we can create our alpha button control. This control will be the usual button control where we will use a boolean flag to store the pushed state of the control, this state is changed during mouse events. The control is painted using 2 gradient fills using shades of black and the text is drawn in the center. Since the entire control is painted in the OnPaint event I override OnPaintBackground with blank code.

class AlphaButton : Control
{
    private bool pushed;
 
    protected override void OnMouseDown(MouseEventArgs e)
    {
        base.OnMouseDown(e);
        pushed = true;
        Invalidate();
    }
 
    protected override void OnMouseUp(MouseEventArgs e)
    {
        base.OnMouseUp(e);
        pushed = false;
        Invalidate();
    }
 
    protected override void OnPaint(PaintEventArgs e)
    {
        using (var backdrop = new Bitmap(Width, Height))
        {
            using (var gxOff = Graphics.FromImage(backdrop))
            {
                var topRect = new Rectangle(0, 0, ClientSize.Width, ClientSize.Height / 2);
                var bottomRect = new Rectangle(0, topRect.Height, ClientSize.Width, ClientSize.Height / 2);
 
                if (!pushed)
                {
                    gxOff.GradientFill(
                        bottomRect,
                        Color.FromArgb(0, 0, 11),
                        Color.FromArgb(32, 32, 32),
                        GraphicsExtension.GradientFillDirection.Vertical);
 
                    gxOff.GradientFill(
                        topRect,
                        Color.FromArgb(176, 176, 176),
                        Color.FromArgb(32, 32, 32),
                        GraphicsExtension.GradientFillDirection.Vertical);
                }
                else
                {
                    gxOff.GradientFill(
                        topRect,
                        Color.FromArgb(0, 0, 11),
                        Color.FromArgb(32, 32, 32),
                        GraphicsExtension.GradientFillDirection.Vertical);
 
                    gxOff.GradientFill(
                        bottomRect,
                        Color.FromArgb(176, 176, 176),
                        Color.FromArgb(32, 32, 32),
                        GraphicsExtension.GradientFillDirection.Vertical);
                }
 
                using (var border = new Pen(Color.White))
                    gxOff.DrawRectangle(border, 0, 0, ClientSize.Width - 1, ClientSize.Height - 1);
 
                if (!string.IsNullOrEmpty(Text))
                {
                    var size = gxOff.MeasureString(Text, Font);
                    using (var text = new SolidBrush(Color.White))
                        gxOff.DrawString(
                            Text,
                            Font,
                            text,
                            (ClientSize.Width - size.Width) / 2,
                            (ClientSize.Height - size.Height) / 2);
                }
 
                try
                {
                    var bgOwner = Parent as IControlBackground;
                    if (bgOwner != null && bgOwner.BackgroundImage != null)
                        gxOff.AlphaBlend(bgOwner.BackgroundImage, 70, Location);
                }
                catch (MissingMethodException ex)
                {
                    throw new PlatformNotSupportedException(
                        "AlphaBlend is not a supported GDI feature on this device", 
                        ex);
                }
            }
 
            e.Graphics.DrawImage(backdrop, 0, 0);
        }
    }
 
    protected override void OnPaintBackground(PaintEventArgs e)
    {
    }
}

I implement the IControlBackground interface in a simple Form class and draw my background image on the Form. I can use this directly as a container or create inherited classes and re-use the code in several occasions.

class FormBase : Form, IControlBackground
{
    Bitmap background;
 
    public FormBase()
    {
        background = new Bitmap(
            Assembly.GetExecutingAssembly().GetManifestResourceStream(
            "SemiTransparentSample.background.jpg"));
    }
 
    protected override void OnPaint(PaintEventArgs e)
    {
        e.Graphics.DrawImage(background, 0, 0);
    }
 
    public Image BackgroundImage
    {
        get { return background; }
    }
}

To finish it up let’s create a Form that will contain the alpha buttons.

class MainForm : FormBase
{
    public MainForm()
    {
        Controls.Add(new AlphaButton
        {
            Font = new Font("Arial", 16f, FontStyle.Bold),
            ForeColor = Color.White,
            Text = "Alpha Button 1",
            Bounds = new Rectangle(20, 20, 200, 50)
        });
        Controls.Add(new AlphaButton
        {
            Font = new Font("Arial", 16f, FontStyle.Bold),
            ForeColor = Color.White,
            Text = "Alpha Button 2",
            Bounds = new Rectangle(20, 90, 200, 50)
        });
        Controls.Add(new AlphaButton
        {
            Font = new Font("Arial", 16f, FontStyle.Bold),
            ForeColor = Color.White,
            Text = "Alpha Button 3",
            Bounds = new Rectangle(20, 160, 200, 50)
        });
        Controls.Add(new AlphaButton
        {
            Font = new Font("Arial", 16f, FontStyle.Bold),
            ForeColor = Color.White,
            Text = "Alpha Button 4",
            Bounds = new Rectangle(20, 230, 200, 50)
        });
    }
}

I hope you found this interesting and insightful. If you’re interested in the Visual Studio solution then you can download it here.



How to get the IP Address of a device in .NETCF

Here's something I see asked every now and then in the community forums. The solution is a one liner that looks like this:

IPAddress[] addresses = Dns.GetHostEntry(Dns.GetHostName()).AddressList;

The code above retrieves the IP addresses for each connected network adapter of the device. The Dns and IPAddress classes belong to the System.Net namespace.



How to Vibrate a Smartphone / Windows Mobile Standard device in .NETCF

The Vibrate API is only available in the Windows Mobile Standard or Smartphone platform. This has been so since Smartphone 2002. Calling Vibrate() will cause the device to vibrate, and VibrateStop() will stop it.

Here's a simple managed wrapper for the Vibrate API

public class Vibrate
{
    [DllImport("aygshell.dll")]
    static extern int Vibrate(int cvn, IntPtr rgvn, bool fRepeat, uint dwTimeout);
 
    [DllImport("aygshell.dll")]
    static extern int VibrateStop();
 
    const uint INFINITE = 0xffffffff;
 
    public static bool Play()
    {
        VibratePlay(0, IntPtr.Zero, true, INFINITE);
    }
 
    public static void Stop()
    {
        VibrateStop();
    }
}

For more information on the Vibrate API, you might want to check the MSDN Documentation out.