I am using Microsoft Visual Studio 2010 and Windows 7 Professional. This is my code to copy window image to clipboard:
void PrintWindowEx( HWND hWnd )
{
HDC hDCMem = CreateCompatibleDC(NULL);
RECT rect;
GetWindowRect(hWnd, &rect);
HBITMAP hBmp = NULL;
HDC hDC = GetDC(hWnd);
hBmp = CreateCompatibleBitmap(hDC, rect.right - rect.left, rect.bottom - rect.top);
HGDIOBJ hOld = SelectObject(hDCMem, hBmp);
PrintWindow(hWnd, hDCMem, 0);
SelectObject(hDCMem, hOld);
DeleteObject(hDCMem);
OpenClipboard(hWnd);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBmp);
CloseClipboard();
ReleaseDC(hWnd, hDC);
}
It works fine with all windows except Google Chrome main window. I thought that it was because Chrome uses direct rendering, so I have disabled hardware acceleration in chrome://settings
. Still does not work. Then I realized that working with messages can be limited due to restrictions in Chrome Sandbox, so I started Chrome with --no-sandbox
command line option. Still does not work.
How can I get this to work? For Chrome and any other windows like Chrome. BitBlt()
is not acceptable because window some parts of the window may be overlapped by another windows, window can be on other desktop, etc. Is there any working solution? Maybe with DLL loading to another process or something like that.
UPD: It does redraw after RedrawWindow()
; so I can take screenshot (some parts - left part (width ~20px) and right part are not copied). So, does it support WM_PRINT
or not? How can I take full screenshot of the window?
I was stuck for ages on this, then found that I can pass a parameter of PW_RENDERFULLCONTENT as the last parameter to PrintWindow. Googling that shows it's new in Windows 8.1 so presumably doesn't work on 7. It may be worth trying it though, Winuser.h defines it as
#if(_WIN32_WINNT >= 0x0603)
#define PW_RENDERFULLCONTENT 0x00000002
#endif /* _WIN32_WINNT >= 0x0603 */
PrintWindow works by sending a WM_PRINT or WM_PRINTCLIENT to the target window. While DefWindowProc handles WM_PRINT
for standard window classes, custom window classes must handle WM_PRINT
in order for PrintWindow
to produce the desired result. If Chrome doesn't handle WM_PRINT
or WM_PRINTCLIENT
, there's nothing you can do.
When targeting Windows Vista and above you can use the DWM Thumbnail API to force a window to render its contents into a target window provided by the client.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With