Environment: VC6 SP3, Windows 98
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.
The idea for developing the article came to me when I had downloaded 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 utility. The MSDN sample WinCap could have served the purpose, but the source was not available on the CD so I stared developing the article in MFC using the Win32 sample provided on the MSDN CD (WinCap). Also, I can capture portions of the screen, which I had done some time ago in Visual Basic because screen capture in Visual Basic is much easier and code for this is available in the Knowledge Base section of Visual Basic.
This article has the following features:
- Capture the Desktop
- Capture a Window
- Capture a Client Area
- Capture a Control (Button)
In addition, it has the following intresting, but not so useful (in my opinion), features:
- Track the X and Y coordinates of the captured image
- Trace the color code of a specific point of the captured image
Options 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, and build the project. In case there are no errors at build-time, execute the project; an icon of a camera will appear in the System Tray (bar at the bottom of the screen). Right-click the the icon and a menu will pop up. Select the options from the menu.
|Capture Desktop||Captures an image of the System Desktop immediately|
|Capture Window||Prompts to click on window to capture|
|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||Displays 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 can be displayed when you select “Show Window” from the pop-up menu.
How it Works
When capturing a window, 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 calls the member function
void CCapITView::OnCaptureChanged(CWnd *pWnd), which calls
WindowCapture(HWND hwnd), which in turn carries out the job of capturing the image (until the menu is disabled).
After completing the 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 to capture the Desktop image immediately because 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!
The 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 CScrollView instead of CView because, if the image being captured is bigger in size (for example, the Desktop), the Frame Window may not be able to capture the entire image because CView will capture as per the CView Client Area size.
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,
HANDLE AllocRoomForDIB(BITMAPINFOHEADER bi, HBITMAP hBitmap,
HPALETTE GetSystemPalette(HWND hwnd)
int PalEntriesOnDevice(HDC hDC)