Click here to Skip to main content
Click here to Skip to main content

Capturing the Desktop Screen with the Mouse Cursor Image

By , 27 Jan 2006
 

Sample Image - DesktopCaptureWithMouse.jpg

Introduction

This article shows how you can capture screen images including the mouse cursor.

Background

Screen capturing is a very useful way of resource sharing as used in applications like Remote Desktop, Virtual Network Computing (VNC), where a user can access, view, and interact with a remote desktop as his own desktop. Also, it is used in non ethical applications like hacking applications, where a hacker can hack a computer using some malicious server application, and the server then frequently takes screenshots of the prey machine and sends them to the clients. You will see a lot of source code resources over the internet discussing how to take screenshots of the desktop or an area of the desktop but none of them discuss how to capture the mouse cursor bitmap with the screenshot. Sometimes it becomes necessary to capture the mouse to see the whole activity of the hacked machine. First, we will discuss here what the actual problem is.

Problem

Most of us think that the mouse cursor image is a part of the desktop display but actually it works on an upper layer over the desktop. Windows always tracks mouse with a “Hot Spot”, the actual position seen by the Windows.

Currently, there are two common ways to capture and manipulate the desktop image:

  1. Copy the desktop bitmap data from Video Memory to the System Memory. Do processing and then again blit it back to the Video Memory. This can be easily done using the BitBlt() or the StretchBlt() APIs provided by Win32.
  2. Another way is to directly manipulate the desktop bitmap in the Video Memory if enough memory is available as provided by DirectDraw.

Both of these don’t provide us the facility to capture the mouse cursor image with the desktop image.

Solution

The solution to the problem of capturing the mouse cursor image with the desktop image is quite simple.

  1. First, get the bitmap of the screen using BitBlt(). I have provided a simple function named CaptureDesktop() in the CaptureScreen.cs file that captures the screen bitmap as almost all the codes available over the internet do.
  2. Then capture the mouse cursor bitmap as:

    Get Cursor Icon:

    First, get the cursor information using the Win32 GetCursorInfo(). The function fills the CURSORINFO structure provided as a parameter. Don't forget to initialize the cbSize member of the structure before passing it as an argument. Then we check whether the cursor is visible or not, by checking for the equality of the flags member of the filled structure with the CURSOR_SHOWING constant. If they are equal then we get the handle to the cursor icon using the CopyIcon() function that takes the hCursor member of the above filled structure.

    Get Cursor Position:

    Now, we have to get the Icon information so that we can get the hotspot position. This information is easily retrieved using the GetIconInfo() function. Here is the C# implementation of the mouse capturing function:

    static Bitmap CaptureCursor(ref int x, ref int y)
    {
       Bitmap bmp;
       IntPtr hicon;
       Win32Stuff.CURSORINFO ci = new Win32Stuff.CURSORINFO(); 
       Win32Stuff.ICONINFO icInfo;
       ci.cbSize = Marshal.SizeOf(ci);
       if(Win32Stuff.GetCursorInfo(out ci))
       {
           if (ci.flags == Win32Stuff.CURSOR_SHOWING)
           { 
               hicon = Win32Stuff.CopyIcon(ci.hCursor);
               if(Win32Stuff.GetIconInfo(hicon, out icInfo))
               {
                   x = ci.ptScreenPos.x - ((int)icInfo.xHotspot);
                   y = ci.ptScreenPos.y - ((int)icInfo.yHotspot);
                   Icon ic = Icon.FromHandle(hicon);
                   bmp = ic.ToBitmap(); 
    
                   return bmp;
               }
           }
       }
       return null;
    }
  3. We now have both the bitmaps, i.e., the desktop bitmap and the mouse cursor bitmap with its position on the screen. Now, it's time to place the mouse cursor bitmap on the desktop bitmap. I have provided the following function that places the mouse cursor image over the desktop bitmap at the proper position:
    public static Bitmap CaptureDesktopWithCursor()
    {     
       int cursorX = 0;
       int cursorY = 0;
       Bitmap desktopBMP;
       Bitmap cursorBMP;
       Bitmap finalBMP;
       Graphics g;
       Rectangle r;
       desktopBMP = CaptureDesktop();
       cursorBMP = CaptureCursor(ref cursorX, ref cursorY);
       if(desktopBMP != null)
       {
           if (cursorBMP != null)
           {
               r = new Rectangle(cursorX, cursorY, 
                       cursorBMP.Width, cursorBMP.Height);
               g = Graphics.FromImage(desktopBMP);
               g.DrawImage(cursorBMP, r);
               g.Flush();
               return desktopBMP;
           }
           else
               return desktopBMP;
       }
       return null;
    }
  4. The bitmap with the cursor is now ready to be rendered over a viewer surface (a PictureBox used here). Since the viewer's visible area is smaller than the desktop bitmap area, scaling has been used in the function that displays the cooked desktop image.
    // ssWithMouseViewer is the PictureBox control
    private void Display(Bitmap desktop)
    {
        Graphics g;
        Rectangle r;
        if(desktop != null)
        {
            r = new Rectangle(0,0,ssWithMouseViewer.Width, 
                                ssWithMouseViewer.Height);
            g = ssWithMouseViewer.CreateGraphics();
            g.DrawImage(desktop,r);
            g.Flush();
        }
    }

