How to retrieve a list of installed applications using .NETCF

In this short post I’d like to demonstrate how to retrieve a list of installed applications on a Windows Mobile device using OMA Client Provisioning. First you need to add a reference to the Microsoft.WindowsMobile.Configuration assembly. To retrieve the list we need to process a specific configuration (UnInstall Configuration Service Provider) using the ConfigurationManager.ProcessConfiguration method. The configuration is described in an XML and the response to this will also be described in XML

To query the device we process this configuration:

<wap-provisioningdoc>
  <characteristic-query type="UnInstall"/>
</wap-provisioningdoc>

The query above will only return installed application that can be uninstalled. The device would then respond with something like this:

<wap-provisioningdoc>
  <characteristic type="UnInstall">
    <characteristic type="Microsoft Application#2">
      <parm name="uninstall" value="0"/>
    </characteristic>
    <characteristic type="Microsoft Application#1">
      <parm name="uninstall" value="0"/>
    </characteristic>
    <characteristic type="Demo Home Screen">
      <parm name="uninstall" value="0"/>
    </characteristic>
  </characteristic>
</wap-provisioningdoc>

And here’s how to accomplish this task using .NETCF and C#

var doc = new XmlDocument();
doc.LoadXml(@"<wap-provisioningdoc><characteristic-query type=""UnInstall""/></wap-provisioningdoc>");
doc = ConfigurationManager.ProcessConfiguration(doc, true);
 
var nodes = doc.SelectNodes("wap-provisioningdoc/characteristic[@type='UnInstall']/characteristic/@type");
foreach (var node in nodes.Cast<XmlNode>())
{
    Trace.WriteLine(node.InnerText);
}

I hope you found this useful.

Writing a Puzzle Game for Windows Phone 7 using XNA

This article is a step by step guide on how to write a puzzle game for Windows Phone 7 using XNA. Before we get started you will need the Windows Phone 7 Developer Tools. Please note that I’m not really a game developer and I might not be doing the best practices. The intention of this article is just to demonstrate how easy it is to write a game using XNA even if one has little to no experience in game development.

I’ve been playing around with XNA these past few nights and decided to write a few casual games. The first prototype I have is a port of my old Puzzle Game. The game is still really incomplete, like there is no menu or state management which means you can’t shut it down properly and stuff. But I thought I’d share some thoughts on my experience with it and at the same time share some code.

The structure of the game is fairly simple. I have 2 collections: one contains an image, another contains an index to the each of the elements of the first collection and its the area where to display the image on the screen. The collection that contains the indexes is my scrambled puzzle. Each time a piece is moved, I update the order of my scrambled list afterwards I check if all the items in my scrambled list are correctly sorted in an ascending fashion. If all the items are sorted properly then it means that the puzzle was solved.

Enough said and let’s get started. The first step is to of course fire up Visual Studio and create a new XNA Game Studio 4.0 – Windows Phone Game project. Let’s call the project PuzzleGame

Now that we have a project we can start adding some content or game assets. For this simple project, we will use 3 different game assets: the puzzle image, and 2 Sprite Font for drawing the elapsed playing time and to draw text to congratulate the player once they complete the puzzle. To add content, right click on the PuzzleGameContent project, then click on Add.

For the puzzle image, we can pick up one of the sample pictures included in Windows 7 (e.g. UsersPublicPicturesSample Pictures)

After adding the puzzle image we should change the Asset Name property to PuzzleImage. This can be done through the Properties Window (Right click on the added image in the Solution Explorer and click Properties)

To add Sprite Fonts, right click on the content project, click Add – New Item, then select Sprite Font. Let’s add 2 sprite fonts and call them GameTime and Congratulations

Let’s change the Asset Name of the Sprite Fonts we just added to GameTimeFont and CongratulationsFont

The SpriteFont content is actually just an XML file. The GameTime font’s default description should be good enough but let’s change the Congratulations font description to use a larger size. Open Congratulations.spritefont from the solution explorer and change the Size to 48, and change the Style to Bold

Now that we have our game assets in place we can start coding. A lot of initial code is generated when creating a new XNA Game Studio project. To start things clean let’s rename default Game1 class to PuzzleGame and delete all the contents leaving the PuzzleGame class empty.

Before we start implementing our PuzzleGame class we’ll need to create a class which will represent a piece of the puzzle, let’s call this PuzzlePiece

class PuzzlePiece
{
    public int Index { get; set; }
    public Vector2 Bounds { get; set; }
 
    public override int GetHashCode()
    {
        return Index.GetHashCode();
    }
 
