Export (0) Print
Expand All

Making the Move from C++ to C#

John Kennedy
Microsoft Corporation

July 24, 2002

Download Road07102002-code.exe.

As with so many things in life, sometimes the only way you can learn about something is to jump in and try it. Of course, there are notable exceptions. I wouldn't recommend learning surgery in this way, but it's definitely a good way to learn about the Smart Device Extensions (SDE) and writing programs in C# for your Pocket PC.

Yes, there's no doubt we're going to be seeing more and more of the Microsoft .NET Compact Framework, both in this column and in real world development circles. And there is even less doubt that C# is one heck of a language for making the most of the .NET Compact Framework. After developing a few programs in C#, I continue to become more and more impressed with its ease of use, flexibility, and elegance. Yes, the current beta has issues that make some things operate in a "suboptimal way" as they like to say round these parts, but these will be dealt with soon. I think it's safe to say that once you get your head around a few new concepts, you will really enjoy using C# and the .NET Compact Framework.

Card Games

We've discussed XML Web services in this column before, but I've been asked about using the Smart Device Extensions to create other, less-connected programming projects. Not every item of software needs to be Internet-aware, and this is something that tends to get overlooked in the general excitement of this new platform.

So this month, we'll walk through developing a more traditional application—a game in fact—for the Pocket PC, written in C# and making use of the .NET Compact Framework. There are some distinct differences between developing in C# and eMbedded Visual C++®, and I hope to share some of the more obvious issues that I ran into while writing this program.

The game in question will be rather simple. A version of that old card-matching favorite, Pelmanism. However, it's complicated enough to bring out some important differences and approaches, so even if you think it's beneath you, give it a try. The source code is available as a download if you want to load it up and have a play.