Note

The binary image provided is compiled with Visual Studio .NET 2005 so you have to install .NET Framework 2.0.

Known problems

I have tested the application on my machine with no known problems, so I expect the same behavior on your machine.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Rashid.Mahmood
Web Developer
Pakistan Pakistan
Member
He is always interested to write technical articles that address the problems of the programmers community.
 
He loves to develope softares using C++, VC++ and C#. He also likes programming in Java due to its high portability. His area of interest is Graphics side esp. Games.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionCan I do it by C++?memberliaoyuandeyehuo8 May '13 - 18:41 
GeneralMy vote of 5memberDeepak Joy Jose18 Sep '12 - 21:14 
GeneralMy vote of 5memberSpoolrd27 Jul '12 - 13:47 
QuestionDistant Learning Appmemberblarejazi26 Jun '12 - 11:34 
QuestionCapture mouse point without desktop capturememberMember 912992816 Jun '12 - 8:17 
GeneralMy vote of 5member(BlackBox) Ethical Hacker31 Oct '10 - 5:33 
GeneralHimemberFazFazFaz30 Sep '10 - 10:30 
GeneralCan't capture cursor's shape like ' I ' and tip's textmemberdong36423 Jul '10 - 17:37 
GeneralNot working in gamememberShargon_8515 Apr '10 - 22:58 
GeneralvncmemberNezam Ahamed21 Feb '10 - 18:34 
QuestionCopy using BitBlt?memberLone Developer2 Sep '08 - 22:40 
QuestionRemote Desktop Monitoring in C#.NetmemberMember 371451227 Dec '07 - 3:15 
AnswerRe: Remote Desktop Monitoring in C#.Netmemberšprici4 Mar '10 - 4:33 
QuestionVC++ :(memberSobaan12 Jan '07 - 17:43 
QuestionText CursormemberFornazin11 Jan '07 - 9:29 
AnswerRe: Text CursormemberFornazin24 Jan '07 - 7:07 
QuestionIT is not rendering me desktop image with mousemembergabrousman8 Jan '07 - 5:17 
QuestionHow can i control the remote Desktop Through Mouse and Key BoardmemberMe the Lover29 Dec '06 - 8:26 
QuestionHave you solved the IBeam cursor problem?memberGlobulus15 Mar '06 - 1:44 
AnswerRe: Have you solved the IBeam cursor problem?memberssheldon7 Mar '07 - 17:31 
GeneralLeak in CaptureCursor found and fixed!memberGlobulus14 Mar '06 - 4:51 
GeneralRe: Leak in CaptureCursor found and fixed!memberham-z9 Sep '07 - 17:01 
GeneralRe: Leak in CaptureCursor found and fixed!memberGhzanfar_Ali21 Mar '10 - 10:06 
GeneralExcellentmembermrsnipey13 Mar '06 - 23:39 
QuestionLeak in CaptureCursor?memberGlobulus12 Mar '06 - 7:07 
AnswerRe: Leak in CaptureCursor?memberRashid.Mahmood12 Mar '06 - 20:22 
GeneralRe: Leak in CaptureCursor?memberGlobulus12 Mar '06 - 21:42 
GeneralRe: Leak in CaptureCursor? [modified]memberTwiggy Ramirez13 Jul '09 - 4:13 
GeneralWin32 and GDImemberScott Elder5 Mar '06 - 17:03 
GeneralRe: Win32 and GDImemberRashid.Mahmood5 Mar '06 - 18:54 
GeneralRe: Win32 and GDImemberScott Elder5 Mar '06 - 19:06 
AnswerRe: Win32 and GDImemberRazi Al-Sayed9 Apr '06 - 9:09 
GeneralSelected areasmemberMichael J. Collins31 Jan '06 - 4:10 
Questionanother question :)memberketan1430 Jan '06 - 22:05 
AnswerRe: another question :)memberRashid.Mahmood31 Jan '06 - 19:32 
GeneralRe: another question :)memberketan1413 Mar '06 - 0:10 
GeneralRe: another question :)memberDaniel Repich31 May '06 - 11:04 
Question"Desktop" ???memberfwsouthern28 Jan '06 - 10:44 
AnswerRe: "Desktop" ???memberRashid.Mahmood29 Jan '06 - 19:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 27 Jan 2006
Article Copyright 2006 by Rashid.Mahmood
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid