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
|
/*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)
// HBITMAP g_hDeskBmp;
HDC g_hMemDC;
int g_nDCdata;
int main()
{
// get desktop window handle (but can be handle of any window)
HWND HCapture = FindWindow(NULL, _T("Map Viewer") );
// HWND HCapture = GetDesktopWindow();
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;
/** 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)
// bitmap = CreateDIBSection(HDevice, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0);
// THIS WAS WRONG DECLARATION: unsigned int * pBitmap;
GpBitmap *pBitmap = NULL; // type Gdiplus::GpBitmap
if (!PrintWindow(HCapture, HDevice, PW_CLIENTONLY)) return 2;
SelectObject (HDevice, pBitmap); // hdc, hbm is GpBitmap is hgdiobj
DllExports::GdipCreateBitmapFromHBITMAP(HBitmap, 0, &pBitmap);
ReleaseDC(HCapture, HDevice);
if(!HBitmap || !memory) return 1;
// 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;
return 0;
}
|