    public override bool Equals(object obj)
    {
        var piece = obj as PuzzlePiece;
        if (piece != null)
            return Index.Equals(piece.Index);
        return base.Equals(obj);
    }
}

We’ll also need an enumeration that describes the state of the game. This state describes what to draw on the screen. Let’s call this enum DrawMode. There are 2 simple states of the game:

1. Puzzle – Draws the puzzle game
2. Congratulations – Draws a “Congratulations” text once the player solves the puzzle

enum DrawMode
{
    Puzzle,
    Congratulations
}

Now we can start implementing our PuzzleGame class. The first step is to define our global variables and the constructor method

GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D previewTexture;
Vector2 previewVector, emptyPiece, totalGameTimeVector, congratulationsVector;
SpriteFont gameTimerFont,congratulationsFont;
Dictionary<int, Texture2D> puzzlePieces;
Dictionary<int, PuzzlePiece> scrambledPieces;
DrawMode Mode;
int height, width;
double elapsedTime, playingTime;
Queue<Keys> pendingCommands;
const int PIECE_COUNT = 4 * 4;
bool solved;
static bool animating;
 
public PuzzleGame()
{
    graphics = new GraphicsDeviceManager(this);
    Content.RootDirectory = "Content";
}

Next step is to implement the Initialize() method. This method allows the game to perform any initialization it needs before it starts to run. With a simple game such as this one could debate where to put the initialization code, I could easily see myself having my initialize code in the constructor method. To make this example as XNA’ish let’s initialize our non-content variables in the Initialize() method.

/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content.  Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
    pendingCommands = new Queue<Keys>();
    Mode = DrawMode.Puzzle;
    previewVector = new Vector2(0, 0);
    totalGameTimeVector = new Vector2(10, 10);
 
    base.Initialize();
}

Next we implement the LoadContent() and UnloadContent()

/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
    spriteBatch = new SpriteBatch(GraphicsDevice);
    previewTexture = Content.Load<Texture2D>("PuzzleImage");
    gameTimerFont = Content.Load<SpriteFont>("GameTimeFont");
    congratulationsFont = Content.Load<SpriteFont>("CongratulationsFont");
 
    var size = congratulationsFont.MeasureString("Congrautulations!");
    congratulationsVector = new Vector2(
        (GraphicsDevice.Viewport.Width - size.X) / 2,
        (GraphicsDevice.Viewport.Height - size.Y) / 2);
 
    Divide();
    Scramble();
}
 
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
    previewTexture.Dispose();
    foreach (var item in puzzlePieces)
        item.Value.Dispose();
 
    spriteBatch.Dispose();
}

You probably noticed that LoadContent calls methods called Divide() and Scramble().

The Divide() method splits the puzzle image into tiny pieces represented by the PuzzlePiece class. The full puzzle image is stored in a Texture2D object called previewTexture, to split this into pieces I copy the color information of the puzzle image within a specified bounds into an array of type Color and then I set this color information in a new instance of Texture2D.

private void Divide()
{
    int idx = 0;
    int cells = Convert.ToInt32(Math.Sqrt(PIECE_COUNT));
    height = GraphicsDevice.Viewport.Height / cells;
    width = GraphicsDevice.Viewport.Width / cells;
    puzzlePieces = new Dictionary<int, Texture2D>();
    for (int y = 0; y < GraphicsDevice.Viewport.Height; y += height)
    {
        for (int x = 0; x < GraphicsDevice.Viewport.Width; x += width)
        {
            var rectangle = new Rectangle(x, y, width, height);
            var data = new Color[width * height];
            previewTexture.GetData<Color>(0, rectangle, data, 0, data.Length);
 
            var piece = new Texture2D(GraphicsDevice, width, height);
            piece.SetData(data);
 
            puzzlePieces.Add(idx++, piece);
        }
    }
}

The Scramble() method does exactly what the method name describes, it scrambles the puzzle. The field called scrambledPieces is a key/value pair collection that uses the index of the puzzlePieces collection as the key and the bounds of this image to be drawn on the screen as the value. The bounds of the image is stored in a Vector2 object.

private void Scramble()
{
    int idx = 0;
    var random = new Random();
    int capacity = puzzlePieces.Count - 1;
    scrambledPieces = new Dictionary<int, PuzzlePiece>(puzzlePieces.Count);
 
    for (int y = 0; y < GraphicsDevice.Viewport.Height; y += height)
    {
        for (int x = 0; x < GraphicsDevice.Viewport.Width; x += width)
        {
            if (idx < capacity)
            {
                var piece = new PuzzlePiece();
                while (true)
                {
                    piece.Index = random.Next(0, capacity);
                    if (!scrambledPieces.ContainsValue(piece))
                        break;
                }
 
                piece.Bounds = new Vector2(x, y);
                scrambledPieces.Add(idx++, piece);
            }
            else
                emptyPiece = new Vector2(x, y);
        }
    }
    scrambledPieces.Add(idx, new PuzzlePiece { Index = -1 });
}

All we need now is to implement the Game Loop.

The Update() method will contain the game logic. The game logic will be used for updating the game surface, collision detection, accepting and handling user input, background music, sounds effects, etc. In our game we use it for accepting and handling user input. We accept the user input through polling the Mouse state by calling the static method Mouse.GetState(). We handle the user input by doing a hit test to get which puzzle piece was clicked and moving this piece. Only one piece can be moved at a time and this piece can only move up, down, left, or right. For those who are not familiar with what a hit test is, here’s my attempt to define it: A hit test is a way of detecting if 2 objects are touching or intersecting with each other. In our case, we use hit testing to figure out which puzzle piece was clicked by checking all the pieces of the puzzle if the mouse position is inside its bounds. Moving a puzzle piece is implemented as a very basic animation that runs on a separate thread. User input is not handled while the puzzle pieces are being moved around. The update method also updates the game playing time which we later on draw on the screen.

/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
    var mouseState = Mouse.GetState();
    if (mouseState.LeftButton == ButtonState.Pressed)
    {
        if (animating)
        {
            base.Update(gameTime);
            return;
        }
 
        var clickedRectangle = new Rectangle(mouseState.X, mouseState.Y, width, height);
        var pieceRect = new Rectangle(0, 0, width, height);
 
        for (int i = 0; i < scrambledPieces.Count; i++)
        {
            pieceRect.X = (int)scrambledPieces[i].Bounds.X;
            pieceRect.Y = (int)scrambledPieces[i].Bounds.Y;
 
            if (!pieceRect.Intersects(clickedRectangle))
                continue;
 
            if (mouseState.X >= emptyPiece.X &&
                mouseState.X <= emptyPiece.X + width &&
                mouseState.Y >= emptyPiece.Y &&
                mouseState.Y <= emptyPiece.Y + height)
                continue;
 
            Keys command = Keys.None;
            if (pieceRect.X >= emptyPiece.X && pieceRect.X <= emptyPiece.X)
            {
                if (pieceRect.Y - height == emptyPiece.Y)
                    command = Keys.Up;
                else if (pieceRect.Y + height == emptyPiece.Y)
                    command = Keys.Down;
            }
            else if (pieceRect.Y >= emptyPiece.Y && pieceRect.Y <= emptyPiece.Y)
            {
                if (pieceRect.X - width == emptyPiece.X)
                    command = Keys.Left;
                else if (pieceRect.X + width == emptyPiece.X)
                    command = Keys.Right;
            }
 
            if (command != Keys.None && !pendingCommands.Contains(command))
            {
                pendingCommands.Enqueue(command);
                Debug.WriteLine("Clicked: " + i);
            }
            break;
        }
    }
    else
        elapsedTime += gameTime.ElapsedGameTime.TotalMilliseconds;
 
    if (elapsedTime >= 10)
    {
        if (pendingCommands.Count > 0)
            MovePiece(pendingCommands.Dequeue());
        elapsedTime = 0;
    }
 
    if (!solved)
        playingTime += gameTime.ElapsedGameTime.TotalMilliseconds;
 
    base.Update(gameTime);
}

The MovePiece() method does a hit test to find which piece to move. Once the correct piece is found the Animate() method is called.

private void MovePiece(Keys command)
{
    for (int i = 0; i < scrambledPieces.Count; i++)
    {
        switch (command)
        {
            case Keys.Up:
                if (scrambledPieces[i].Bounds.X == emptyPiece.X && scrambledPieces[i].Bounds.Y - height == emptyPiece.Y)
                {
                    Animate(command, i);
                    return;
                }
                break;
            case Keys.Down:
                if (scrambledPieces[i].Bounds.X == emptyPiece.X && scrambledPieces[i].Bounds.Y + height == emptyPiece.Y)
                {
                    Animate(command, i);
                    return;
                }
                break;
            case Keys.Left:
                if (scrambledPieces[i].Bounds.Y == emptyPiece.Y && scrambledPieces[i].Bounds.X - width == emptyPiece.X)
                {
                    Animate(command, i);
                    return;
                }
                break;
            case Keys.Right:
                if (scrambledPieces[i].Bounds.Y == emptyPiece.Y && scrambledPieces[i].Bounds.X + width == emptyPiece.X)
                {
                    Animate(command, i);
                    return;
                }
                break;
        }
    }
}

