main.c
#include <windows.h>
#include <tlhelp32.h>
int CaptureImage(HWND hWnd)
{
int ret = 0;
RECT rt={ 0 };
HDC hdcWindow = 0;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
BITMAP bmpScreen = { 0 };
hdcWindow = GetDC(NULL);
hdcMemDC = CreateCompatibleDC(hdcWindow);
if (!hdcMemDC) {
ret = -1;
goto done;
}
rt.right = GetSystemMetrics(SM_CXSCREEN);
rt.bottom = GetSystemMetrics(SM_CYSCREEN);
if (hWnd != NULL) {
GetWindowRect(hWnd, &rt);
}
hbmScreen = CreateCompatibleBitmap(hdcWindow, rt.right-rt.left, rt.bottom-rt.top);
if (!hbmScreen) {
ret = -2;
goto done;
}
SelectObject(hdcMemDC, hbmScreen);
if (!BitBlt(hdcMemDC, 0, 0, rt.right - rt.left, rt.bottom - rt.top, hdcWindow, rt.left, rt.top, SRCCOPY)) {
ret = -3;
goto done;
}
GetObject(hbmScreen, sizeof(BITMAP), &bmpScreen);
BITMAPFILEHEADER bmfHeader;
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmpScreen.bmWidth;
bi.biHeight = bmpScreen.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
char *lpbitmap = (char*)GlobalLock(hDIB);
GetDIBits(hdcWindow, hbmScreen, 0, (UINT)bmpScreen.bmHeight, lpbitmap, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
HANDLE hFile = CreateFile("main.bmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
bmfHeader.bfSize = dwSizeofDIB;
bmfHeader.bfType = 0x4D42;
DWORD dwBytesWritten = 0;
WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);
GlobalUnlock(hDIB);
GlobalFree(hDIB);
CloseHandle(hFile);
done:
DeleteObject(hbmScreen);
DeleteObject(hdcMemDC);
ReleaseDC(NULL, hdcWindow);
return ret;
}
struct FindWindowData {
DWORD pid;
HWND hwnd;
};
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
struct FindWindowData* data = (struct FindWindowData *)lParam;
DWORD windowPid = 0;
GetWindowThreadProcessId(hwnd, &windowPid);
if (windowPid == data->pid) {
data->hwnd = hwnd;
return FALSE;
}
return TRUE;
}
HWND FindMainWindowFromPid(DWORD pid)
{
struct FindWindowData data = { 0 };
data.pid = pid;
data.hwnd = NULL;
EnumWindows(EnumWindowsProc, (LPARAM)&data);
return data.hwnd;
}
DWORD FindProcessID(const char *processName)
{
DWORD processId = 0;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot == INVALID_HANDLE_VALUE) {
return 0;
}
PROCESSENTRY32 entry;
entry.dwSize = sizeof(entry);
if (Process32First(snapshot, &entry)) {
do {
if (strcmp(entry.szExeFile, processName) == 0) {
processId = entry.th32ProcessID;
break;
}
} while (Process32Next(snapshot, &entry));
}
CloseHandle(snapshot);
return processId;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
DWORD pid = FindProcessID("hello.exe");
HWND hwnd = FindMainWindowFromPid(pid);
CaptureImage(hwnd);
ExitProcess(0);
return 0;
}