The design of the game is rather simple, as you can see from the screenshot below. (The photographs are all of members on my team here in the Visual C++ group. You would think by now people would be more cautious when I ask them if I can take their picture. Of course I'd rather use pictures of Drew Barrymore, but with the restraining order and everything...). Sixteen cards are on the screen, and the player "turns them over" with a tap of the stylus. If the cards match, they are taken off the screen. I'm leaving it as an exercise for the reader to add code for counting the turns, keeping score and so on. Yes, that does mean I'm lazy. Hey, I've got a day job too you know! The first person that asks me how much of my time I spend playing Halo on the Xbox™ gets a very withering look.

Figure 1. I've been approached by the Xbox team to discuss licensing rights on this you know. Well, actually that's a lie.

Graphics and the SDE

In a dramatic change from the eMbedded Visual C++ way of doing things, a C# program copies the idea of forms from Visual Basic®. Well, it's technically not a dramatic change, but I was hoping to get your attention. As you probably know, a form is simply the page onto which you can add controls, display text, receive screen tap message from, and so on. When we create a default project in Visual Studio ®.NET, we are given one default form automatically.

Figure 2. A blank form, ready for us to unleash our imaginations and stuff.

You'll notice that to the left of the form is a collection of controls, and we can drag and drop these onto the form, and hence into our program. Compared to using the eMbedded Visual C++ toolkit, you will find that the link between the visual appearance of the controls in the editor and the source code created as a result, is a lot stronger. Play with some controls and watch the code. It's impressive how Visual Studio keeps track.

A word of caution   There are regions of the source code that warn not to make changes manually. For some reason I ignored this advice, and did lose my code when I tweaked the form in the designer, so take heed.

One of the controls you can add to the form is a PictureBox, which is a control that displays an image. I'm going to use a PictureBox for each card displayed by the game. Now, this is different from how I'd have written the program originally in C++. If I were creating it for C++, I'd have created the window (which we now call a form) and obtained the HDC (Handle to a Display Context), and then used BitBlt to zap chunks of graphics data into existence. This time, I'm going to use sixteen PictureBox controls, and use their methods to define what image they display. It's rather an elegant way of doing things, as you'll see.

Of course, knowing that we have sixteen cards to display, you might be tempted to drag sixteen PictureBoxes onto the form and then size and arrange them neatly. Good idea, but it then quickly becomes a chore to deal with each one programmatically. It's far better to create an array of PictureBoxes and be able to deal with them using indices and as you'll see in a moment, that's exactly what I did. So although the designer is very useful, we won't actually use it to add the PictureBox controls.

Let's take a peek at some source code. For the most part, a C# program looks like a C++ program. There are functions, if() statements, do/whiles, and lots of curly braces. However, there are some (not so) subtle differences.

Take something as fundamental as the good old #define statement. Well, how can I break this to you? It's gone. Well, not so much gone as changed a little. In a C# program, #define can only be used to create an identifier. You can't use it to create a constant such as #define X_WIDTH 100.

While that sinks in, let's look at some array declarations too. Need a two dimensional array of integers? Forget int grid[4][4]; and instead say hello to: int[,] grid = new int[4,4] ;.

With this information, you should be able to work out what this segment from the start of our game is doing:

.

Figure 3. Creating controls programmatically is easy, and they all have methods that pop-up in the editor to give you a clue what happens next.

This section of code declares some arrays: one to store the nine different images as used by the playing cards, one to store the type of card stored in each of the 16 possible positions, and one to store the PictureBox controls themselves.

We then cycle through all these PictureBox objects, create them, add them to the form, and adjust their size and position. Notice how the methods and properties that apply to each object (for example, Location) are separated from the object by a period. The Visual Studio integrated development environment (IDE) is very smart and once you type that period, you get a pop-up list of everything that you can correctly do with that object. It's just one aspect of C# that makes it genuinely fun to code in.

Oh, if you're anything like me, you love to put MessageBox calls into your program to keep you abreast of what is happening. You still have this ability using the Smart Device Extensions: simply use the following syntax:

Messagebox.Show("Hello");

There are more options of course, consult the online help for a full list.

Looking After Your Image

Wondering how we can load some images to display as our playing cards? I was too, because the .NET Compact Framework lacks some of the functionality of the.NET Framework and my first choice methods were missing. However, it's still quite straightforward, and if you were paying attention when reading through the sample chunk of source code, you'll know it has to do with the Image object.

So, here is another chunk of code. This one is a function that I call to load images from disk (well, memory, you know what I mean) and assign it to elements in the array of Images declared previously.

Figure 4. Loading images from memory is easy-peasy.

The .bmp files are a collection of images I created in a paint program, and preshrunk to fit the size of the PictureBox control. Force of habit led me to use .bmp format, but other popular file formats are also supported.

I'm sure that you'll have spotted straightaway the try/catch exception handling, which is an optional but recommended habit to get into. If the image loading fails, the code inside the catch() { } is executed. This definitely makes for more robust and reliable code, although it's more useful if you do more than simply warn the user the program is aborting.

If you are trying out this example program using the very cool little Pocket PC emulator that ships with the Smart Device Extensions, you might be puzzled as to how to move .bmp image files from the development PC to the emulated Pocket PC. Well, let me tell you, because the procedure has changed from previous Pocket PC development tools, and if you guess, I'll be extremely impressed.

Copying Files to the Emulator

  1. Start the emulator (if you haven't already).
  2. From the Start menu, select Settings, and then the System tab.
  3. Click on About, and then the Device ID tag.
  4. Change the device name from Pocket_PC to something else.

    Figure 5. Change the device ID or you'll get an error when the emulator communicates with the desktop PC.

  5. Now start the File Explorer program on the Pocket PC.
  6. Tap the network share icon. It's the right-most icon at the bottom of the screen.
  7. Enter the details you need to access your computer over a LAN.
  8. Browse to share on the desktop PC, and select the files you want to copy.
  9. Tap and hold the files on the Pocket PC.
    Note   There is a bug in the emulator and you may need to keep the mouse button held down for 30 seconds to get the ring of red dots and subsequent pop-up menu.
  10. Copy the files, return to your Pocket PC's own directory and paste.

Figure 6. Browse to share on your desktop PC, and then copy and paste the files back to your (emulated) Pocket PC.

That's about it.

In all seriousness, that's about all there is to this little program. I've added some menus of course, using the form designer it's as easy as you might imagine. One thing that did take me a while was considering how to handle the stylus taps from the user.

In my theoretical Visual C++ program, I would own the entire screen and accept the mousedown message, decode the X and Y coordinates, and then work out what card the user was tapped. In this case, each card is a control, and each control responds to mousedown messages individually. There is no global "tap-the-screen and get a message" code I can include.

However, specifying the handler for each control is easy. It's the line in the first block of source code:

this.pictureBox[x,y].Click += new System.EventHandler(this.UserTapsScreen);

You can see that I've added the same function (UserTapsScreen) to each control. The obvious question is then "Inside that function, how do I know which control sent the message?" Here is the source code that does it:

private void UserTapsScreen(object sender, System.EventArgs e)
      {
         int cardx = -1; 
         int cardy = -1;

         // Find the card that send the message
         for (int x=0; x<4; x++)
            for (int y=0; y<4; y++)
               if (sender.Equals(pictureBox[x,y]))
               {
                  cardx = x;
                  cardy = y;
                  y=4;x=4;
               }...

Notice that the code makes use of a property of the sender argument passed into the UserTapsScreen function, and it's Equals method.

Sound Effects

What good is a game without sound effects? Well that's something we can look at next month. In the meantime, download the source and have a play. If you have any questions, feel free to e-mail me, that is unless you are that spam company that feels it's important to e-mail me twelve times a day with special offers on clothing, electronics, and pornography.

John Kennedy is a Technical Writer/Programmer in the Visual C++ group by day and leads a secret life as a Pocket PC developer by night.

Larry Roof heads up larryroof.com, a firm that specializes in consulting on mobile projects and training on eMbedded Visual Basic, Smart Device Extensions, and SQL Server CE.

Show:
© 2014 Microsoft