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

Barry's Screen Capture

By , 11 Jan 2003
 

Sample Image - CapIT.jpg

Introduction

This article demonstrates the methods of capturing different portions of the screen. You have the facility to then save the captured image to a file.

Background

The idea for developing the article came to me when I had downloaded such a utility for capturing screen-shots for use in my articles like this one, on the Internet, but unfortunately the downloaded utility had too many nagging screens and obviously for a no-nags version I had to pay which I cannot afford. So the only way out was to develop one on my own, the MSDN sample WinCap could have served the purpose but the source was not available on the CD. So I started developing the article in MFC using the Win32 sample provided on the MSDN CD (WinCap). And also so as to be able to capture portions of the screen which I had done sometime ago in Visual Basic, since screen capture in Visual Basic is much easier and code for this is available in the Knowledge Base section of Visual Basic.

Features

This article has the following features.

  • Capture the Desktop
  • Capture a window
  • Capture a client area
  • Capture a control (e.g. Button)

In addition it has the following, interesting but not so useful (in my view) features:

  • Track the X and Y coordinates of the captured image
  • Trace the color code of a specific point of the captured image

Option for color and position tracking are on the MainFrame window of the system and can only be used after capturing an image.

How to use the project

Download the project source, unzip the files to some folder, build the project, in case there are no error at build-time, execute the project, a Icon of a Camera will appear in the System Tray (bar at the bottom of the screen), Right-Click on the the Icon and a menu will pop-up, select the options from the menu.

Sample Image

Pop-up Menu

Option Task performed
Capture Desktop Captures a image of the System Desktop immediately
Capture Window Prompts to click on window to be captured
Capture Client Area Prompts to click on client area to capture
Capture Control Prompts to click on control to capture
Clear Image Clears captured image
Show Window Display the CapIT System Window
Close Closes the CapIT System

In addition to the pop-up menus the CapIT System has it own main menu which cap be displayed when you select "Show Window" from the pop-up menu.

How it works

When capturing window or client area or control, the system calls the function SetCapture() and waits for the user to click on some window on the Desktop which is to be captured. After clicking on the area to be captured, the system framework call the member function void CCapITView::OnCaptureChanged(CWnd *pWnd) which calls WindowCapture(HWND hwnd) which in turn carries out the job of capturing the image (till the menu are disabled). After completion of capture the system calls ReleaseCapture() to release SetCapture(). But in the case of capturing the Desktop SetCapture() is not called, but directly calls WindowCapture(HWND hwnd) passing to it GetDesktopWindow()->m_hWnd and the system proceeds with capturing the Desktop image immediately, since there is only one Desktop area and its HWND is known to the System.

Note :

The following member functions in the class CCapITView are borrowed from the MSDN sample WinCap. Could I have written them on my own, No Way.

  • HBITMAP CopyWindowToBitmap(CWnd* wnd , HWND hWnd, WORD fPrintArea)
  • HBITMAP CopyScreenToBitmap(LPRECT lpRect)
  • BOOL PaintBitmap(HDC hDC, LPRECT lpDCRect, HBITMAP hDDB, LPRECT lpDDBRect, HPALETTE hPal)
  • void DoSize(CWnd* wnd , HBITMAP ghBitmap)
  • void SetupScrollBars(CWnd* wnd , WORD cxBitmap, WORD cyBitmap)
  • void ReallyGetClientRect(CWnd* wnd , LPRECT lpRect)
  • WORD SaveDIB(HDIB hDib, LPSTR lpFileName)
  • WORD PaletteSize (VOID FAR * pv)
  • WORD DibNumColors (VOID FAR * pv)
  • HDIB ChangeBitmapFormat(HBITMAP hBitmap, WORD wBitCount, WORD dwCompression, HPALETTE hPal, HWND hwnd)
  • HANDLE AllocRoomForDIB(BITMAPINFOHEADER bi, HBITMAP hBitmap , HWND hwnd)
  • HPALETTE GetSystemPalette(HWND hwnd)
  • int PalEntriesOnDevice(HDC hDC)

Known problems

Color of the saved image under Windows 98 is not the same as of the captured image, but I think it is nearly the same in Windows 2000.

Points of interest

The project uses a CScrollView instead of CView because if the image being captured is bigger in size (e.g. Desktop) then in the Frame Window you may not be able to capture the entire image since a CView will capture as per the CView Client Area size.

History

  • Version 1

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

