#include "stdafx.h"
#include <Windows.h>
#include <gdiplus.h>
#include <conio.h>
#pragma warning(disable : 4996)
#pragma comment (lib,"Gdiplus.lib")
using namespace Gdiplus;
int GetEncoderClsid(const WCHAR* format,
CLSID* pClsid)
{
UINT num = 0;
UINT size = 0;
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if (size == 0)
return -1;
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if (pImageCodecInfo == NULL)
return -1;
GetImageEncoders(num, size, pImageCodecInfo);
for (UINT j = 0; j < num; ++j)
{
if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0)
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j;
}
}
free(pImageCodecInfo);
return -1;
}
//========================================================================================================
BOOL xPrintWindow(HWND hWnd, HDC hDc, HDC hDcScreen)
{
BOOL ret = FALSE;
RECT rect;
GetWindowRect(hWnd, &rect);
HDC hDcWindow = CreateCompatibleDC(hDc);
HBITMAP hBmpWindow = CreateCompatibleBitmap(hDc, rect.right - rect.left, rect.bottom - rect.top);
SelectObject(hDcWindow, hBmpWindow);
if (PrintWindow(hWnd, hDcWindow, 0))
{
BitBlt(hDcScreen,
rect.left,
rect.top,
rect.right - rect.left,
rect.bottom - rect.top,
hDcWindow,
0,
0,
SRCCOPY);
ret = TRUE;
}
DeleteObject(hBmpWindow);
DeleteDC(hDcWindow);
return ret;
}
void EnumWindowsTopToDown(HWND owner, WNDENUMPROC proc, LPARAM param)
{
HWND currentWindow = GetTopWindow(owner);
if (currentWindow == NULL)
return;
if ((currentWindow = GetWindow(currentWindow, GW_HWNDLAST)) == NULL)
return;
while (proc(currentWindow, param) && (currentWindow = GetWindow(currentWindow, GW_HWNDPREV)) != NULL);
}
struct EnumHwndsPrintData
{
HDC hDc;
HDC hDcScreen;
};
BOOL CALLBACK EnumHwndsPrint(HWND hWnd, LPARAM lParam)
{
EnumHwndsPrintData *data = (EnumHwndsPrintData *)lParam;
if (!IsWindowVisible(hWnd))
return TRUE;
xPrintWindow(hWnd, data->hDc, data->hDcScreen);
DWORD style = GetWindowLongA(hWnd, GWL_EXSTYLE);
SetWindowLongA(hWnd, GWL_EXSTYLE, style | WS_EX_COMPOSITED);
/*OSVERSIONINFOA versionInfo;
ZeroMemory(&versionInfo, sizeof(OSVERSIONINFO));
versionInfo.dwOSVersionInfoSize = sizeof(versionInfo);
GetVersionExA(&versionInfo);
if (versionInfo.dwMajorVersion < 6)
EnumWindowsTopToDown(hWnd, EnumHwndsPrint, (LPARAM)data);*/
return TRUE;
}
void testPrintWindow(int serverWidth, int serverHeight)
{
RECT rect;
HWND hWndDesktop = GetDesktopWindow();
GetWindowRect(hWndDesktop, &rect);
HDC hDc = GetDC(NULL);
HDC hDcScreen = CreateCompatibleDC(hDc);
HBITMAP hBmpScreen = CreateCompatibleBitmap(hDc, rect.right, rect.bottom);
SelectObject(hDcScreen, hBmpScreen);
EnumHwndsPrintData data;
data.hDc = hDc;
data.hDcScreen = hDcScreen;
EnumWindowsTopToDown(NULL, EnumHwndsPrint, (LPARAM)&data);
if (serverWidth > rect.right)
serverWidth = rect.right;
if (serverHeight > rect.bottom)
serverHeight = rect.bottom;
if (serverWidth != rect.right || serverHeight != rect.bottom)
{
HBITMAP hBmpScreenResized = CreateCompatibleBitmap(hDc, serverWidth, serverHeight);
HDC hDcScreenResized = CreateCompatibleDC(hDc);
SelectObject(hDcScreenResized, hBmpScreenResized);
SetStretchBltMode(hDcScreenResized, HALFTONE);
StretchBlt(hDcScreenResized, 0, 0, serverWidth, serverHeight,
hDcScreen, 0, 0, rect.right, rect.bottom, SRCCOPY);
DeleteObject(hBmpScreen);
DeleteDC(hDcScreen);
hBmpScreen = hBmpScreenResized;
hDcScreen = hDcScreenResized;
}
//=======================================================================================================
// ========== HBITMAP to bmp file ===========
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
Bitmap *image = new Bitmap(hBmpScreen, NULL);
CLSID myClsId;
int retVal = GetEncoderClsid(L"image/bmp", &myClsId);
image->Save(L"output.bmp", &myClsId, NULL);
delete image;
GdiplusShutdown(gdiplusToken);
//=======================================================================
}
int _tmain(int argc, _TCHAR* argv[])
{
testPrintWindow(800, 600);
_getch();
return 0;
}