A game of cards?

by Dominic Zukiewicz 11. March 2008 22:40
Ever wanted to create a card game, but can't be bothered to create the card graphics?? I know what you mean! Why pay, when Microsoft have already got the cards there for you!

When Solitaire is loaded, it calls a convenient little DLL called cards.dll, which stores some Bitmap images of each card. All you have to do is know how to retrieve each one:

Firstly, the DLL needs to be kicked into action. Use the method below to retrieve the default width and height of the cards.

[DllImport("cards.dll")]
private static extern bool cdtInit(ref int width, ref int height);

Next we need to retrieve each card individually, so we need to call another method to "draw" the data to a pointer.

[DllImport("cards.dll")]
private static extern bool cdtDraw(IntPtr hdc, int x, int y, int cardValue, int cardType, Int32 color);

This method needs to take a handle, which then renders the card specified in "cardValue" to the screen. So firstly, how do we get and set an IntPtr for which the graphics are drawn to? Simple ... ish

Bitmap bmp = new Bitmap(width,height);
Graphics graph = Graphics.FromImage(bmp);
IntPtr hdc = graph.GetHdc(); //Locks the pointer
//Call the method (explained below)
graph.ReleaseHdc();

And there we go, the Bitmap now has the card stored within it. So what are the other parameters?

int x => 0
int y => 0
cardType => 0  [Front of card]
color => [Background colour of the card]

cardValue is slightly more complicated. Every card can be rendered as it is one of 52 (0-51) cards. So we just need a little formula to work out the face value (rank) of the card, and then the suit. This is:

int rank = (int)Math.Floor(cardValue / 4);
int suit = cardValue - (rank*4);

Its typical, I would list the suit values, but I seem to have deleted my cards.dll!! D'oh! A bit of trial and error and you will find them out.

So all we do is then set the Image property of the PictureBox, add that to a form and voila!

Here is a quick recap:

protected void button1_Click(....)
{
    int currentX = 10, currentY = 10;

    for(int cardIndex =0;cardIndex<52;cardIndex++)
    {
        PictureBox pb = new PictureBox();
        pb.Left = currentX;
        pb.Top = currentY;

        currentX += 10;
        currentY += 10;

        pb.Image = GetCard(cardIndex);
        this.Controls.Add(pb);

        pb.BringToFront();
    }
}

The last method, which I should have brought up earlier is to clean up the resources of course. And this is achieved with the call to:

[DllImport("cards.dll")]
private static extern void cdtTerm();

Which ensures a clean tidy up of the DLL.

I will eventually paste up some UI shots, but hopefully that will get you going!

Tags:

Powered by BlogEngine.NET 1.5.0.7
Theme by Interakting

Interakting

A full service digital agency offering online strategy, design and usability, systems integration and online marketing services that deliver real business benefits and ensure your online objectives are met.

Calendar

<<  February 2012  >>
MoTuWeThFrSaSu
303112345
6789101112
13141516171819
20212223242526
2728291234
567891011

View posts in large calendar