Barretto VN
India India
Member
Nothing to boast about

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

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralScrolling dont workmembercppoju23 Nov '07 - 12:18 
You wrote that CScrollView class is used for capture images those are bigger to capture the entire image. I tried to capture Client Area at NotePad window with big document inside, there was both scrollbars (vertical and horizontal). Captured image was only the visible part of window. I cant find scrolling part of source code, is there any scrolling capabilities?
GeneralAlt-Tabmembernaykid319 Sep '06 - 7:41 
I need to document operation of Alt-Tab under windows. Do you know of a way to capture the Alt-Tab window to place in documentation? CapIT.exe does not work. As as the mouse button is pressed on the CapIT menu the Alt-Tab window closes.Mad | :mad:
GeneralRe: Alt-TabmemberBarretto VN19 Sep '06 - 21:38 
I developed only the capture portion, have no idea about trapping individual keys, but that should not be much of a problem in a actual situation.
QuestionCan I get your email?memberXueyan30 Jul '06 - 16:22 
Hello, Barry,
 
I am very interesting in this article about screen capture. Can I get your email address? I want to discuss some question with you.
 
I am sorry I can not connect your homepage, so I sent the message here.
 
Thanks.
 
Xueyan
2006.7.31
QuestionHow to capture a transparent windowmembernowlex6 Jan '06 - 11:58 
Any ideas? In Win2K and XP, we have transparent windows.
 
Thanks,
Nowlex
AnswerRe: How to capture a transparent window [modified]memberAlexandru28 May '06 - 20:08 
I've noticed that transparent windows can be captured by using PrintScreen.
 
Then why not simulate the pressing of the PrintScreen key? Doing this, you'll get a copy of the full screen into the clipboard.
 
Then open the clipboard, grab the full screen bitmap and then use BitBlt to extract the area under the transparent window you're interesed in.
 
HWND hWndTransparentWindow;//you need to know this
RECT rectTransparentWindow;
GetWindowRect(hWndTransparentWindow,&rectTransparentWindow);
 
LONG lWidthTransparentWindow=rectTransparentWindow.right - rectTransparentWindow.left;
LONG lHeightTransparentWindow= rectTransparentWindow.bottom - rectTransparentWindow.top;
 
keybd_event(VK_SNAPSHOT,0, 0 ,0);
 
//this doesn't work ??
//INPUT input;
//input.ki.wVk=VK_SNAPSHOT;
//input.type=INPUT_KEYBOARD;
//SendInput(1,&input,sizeof(input));

//now the clipboard contains a full screen bitmap
 
OpenClipboard(NULL);

HANDLE hDataImage=GetClipboardData(CF_BITMAP);
if (NULL !=hDataImage)
{
//this is the full screen bitmap
HBITMAP hBmpBig=(HBITMAP) hDataImage;
 
HDC hDCScreen = CreateDC ("DISPLAY", NULL, NULL, NULL );
 
//create a memory device context, as large as the full screen bitmap
HDC hDCBig=CreateCompatibleDC(hDCScreen);
 
//Select the full screen bitmap into it
HGDIOBJ hOldBitmapBig = SelectObject(hDCBig, hBmpBig);
 
//now create another memory device context, as large as the transparent window
HDC hDCSmaller=CreateCompatibleDC(hDCScreen);
 
HBITMAP hBmpTransparentWindow = CreateCompatibleBitmap(hDCScreen,lWidthTransparentWindow,lHeightTransparentWindow);
 
//select the smaller bitmap
HGDIOBJ hOldBitmap = SelectObject(hDCSmaller, hBmpTransparent window);
 
//copy from the big device context into the smaller memory device context.
 
BitBlt(hDCSmaller,0,0,lWidthTransparentWindow,lHeightTransparentWindow,hDCBig, rectTransparentWindow.left, rectTransparentWindow.top, SRCCOPY);
 
SelectObject(hDCBig, hOldBitmapBig);
SelectObject(hDCSmaller, hOldBitmap);
DeleteDC(hDCSmaller);
DeleteDC(hDCBig);
DeleteDC(hDCScreen);
 
//Voila! Now you have a 'hBmpTransparentWindow' representing the transparent window image
 

}
CloseClipboard();
 