The Animate() method starts a thread in the ThreadPool which will move the puzzle piece by 2 pixels at a time until the piece is placed in the empty area. The empty area information is stored in the emptyPiece object. Once the piece is in the empty area the scrambled index of the piece is updated together with its new bounds. Finally a check if the puzzle was solved by the move is done.

private void Animate(Keys direction, int i)
{
    animating = true;
 
    ThreadPool.QueueUserWorkItem((state) =>
    {
        try
        {
            const int INCREMENT = 2;
            var newEmptyPiece = scrambledPieces[i].Bounds;
 
            while (scrambledPieces[i].Bounds != emptyPiece)
            {
                switch (direction)
                {
                    case Keys.Up:
                        scrambledPieces[i].Bounds = new Vector2(emptyPiece.X, scrambledPieces[i].Bounds.Y - INCREMENT);
                        break;
                    case Keys.Down:
                        scrambledPieces[i].Bounds = new Vector2(emptyPiece.X, scrambledPieces[i].Bounds.Y + INCREMENT);
                        break;
                    case Keys.Left:
                        scrambledPieces[i].Bounds = new Vector2(scrambledPieces[i].Bounds.X - INCREMENT, emptyPiece.Y);
                        break;
                    case Keys.Right:
                        scrambledPieces[i].Bounds = new Vector2(scrambledPieces[i].Bounds.X + INCREMENT, emptyPiece.Y);
                        break;
                }
                Thread.Sleep(1);
            }
 
            emptyPiece = newEmptyPiece;
        }
        finally
        {
            UpdateScrambledIndex(direction, i);
            CheckForCompletion();
            animating = false;
        }
    });
}
 
private void UpdateScrambledIndex(Keys command, int index)
{
    int newIndex = -1;
    int INCREMENT = Convert.ToInt32(Math.Sqrt(PIECE_COUNT));
    switch (command)
    {
        case Keys.Up:
            newIndex = index - INCREMENT;
            if (newIndex < 0) newIndex = 0;
            break;
        case Keys.Down:
            newIndex = index + INCREMENT;
            if (newIndex > scrambledPieces.Count - 1) newIndex = scrambledPieces.Count - 1;
            break;
        case Keys.Left:
            newIndex = index - 1;
            if (newIndex < 0) newIndex = 0;
            break;
        case Keys.Right:
            newIndex = index + 1;
            if (newIndex > scrambledPieces.Count - 1) newIndex = scrambledPieces.Count - 1;
            break;
    }
 
    var temp = scrambledPieces[newIndex];
    scrambledPieces[newIndex] = scrambledPieces[index];
    scrambledPieces[index] = temp;
}
 
private void CheckForCompletion()
{
    for (int i = 0; i < scrambledPieces.Count - 1; i++)
        if (scrambledPieces[i].Index != i)
            return;
 
    solved = true;
    Mode = DrawMode.Congratulations;
}

Last but not the least we implement the Draw() method. This is where we render the screen. We always start by clearing the screen and afterwards adding sprites to our SpriteBatch. In our game we only have 2 ways of rendering the screen: rendering the puzzle game in play; and rendering if the puzzle was solved.

To render the puzzle game I add a sprite that draws the game playing time on the top left corner then I add a sprite for each piece of the puzzle by iterating through my scrambledPieces collection..

To render the screen when the puzzle is solved I draw 2 sprites. One is the playing time and the other is “Congratulations”

/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.Black);
 
    spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
 
    switch (Mode)
    {
        case DrawMode.Puzzle:
            spriteBatch.DrawString(gameTimerFont, new TimeSpan(0, 0, 0, 0, (int)playingTime).ToString(), totalGameTimeVector, Color.White);
            for (int i = 0; i < scrambledPieces.Count; i++)
            {
                if (scrambledPieces[i].Index == -1) continue;
                var piece = puzzlePieces[scrambledPieces[i].Index];
                spriteBatch.Draw(piece, scrambledPieces[i].Bounds, Color.White);
            }
            break;
        case DrawMode.Congratulations:
            spriteBatch.DrawString(gameTimerFont, new TimeSpan(0, 0, 0, 0, (int)playingTime).ToString(), totalGameTimeVector, Color.White);
            spriteBatch.DrawString(congratulationsFont, "Congratulations!", congratulationsVector, Color.White);
            break;
    }
 
    spriteBatch.End();
 
    base.Draw(gameTime);
}

I hope you found this article useful and educational. You can grab the source code here

Cropping an Image in .NETCF

