1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
/*Window capture example*/
#include "stdafx.h"
using namespace Gdiplus;
using namespace Gdiplus::DllExports;
// using namespace GdiPlus;
// #define SCREENWIDTH GetSystemMetrics(SM_CXSCREEN)
// #define SCREENHEIGHT GetSystemMetrics(SM_CYSCREEN)
int main()
{
/////////////////////////////////////////////////////////////////////////////////////////////////////
// PART 1 - PREPARATION OF THE BASIC BITMAP
/////////////////////////////////////////////////////////////////////////////////////////////////////
HWND HCapture = FindWindow(NULL, _T("Map Viewer") ); // get window handle
// HWND HCapture = GetDesktopWindow(); // get desktop handle (but can be handle of any window)
if(!IsWindow(HCapture)) return 1;
/*
BOOL PrintWindow(
HWND hwnd, // A handle to the window that will be copied.
HDC hdcBlt, // A handle to the device context.
UINT nFlags // The drawing options: PW_CLIENTONLY
// Only the client area of the window is copied to hdcBlt. By default, the entire window is copied.
);
*/
// get window dimensions
RECT rect; GetWindowRect(HCapture, &rect);
size_t dx = rect.right - rect.left;
size_t dy = rect.bottom - rect.top;
// create BITMAPINFO structure
// used by CreateDIBSection
BITMAPINFO info;
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biWidth = dx;
info.bmiHeader.biHeight = dy;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = 24;
info.bmiHeader.biCompression = BI_RGB;
info.bmiHeader.biSizeImage = 0;
info.bmiHeader.biXPelsPerMeter = 0;
info.bmiHeader.biYPelsPerMeter = 0;
info.bmiHeader.biClrUsed = 0;
info.bmiHeader.biClrImportant = 0;
// a bitmap handle and a pointer its bit data
HBITMAP HBitmap = 0;
BYTE* memory = 0; // ppvBits - A pointer to a variable that will receive a pointer to the location of the DIB bit values. See CreateDIBSection()
/** We should create Bitmap first and then Device Context,
however when I want to create snapshot of window, I need to use
fnc PrintWindow to copy the visual window to Device Context.
So I need to create DC first. The DC will be compatible with
current screen.
*/
// 1. FIRST we need to Create DC for PrintWindow function
// HDC HDevice = GetDC(HCapture);
HDC HDevice = CreateCompatibleDC(NULL);
// 2. SECOND we need to CREATE BITMAP (Device Independent Bitmap)
// HBitmap = CreateCompatibleBitmap(HDevice, dx, dy);
HBitmap = CreateDIBSection(HDevice, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0);
DWORD dw = GetLastError();
// 3. Make HBitmap to be destination of the following work
SelectObject(HDevice, HBitmap);
///////////////////////////////////////////////////////////////////////////////////////////
// PART 2 - GET VISUAL CONTENT OF WINDOW //
// AND SAVE IT TO BITMAP //
///////////////////////////////////////////////////////////////////////////////////////////
// THIS WAS WRONG DECLARATION: unsigned int * pBitmap;
GpBitmap *pBitmap = NULL; // type Gdiplus::GpBitmap
if (!PrintWindow(HCapture, HDevice, PW_CLIENTONLY)) return 2;
// INIT GDI
ULONG_PTR gdiplusToken;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
if (!gdiplusToken) return 3;
// pBitmap is null.
int state = Gdiplus::DllExports::GdipCreateBitmapFromHBITMAP(HBitmap, 0, &pBitmap);
ReleaseDC(HCapture, HDevice);
// if(!HBitmap || !memory) return 1;
/*
The GetWindowDC function retrieves the device context (DC) for
the entire window, including title bar, menus, and scroll bars.
A window device context permits painting anywhere in a window */
// blit the contents of the desktop (winDC)
// to the bitmap (selected in memDC)
HDC winDC = GetWindowDC(HCapture);
HDC memDC = CreateCompatibleDC(winDC);
SelectObject(memDC, HBitmap);
BitBlt(memDC, 0, 0, dx, dy, winDC, 0, 0, SRCCOPY);
DeleteDC(memDC);
ReleaseDC(HCapture, winDC);
/** THIS IS WRONG! VARIABLE CANNOT POINT TO NOWHERE!*/
// char *buffer; // First set the type and range and then make pointer:
char *buffer = new char[50]; // RIGHT DECLARATION
sprintf(buffer,"capture%d%d.bmp",dx,dy);
// create bitmap file
std::basic_ofstream <char> file(buffer, std::ios::binary);
if(!file) { DeleteObject(HBitmap); return 1; }
// initialize bitmap file headers
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
fileHeader.bfType = 0x4d42;
fileHeader.bfSize = 0;
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
infoHeader.biSize = sizeof(infoHeader);
infoHeader.biWidth = dx;
infoHeader.biHeight = dy;
infoHeader.biPlanes = 1;
infoHeader.biBitCount = 24;
infoHeader.biCompression = BI_RGB;
infoHeader.biSizeImage = 0;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;
// save file headers
file.write((char*)&fileHeader, sizeof(fileHeader));
file.write((char*)&infoHeader, sizeof(infoHeader));
// save 24-bit bitmap data
int wbytes = (((24*dx + 31) & (~31))/8);
int tbytes = (((24*dx + 31) & (~31))/8)*dy;
file.write((char*)memory, tbytes);
// delete bitmap
DeleteObject(HBitmap);
HBitmap = 0;
memory = 0;
GdiplusShutdown(gdiplusToken);
return 0;
} |
Partager