Screen Scraping with C#?


  I like to play Hearts on MSN Gaming Zone.  I would like to write a program that tracks the different cards that have been played for each round.  So, the question is how do I screen scrape a graphical window using C#?

The steps in my mind would consist of something like:

1) Get the device context of the foreign (Hearts) window
2) Capture the graphic bits in a well-defined, never changing location
3) Compare those graphics (the face of the card) with a library of 52 cards looking for a match

Can anyone help me with this?  Never mind if it is cheating or not, it is a way for me to learn more about graphics and programming.  I would consider giving more points if 500 is not enough for this challenge.


Who is Participating?
thedude112286Connect With a Mentor Commented: was used extensively to develop this

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

class GDI32
      public static extern bool BitBlt(int hdcDest,int nXDest,int nYDest,
                                       int nWidth,int nHeight,int hdcSrc,
                                       int nXSrc,int nYSrc,int dwRop);
      public static extern int CreateCompatibleBitmap(int hdc,int nWidth,
                                                       int nHeight);
      public static extern int CreateCompatibleDC(int hdc);
      public static extern bool DeleteDC(int hdc);
      public static extern bool DeleteObject(int hObject);
      public static extern int GetDeviceCaps(int hdc,int nIndex);
      public static extern int SelectObject(int hdc,int hgdiobj);

class User32
      public static extern int FindWindow(string lpClassName, string lpWindowName);
      public static extern int GetWindowDC(int hWnd);
      public static extern int ReleaseDC(int hWnd,int hDC);

class Example
        string className, windowText;
        //the className parameter must be the name of the target window's class
        //and windowText must be the text of the target window - if you've never done
        //straight Win32 API programming and don't understand this concept, ask me
      public void CaptureScreen(string fileName,ImageFormat imageFormat, string className, string windowText)
                  this.className = className;
                this.windowText = windowText;
                  int hdcSrc = User32.GetWindowDC(User32.FindWindow(className, windowText));
            int hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
            int hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc),
            // set the nWidth, nHeight, nXSrc, and nYSrc parameters of BitBlt to whatever portion of the window you want
            Bitmap bitmap = GetManagedBitmap(hBitmap,fileName,imageFormat);
                  //do whatever operations you want to do on bitmap
      private void Cleanup(int hBitmap,int hdcSrc,int hdcDest)
            User32.ReleaseDC(User32.FindWindow(className, windowText),hdcSrc);

      private Bitmap GetManagedBitmap(int hBitmap,string fileName,ImageFormat imageFormat)
            Bitmap image =
            new Bitmap(Image.FromHbitmap(new IntPtr(hBitmap)),
                       Image.FromHbitmap(new IntPtr(hBitmap)).Width,
                       Image.FromHbitmap(new IntPtr(hBitmap)).Height);
            return image;
rmyhreAuthor Commented:
Wow... a lot to disect there... thanks.

What I don't see is step 3... how to compare the two images?

Any help?
I'm going away for the weekend but I'll look into comparing the images when I get back.
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

All I can think of is to try:

if ( screenBitmap == storedBitmap )

That should work fine as long as you get the EXACT same area of the window when you store the bitmap and when you get a bitmap to compare.
Actually, I'm not sure about how == works on Bitmaps.  You may need to examine each bit to see if it is equal.
rmyhreAuthor Commented:
I figured it out over the weekend.  Basically I dump the bitmap into a memory stream and then convert the memory stream into a byte array.  Finally, I just iterate through the array checking each value to ensure that they are the same in both the stored image and the scanned image.

Works pretty slick  :)
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.