I’ve seen some people ask how to crop an image in .NET Compact Framework in the community. Although the operation is pretty simple, I’ll share a code snippet anyway.

public static Image Crop(Image image, Rectangle bounds)
{
    Image newImage = new Bitmap(bounds.Width, bounds.Height);
 
    using (Graphics g = Graphics.FromImage(newImage))
        g.DrawImage(image, 
                    new Rectangle(0, 0, newImage.Width, newImage.Height), 
                    bounds, 
                    GraphicsUnit.Pixel);
 
    return newImage;
 
}

What the code above does is to create a new image and draw part of the source image specified in the bounds to the new image.

Themed Image Button in .NETCF

In this article I’d like to demonstrate how to create a themed image button control. I’ll be using the same techniques in my previous article, How to draw a textured rounded rectangle and Semi-Transparent Controls in .NETCF.

First, we need to define our theme. We get the start and end gradient colors from alpha blending the SystemColors.Highlight color and Color.White

class Theme
{
    public static Color AlphaBlend(Color value1, Color value2, int alpha)
    {
        int ialpha = 256 - alpha;
        return Color.FromArgb((value1.R * alpha) + (value2.R * ialpha) >> 8,
                              (value1.G * alpha) + (value2.G * ialpha) >> 8,
                              (value1.B * alpha) + (value2.B * ialpha) >> 8);
    }
 
    public static Color GradientLight
    {
        get
        {
            var color = AlphaBlend(SystemColors.Highlight, Color.White, 100);
            return AlphaBlend(Color.White, color, 50); ;
        }
    }
 
    public static Color GradientDark
    {
        get
        {
            var color = AlphaBlend(SystemColors.Highlight, Color.Black, 256);
            return AlphaBlend(Color.White, color, 50); ;
        }
    }
}

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, 
    int dwNumVertex, 
    GRADIENT_RECT[] pMesh, 
    int dwNumMesh, 
    int dwMode);

Let’s wrap the P/Invoke call to GradientFill in a nice method

const int GRADIENT_FILL_RECT_V = 0x00000001;
 
public static void GradientFill(
    this Graphics graphics,
    Rectangle rect,
    Color startColor,
    Color endColor)
{
    var tva = new TRIVERTEX[2];
    tva[0] = new TRIVERTEX(rect.X, rect.Y, startColor);
    tva[1] = new TRIVERTEX(rect.Right, rect.Bottom, endColor);
    var gra = new GRADIENT_RECT[] { new GRADIENT_RECT(0, 1) };
 
    var hdc = graphics.GetHdc();
    GradientFill(hdc, tva, tva.Length, gra, gra.Length, GRADIENT_FILL_RECT_V);
    graphics.ReleaseHdc(hdc);
}

In order to use the function we need to create a few GDI objects: a Pen to draw the border, and a Brush to fill the rectangle. We will mostly use P/Invoke for creating and releasing GDI objects

const int PS_SOLID = 0;
const int PS_DASH = 1;
 
[DllImport("coredll.dll")]
static extern IntPtr CreatePen(int fnPenStyle, int nWidth, uint crColor);
 
[DllImport("coredll.dll")]
static extern int SetBrushOrgEx(IntPtr hdc, int nXOrg, int nYOrg, ref Point lppt);
 
[DllImport("coredll.dll")]
static extern IntPtr CreateSolidBrush(uint color);
 
[DllImport("coredll.dll")]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobject);
 
[DllImport("coredll.dll")]
static extern bool DeleteObject(IntPtr hgdiobject);
 
[DllImport("coredll.dll")]
static extern IntPtr CreatePatternBrush(IntPtr HBITMAP);
 
[DllImport("coredll.dll")]
static extern bool RoundRect(
    IntPtr hdc, 
    int nLeftRect, 
    int nTopRect, 
    int nRightRect, 
    int nBottomRect, 
    int nWidth, 
    int nHeight);

We’ll draw a textured rounded rectangle with a gradient fill that uses the current theme’s Highlight color as the base color.

public static void DrawThemedGradientRectangle(
    this Graphics graphics,
    Pen border,
    Rectangle area,
    Size ellipseSize)
{
    using (var texture = new Bitmap(area.Right, area.Bottom))
    {
        using (var g = Graphics.FromImage(texture))
            GradientFill(g, area, Theme.GradientLight, Theme.GradientDark);
 
        FillRoundedTexturedRectangle(graphics, border, texture, area, ellipseSize);
    }
}
 
static IntPtr CreateGdiPen(Pen pen)
{
    var style = pen.DashStyle == DashStyle.Solid ? PS_SOLID : PS_DASH;
    return CreatePen(style, (int)pen.Width, GetColorRef(pen.Color));
}
 