-- modified at 3:08 Monday 29th May, 2006
Generalcapture image without displaying application windowmemberjags_vc15 Feb '05 - 19:07 
hy,
Everybody,
Can it posible that capturing image of any application window
without displying it.I mean that application is running in backgroud that mean it`s window is hide,Now can i capture that
window which is hide? if yes then how?Confused | :confused:
GeneralCapturing background Windowmembertyounsi17 Jan '05 - 14:28 
Hi,
 
i am wondering if it is possible to capture the area which is behind a window. The need would be to provide a way to drag a transparent dialog which uses some region and clipping and at the end of the day try to handle a better Redraw mecanism of this window when moving the window.
The draging of the window occures in the "opaque" unix style mode when you tell your Graphics board to do this through the settings. It sounds that there is nothing in MFC which tell a Dialog to be create with a Save under copy bitmap flags and let the GDI do the stuff for you. I am also wondering if there is something with the CWnd. Something which is possible and trivial in XWindow....
 
any idea ?
 

GeneralGood Work Dude.memberThatsAlok20 Jul '04 - 23:20 
I would like to thank you for all the work you posted at Code Project,which help the new emerging programmer a lot.
 
you are a Really a great programmer.Rose | [Rose] Smile | :)
FIvw Vote Frm me
 
-----------------------------
"I Think It will Work"
Formerly Known As "Alok The Programmer" at CP
-----------------------------
Alok Gupta
visit me at http://www.thisisalok.tk
GeneralI'm happy about this articlememberGeorgi Petrov26 May '04 - 1:42 
Hi friend,
I'm trying to use your code in my ECG project, so is there any problem to use your code in to my application it is open and free too?
Generalcapturing desktopmembernandiniarun4 Apr '04 - 21:47 
capturing desktop of the server and show that at client side if any button pressed at the client side it should process at the server side and display the updated view at the client side. please help me out about this
 
nandini
GeneralRe: capturing desktopmemberBarretto VN8 Apr '04 - 23:52 
sorry i do not have a connect to any network , hence testing developing such a project is ruled out
GeneralRe: capturing desktopmemberThatsAlok20 Jul '04 - 23:17 
nandiniarun wrote:
capturing desktop of the server and show that at client side if any button pressed at the client side it should process at the server side and display the updated view at the client side. please help me out about this
 
hain i think here is your solution.
do you heard about winsocket.,if yes then
create the two application,connect them using socket and capture the image at desktop and transfer the image.
 
o0pps! soory i forget to tell you how to pass image using socket.so here is the way.
read image file into char* var and transmit that string to client machine.
and at the client part save that in a file and display that file.

 
-----------------------------
"I Think It will Work"
Formerly Known As "Alok The Programmer" at CP
-----------------------------
Alok Gupta
visit me at http://www.thisisalok.tk
Generalmore informationmembermahavirsinh vaghela3 Feb '04 - 0:15 
hi barry i would like to gain information from you that i am doing my final year project in computer engineering and i want to make an application such that it give me information about what's going on the other neighbour machines and i can handle the control of that machine.Tell me about necessary language that is best suitable for this and mail me about this all information at mahavir2002_4u@yahoo.com. Thank you.....;;P
QuestionHow to capture a hidden windowmemberSameers (theAngrycodeR )3 Jan '04 - 6:13 
Is there a way to capture a window which is hidden? Well, I am actually looking for an example for VB or VB .NET (preferably). But I can try to convert the VC example to VB (if it uses APIs only).
 
My aim is to capture a window which is not visible or hidden or its some portion is behind another window. How is it possible?
 
Thanks,
 
Sameers
AnswerRe: How to capture a hidden windowsussAnonymous9 Mar '04 - 10:29 
Yes. Try to use WM_PRINT message. For detailed explanation visit http://www.fengyuan.com.

GeneralRe: How to capture a hidden windowmemberBob McCown22 Jul '04 - 10:49 
Your link is nothing but a shill for someone's book. Bad form all around.
 
-=Bob
GeneralRe: How to capture a hidden windowmemberGATJR10 Oct '06 - 6:40 
Actually the answer to this thread is at the dudes book site. Really neat solution. Too bad you didn't dig a bit.
Hmmm | :|
AnswerRe: How to capture a hidden windowmemberguangyen11 Mar '05 - 20:19 
Try PrintWindow(...)

GeneralRe: How to capture a hidden windowmemberRajan Phatak31 Mar '05 - 19:58 
I am having problem in capturing the window when it is minimized. I dont want to maximize the window. Is there any way by which I can captur image?
GeneralRe: How to capture a hidden windowmemberfaz793 Jun '05 - 1:00 
I use this code, i don't know if it works in minimized... TRY it
memoryImage is the Bitmap you want....
 
Example
[System.Runtime.InteropServices.DllImport("gdi32.dll")]
public static extern long BitBlt (IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, int dwRop);
private Bitmap memoryImage;
private void Capture()
{
Graphics mygraphics = this.CreateGraphics();
Size s = this.Size;
memoryImage = new Bitmap(s.Width, s.Height, mygraphics);
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
IntPtr dc1 = mygraphics.GetHdc();
IntPtr dc2 = memoryGraphics.GetHdc();
BitBlt(dc2, 0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height, dc1, 0, 0, 13369376);
mygraphics.ReleaseHdc(dc1);
memoryGraphics.ReleaseHdc(dc2);
}
 
By FAZE

GeneralRe: How to capture a hidden windowmemberkajok3 Oct '06 - 6:27 
Nope. seems like you still have to bring the window to front to capture its contents.
 
Is there another way?
GeneralEverytime I pressed Capture desktop, it eats 4 MB of memory..memberMr. Jigar Mehta2 Jan '04 - 2:47 
Everytime Ipress Capture desktop, it eats 4 MB of memory according to my resolution 1184*764... When I do it repeatedly (Capture and Clear) it empties my memory.. Can you remove (Barry - for you!!!) that thing as everytime I test the program, I got out of memory...Frown | :(
 
Jigar Mehta
jigar@programmer.net
QuestionHow to Capture Screen with DirectX ?memberhiver6 Dec '03 - 3:27 
use GDI method is too slow, who know how to use DirectX capture screen
thanks!
 
hiver
AnswerRe: How to Capture Screen with DirectX ?memberKovari Attila15 Feb '04 - 21:42 
i am trying to capture the screen with directx to but till now i had no luck Frown | :(
GeneralRe: How to Capture Screen with DirectX ?memberm_idris8 Jun '04 - 19:17 
I am able to capture the desktop but the rate of capturing is very slow. If any have idea pls share with me, how to increase the rate of capturing. I am using GetFrontBufferData(). This fun is slow in both mem & CPU usage (100%).

GeneralWill try the code, save me a lot of time.memberw0705310 Jul '03 - 11:47 
Laugh | :laugh: Laugh | :laugh:
GeneralRe: Will try the code, save me a lot of time.memberMr. Jigar Mehta4 Jan '04 - 23:02 
Have you tried... the code (barry's screen capture..) I have the problem with it so i am asking that...
 
Jigar Mehta
jigar@programmer.net
GeneralRe: Will try the code, save me a lot of time.memberw070536 Jan '04 - 8:31 
Yes, I have tried it, it works fine for me.
GeneralSaving to JPGmemberbob_brown_200025 Apr '03 - 18:52 
Great program - can you help extend this to save in jpg ?
 
Robert
GeneralRe: Saving to JPGmemberThatsAlok20 Jul '04 - 23:45 
Use Cximage Library to convert the bitmap produce by this project to Jpeg,or other format like gif,png etc.
 
now question is where to find CxImage,so here is the link.
http://www.codeproject.com/bitmap/cximage.asp
 
-----------------------------
"I Think It will Work"
Formerly Known As "Alok The Programmer" at CP
-----------------------------
Alok Gupta
visit me at http://www.thisisalok.tk
GeneralRe: Saving to JPGmemberBarretto VN28 Jul '04 - 1:07 
Thanks Alok
 
you seem to be doing part of my job, thanks for the same, but i found that there is a very simple way of creating images of other formats from a .bmp file, here is how it can be done (not programatically)
 
Open the saved .bmp file in Paintbrush (.exe). from the file menu select "Save As..." , in "Save As type" pull-down select the type of image you want to save / create give a name (maybe a different one or same) and click Ok.
 
Note : this works with Windows 2000 / XP , not in WIndows 98
 
Barretto VN
 

GeneralRe: Saving to JPGmemberThatsAlok28 Jul '04 - 3:19 
Actually,
i think he want to change the format of image programmatically.that why i refer to him for CXImage Library.
 
thanks for reply.any way what r u doing sir
 
-----------------------------
"I Think It will Work"
Formerly Known As "Alok The Programmer" at CP
-----------------------------
Alok Gupta
visit me at http://www.thisisalok.tk
GeneralRe: Saving to JPGmemberBarretto VN2 Aug '04 - 1:17 
ThatsAlok wrote:
thanks for reply.any way what r u doing sir
 
Nothing !!!, hav'nt you seen my profile
GeneralGood Program.memberSeungju Choi13 Jan '03 - 19:44 
All honor to your effort
Thanks.
Smile | :)
GeneralRe: Good Program.membereegiboo12 May '03 - 16:11 
nice app. thanks Smile | :)
GeneralRe: Good Program.sussAnonymous12 Apr '05 - 19:08 
thank you very much.are u from china
Generalgood article, any equivalent in c# and vs7memberelwolv12 Jan '03 - 5:16 
any equivalent to this article in c# and vs7
how to translate window handle from win 32 to managed c#?
this sould be a totally different approach to screen capture to include in a
c# desk top program.
 
elwolvSmile | :)
 
elwolv

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 12 Jan 2003
Article Copyright 2003 by Barretto VN
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid