I have just started programming in VC++, and this is my first article on CodeProject. I have created this project after reading the materials from CodeProject itself.
Everybody knows about the Screen Capture (Prt Scr Button) utility that comes with each and every Microsoft Windows. So what is the necessity of another Screen Capture application. But the Screen Capture utility that ships with Windows is very simple, you can only capture the whole screen. But what if you have to capture the part of the screen or say only a particular control on other window. Don't worry; here is the application for that. Using this application, you can capture the Selected area rather than the whole window. You can also capture any window or control by just clicking on it. (You can even capture only the start button or clock on task bar). Isn't it good! And it uses a simple Win32 API function for that.
This article uses the two main functions of the Win32 API:
SetWindowsHookEx(): To Set the global Mouse Hook (see MSDN for more help about this.) Global Mouse Hook is necessary to capture the Mouse Event from outside of our window.
BitBlt() (pronounced as Bitblit): Used to transfer color data between source device context and destination device context. It is used here to Capture the Screen.
Using the Code
Below is the code from MyMouseHook.cpp. Here we are sending
MOUSE_DOWN message when user presses the left Mouse Button and
MOUSE_UP when user leaves the left Mouse Button. Both of these are user messages.
LRESULT CALLBACK MyMouseHookProc(int nCode, WPARAM wParam, LPARAM lParam)
HWND hWndApp = FindWindow(0,L"Capture");
if(wParam== WM_LBUTTONDOWN || wParam == WM_NCLBUTTONDOWN)
if(wParam == WM_LBUTTONUP)
Below is the part of the code used in ScreenCaptureDlg.cpp File. When the user first presses the Mouse Button after pressing the Capture button, we take that point as the starting point in
Begpt as a starting point. And after dragging the Mouse when the user releases the button, we take the End points of the Selected Rectangle in
Endpt. Then we capture the area between this
Endpt from Desktop to
MemDC and send it to the
SaveBitmap()function which will save DC into .bmp file. And then we will create a process to show the .bmp file into PAIN application. Don't worry about the other function I haven't explain here. I have explained all the things well in the code:
if(CaptureActWnd == TRUE)
GetCursorPos(&Begpt); hWndActWnd= WindowFromPoint(Begpt); CaptureActiveWindow(); EndDialog(hWndDlg,LOWORD(lParam)); PostQuitMessage(0); }
OutputDebugString( L"Desktop -GDI, MOUSE_DOWN");
if(CaptureActWnd == FALSE)
GetCursorPos(&Endpt); DrawBox(); MemDC = CreateCompatibleDC(DlgDC);
hBitmap = CreateCompatibleBitmap(DlgDC,width,height);
Points of Interest
I tried to capture
WM_MOUSEMOVE event to draw the rectangle on screen rather than capture only
WM_LBUTTONUP but it was making the application very sluggish. So I left it and took only Starting Point and End Points to draw the rectangle and capture the screen. So you will not be able to see the rectangle when you will be selecting the area, but the rectangle will appear when you will complete your selection.
To Arun Krishnan for his nice article on Desktop Calendar from where I came to know how to save the DC(Device Context)in .bmp file.
To Mumtaz Zaheer for his nice project about Sweep the Minesweeper from where I came to know about global hook.
There was a little flaw in the previous version of the application. When it was capturing the Window, it was failing to capture the Title bar which is also important. I have fixed the problem in the updated version.