public static void FillRoundedTexturedRectangle(
    this Graphics graphics,
    Pen border,
    Bitmap texture,
    Rectangle rect,
    Size ellipseSize)
{
    Point old = new Point();
 
    var hdc = graphics.GetHdc();
    var hpen = CreateGdiPen(border);
    var hbitmap = texture.GetHbitmap();
    var hbrush = CreatePatternBrush(hbitmap);
 
    SetBrushOrgEx(hdc, rect.Left, rect.Top, ref old);
    SelectObject(hdc, hpen);
    SelectObject(hdc, hbrush);
 
    RoundRect(hdc, rect.Left, rect.Top, rect.Right, rect.Bottom, ellipseSize.Width, ellipseSize.Height);
 
    SetBrushOrgEx(hdc, old.Y, old.X, ref old);
    DeleteObject(hpen);
    DeleteObject(hbrush);
 
    graphics.ReleaseHdc(hdc);
}

Let’s wrap all the code above as extension methods to the Graphics class and use them in our owner drawn button control. A button control is one of the easiest owner drawn controls to create. Let’s keep it as simple as possible and only have 2 states for our button: pressed and not pressed.

class ThemedImageButton : Control
{
    bool pushed = false;
    private Bitmap image;
    private Bitmap offScreen;
 
    public Bitmap Image
    {
        get { return image; }
        set
        {
            image = value;
            Invalidate();
        }
    }
 
    protected override void OnResize(EventArgs e)
    {
        base.OnResize(e);
 
        if (offScreen != null)
        {
            offScreen.Dispose();
            offScreen = null;
        }
        offScreen = new Bitmap(ClientSize.Width, ClientSize.Height);
    }
 
    protected override void OnPaint(PaintEventArgs e)
    {
        if (offScreen == null)
            offScreen = new Bitmap(ClientSize.Width, ClientSize.Height);
 
        using (var attributes = new ImageAttributes())
        using (var g = Graphics.FromImage(offScreen))
        {
            if (pushed)
            {
                using (var pen = new Pen(SystemColors.Highlight))
                    g.DrawThemedGradientRectangle(pen, ClientRectangle, new Size(4, 4));
            }
            else
                g.Clear(Parent.BackColor);
 
            var textSize = g.MeasureString(Text, Font);
            var textArea = new RectangleF(
                (ClientSize.Width - textSize.Width) / 2,
                (ClientSize.Height - textSize.Height),
                textSize.Width,
                textSize.Height);
 
            if (Image != null)
            {
                var imageArea = new Rectangle(
                    (ClientSize.Width - Image.Width) / 2,
                    (ClientSize.Height - Image.Height) / 2,
                    Image.Width,
                    Image.Height);
 
                var key = Image.GetPixel(0, 0);
                attributes.SetColorKey(key, key);
 
                g.DrawImage(
                    Image,
                    imageArea,
                    0, 0, Image.Width, Image.Height,
                    GraphicsUnit.Pixel,
                    attributes);
            }
 
            using (var brush = new SolidBrush(ForeColor))
                g.DrawString(Text, Font, brush, textArea);
 
            if (pushed)
            {
                var key = offScreen.GetPixel(0, 0);
                attributes.SetColorKey(key, key);
            }
            else
                attributes.ClearColorKey();
 
            e.Graphics.DrawImage(
                offScreen,
                ClientRectangle,
                0, 0, offScreen.Width, offScreen.Height,
                GraphicsUnit.Pixel,
                attributes);
        }
    }
 
    protected override void OnPaintBackground(PaintEventArgs e)
    {
    }
 
    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 OnParentChanged(EventArgs e)
    {
        base.OnParentChanged(e);
        Invalidate();
    }
 
    protected override void OnTextChanged(EventArgs e)
    {
        base.OnTextChanged(e);
        Invalidate();
    }
}

I hope you found this useful. If you’re interested in the full source code then you can grab it here

How to enumerate files on a Windows CE based device from the Desktop

In this article I’d like to demonstrate how to enumerate files on a Windows CE based device from the desktop.

Listing the contents of a directly on a Windows CE from the desktop is something I found to be useful every now and then. It involves using the Remote API and ActiveSync / Windows Mobile Device Center

As usual this will involve a few P/Invokes:

[DllImport("rapi.dll", CharSet = CharSet.Unicode)]
static extern int CeRapiInit();
 
[DllImport("rapi.dll", CharSet = CharSet.Unicode)]
static extern int CeRapiUninit();
 
[DllImport("rapi.dll", CharSet = CharSet.Unicode)]
static extern IntPtr CeFindFirstFile(string lpFileName, ref CE_FIND_DATA lpFindFileData);
 
[DllImport("rapi.dll", CharSet = CharSet.Unicode)]
static extern bool CeFindNextFile(IntPtr hFindFile, ref CE_FIND_DATA lpFindFileData);
 
[DllImport("rapi.dll", CharSet = CharSet.Unicode)]
static extern bool CeFindClose(IntPtr hFindFile);

We also need the CE_FIND_DATA structure

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct CE_FIND_DATA
{
    public int dwFileAttributes;
    public FILETIME ftCreationTime;
    public FILETIME ftLastAccessTime;
    public FILETIME ftLastWriteTime;
    public int nFileSizeHigh;
    public int nFileSizeLow;
    public int dwOID;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string cFileName;
};
 
[StructLayout(LayoutKind.Sequential)]
struct FILETIME
{
    public int dwLowDateTime;
    public int dwHighDateTime;
}

The CeRapiInit method has be always called before performing Remote API operations. Once done, the CeRapiUninit must be called. For listing the files in a directory, I use CeFindFirstFile, CeFindNextFile, and CeFindClose. How this works: If the file(s) exists CeFindFirstFile will return a valid handle that can be used for calling CeFindNextFile. After going through all the files CeFindNextFile will return false and a call to CeFindClose needs to be called.

public static string[] GetFiles(string remoteDirectory)
{
    try
    {
        CeRapiInit();
 
        var list = new List<string>();
        var findData = new CE_FIND_DATA();
        var hFindFile = CeFindFirstFile(remoteDirectory + "\*", ref findData);
 
        if (hFindFile != new IntPtr(-1))
        {
            try
            {
                do
                {
                    if (findData.dwFileAttributes != (int)FileAttributes.Directory)
                        list.Add(findData.cFileName);
                } while (CeFindNextFile(hFindFile, ref findData));
            }
            finally
            {
                CeFindClose(hFindFile);
            }
        }
 
        return list.ToArray();
    }
    finally
    {
        CeRapiUninit();
    }
}

I hope you found this useful.

How to draw a textured rounded rectangle in .NETCF

I’d like to demonstrate how to draw patterned rounded rectangles by P/Invoking the GDI function RoundRect using a patterned brush instead of a solid brush. Let’s create an extension method called FillRoundedTexturedRectangle to the Graphics class. With this method we can fill rectangles with an image. This image will be drawn as tiles to fill the rectangle bounds. This method can come in handy for drawing complex textures or patterns into a rectangle. With a little alpha blending and gradient fills, one can achieve a modern glass effect in the user interface

We create our brush with the CreatePatternBrush function instead of CreateSolidBrush as we did in my previous article on How to draw a rounded rectangle in .NETCF. We will mostly use P/Invoke for creating and releasing GDI objects.

const int PS_SOLID = 0;
const int PS_DASH = 1;
 
[DllImport("coredll.dll")]
static extern IntPtr CreatePen(int fnPenStyle, int nWidth, uint crColor);
 
[DllImport("coredll.dll")]
static extern int SetBrushOrgEx(IntPtr hdc, int nXOrg, int nYOrg, ref Point lppt);
 
[DllImport("coredll.dll")]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobject);
 
[DllImport("coredll.dll")]
static extern bool DeleteObject(IntPtr hObject);
 
[DllImport("coredll.dll")]
static extern IntPtr CreatePatternBrush(IntPtr hbmp);
 
[DllImport("coredll.dll")]
static extern bool RoundRect(
    IntPtr hdc, 
    int nLeftRect, 
    int nTopRect, 
    int nRightRect, 
    int nBottomRect, 
    int nWidth, 
    int nHeight);
 
static uint GetColorRef(Color value)
{
    return 0x00000000 | ((uint)value.B << 16) | ((uint)value.G << 8) | (uint)value.R;
}

Now we have our P/Invoke definitions in place we can neatly wrap all P/Invoke operations in a single function and let’s call that FillRoundedTexturedRectangle()

public static void FillRoundedTexturedRectangle(
    this Graphics graphics,
    Pen border,
    Bitmap texture,
    Rectangle rectangle,
    Size ellipseSize)
{
    var lppt = new Point();
    var hdc = graphics.GetHdc();
    var style = border.DashStyle == DashStyle.Solid ? PS_SOLID : PS_DASH;
    var hpen = CreatePen(style, (int)border.Width, GetColorRef(border.Color));
    var hbrush = CreatePatternBrush(texture.GetHbitmap());
 
    try
    {
        SetBrushOrgEx(hdc, rectangle.Left, rectangle.Top, ref lppt);
        SelectObject(hdc, hpen);
        SelectObject(hdc, hbrush);
 
        RoundRect(hdc,
                  rectangle.Left,
                  rectangle.Top,
                  rectangle.Right,
                  rectangle.Bottom,
                  ellipseSize.Width,
                  ellipseSize.Height);
    }
    finally
    {
        SetBrushOrgEx(hdc, lppt.Y, lppt.X, ref lppt);
        DeleteObject(hpen);
        DeleteObject(hbrush);
 
        graphics.ReleaseHdc(hdc);
    }
}

To use this extension method you need to create a Bitmap and a Pen. The pen will be used to draw the rounded border, and the Bitmap will be used as a fill (tiled). Here’s an example where “e” is an instance of PaintEventArgs

using (var pen = new Pen(SystemColors.Highlight, 5))
using (var texture = new Bitmap(@"windowsmsn.gif"))
    e.Graphics.FillRoundedTexturedRectangle(pen, 
                                            texture, 
                                            ClientRectangle, 
                                            new Size(8, 8));

I hope you found this useful. If you’re interested in the full source code then you can grab it here

How to draw a rounded rectangle in .NETCF

In this short article I’d like to demonstrate how to draw rounded rectangles by P/Invoking the GDI function RoundRect. Let’s create an extension method called FillRoundedRectangle to the Graphics class.

In order to use the function we need to create a few GDI objects: a Pen to draw the border, and a Brush to fill the rectangle. We will mostly use P/Invoke for creating and releasing GDI objects

const int PS_SOLID = 0;
const int PS_DASH = 1;
 
[DllImport("coredll.dll")]
static extern IntPtr CreatePen(int fnPenStyle, int nWidth, uint crColor);
 
[DllImport("coredll.dll")]
static extern int SetBrushOrgEx(IntPtr hdc, int nXOrg, int nYOrg, ref Point lppt);
 
[DllImport("coredll.dll")]
static extern IntPtr CreateSolidBrush(uint color);
 
[DllImport("coredll.dll")]
static extern IntPtr SelectObject(IntPtr hdc, IntPtr hgdiobject);
 
[DllImport("coredll.dll")]
static extern bool DeleteObject(IntPtr hgdiobject);
 
[DllImport("coredll.dll")]
static extern bool RoundRect(
    IntPtr hdc, 
    int nLeftRect, 
    int nTopRect, 
    int nRightRect, 
    int nBottomRect, 
    int nWidth, 
    int nHeight);

The CreateSolidBrush function in native code actually takes a COLORREF parameter, and the developer would normally use the RGB macro to create it. We need to translate that macro into a .NET function

static uint GetColorRef(Color value)
{
    return 0x00000000 | ((uint)value.B << 16) | ((uint)value.G << 8) | (uint)value.R;
}

Now we have our P/Invoke definitions in place we can neatly wrap all P/Invoke operations in a single function and let’s call that FillRoundedRectangle()

public static void FillRoundedRectangle(
    this Graphics graphics,
    Pen border,
    Color color,
    Rectangle rectangle,
    Size ellipseSize)
{
    var lppt = new Point();
    var hdc = graphics.GetHdc();
    var style = border.DashStyle == DashStyle.Solid ? PS_SOLID : PS_DASH;
    var hpen = CreatePen(style, (int)border.Width, GetColorRef(border.Color));
    var hbrush = CreateSolidBrush(GetColorRef(color));
 
    try
    {
        SetBrushOrgEx(hdc, rectangle.Left, rectangle.Top, ref lppt);
        SelectObject(hdc, hpen);
        SelectObject(hdc, hbrush);
 
        RoundRect(hdc, 
                  rectangle.Left, 
                  rectangle.Top, 
                  rectangle.Right, 
                  rectangle.Bottom, 
                  ellipseSize.Width, 
                  ellipseSize.Height);
    }
    finally
    {
        SetBrushOrgEx(hdc, lppt.Y, lppt.X, ref lppt);
        DeleteObject(hpen);
        DeleteObject(hbrush);
 
        graphics.ReleaseHdc(hdc);
    }
}

Using this extension method should be straight forward, but here’s an example where “e” is an instance of PaintEventArgs:

using (var pen = new Pen(Color.Blue))
    e.Graphics.FillRoundedRectangle(
        pen, 
        Color.LightBlue, 
        new Rectangle(10, 10, 100, 100), 
        new Size(16, 16));

I hope you found this useful. If you’re interested in the full source code then you can grab it here

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 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

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.