我正在尝试定期编写应用程序窗口的副本。如果窗口正常化,事情就可以正常工作了。在桌面上。但是如果窗口最小化,我只得到最小化的命令栏。
我尝试过使用SendMessage和WM_PRINT以及PrintWindow的各种方法但没有成功。在下面使用SendMessage的代码中,我知道规范化窗口的正确大小用于创建位图。我知道通过DefWindowProc对WM_PRINT的默认处理生成了WM_PRINTCLIENT消息。 hWnd是最小化窗口的句柄。
HDC scrdc, memdc;
HBITMAP membit;
WINDOWPLACEMENT WP;
EncoderParameters encoderParameters;
ULONG quality;
Status status;
RECT Rect;
WP.length = sizeof (WP);
WP.flags = 0;
WP.showCmd = 0;
GetWindowPlacement (hWnd, &WP);
int WPHeight = WP.rcNormalPosition.bottom - WP.rcNormalPosition.top;
int WPWidth = WP.rcNormalPosition.right - WP.rcNormalPosition.left;
scrdc = GetWindowDC (hWnd); // source DC
GetWindowRect(hWnd,&Rect); // source Rectangle
int Height = Rect.bottom-Rect.top; // source height
int Width = Rect.right-Rect.left; // source width
if (WP.showCmd == SW_SHOWMINIMIZED)
{
Height = WPHeight;
Width = WPWidth;
}
memdc = CreateCompatibleDC(scrdc); // destination DC
membit = CreateCompatibleBitmap(scrdc, Width, Height); // destination bitmap
HBITMAP hOldBitmap =(HBITMAP) SelectObject(memdc, membit); // add bitmap to DC
// copy screen to new BitMap
// BitBlt(memdc, 0, 0, Width, Height, scrdc, 0, 0, SRCCOPY);
// PrintWindow (hWnd, memdc, 0);
BitBlt
(
memdc,
0,
0,
GetDeviceCaps(memdc,HORZRES),
GetDeviceCaps(memdc,VERTRES),
NULL,
NULL,
NULL,
WHITENESS
);
SendMessage (hWnd, WM_PRINT, unsigned int (memdc), PRF_CLIENT|PRF_NONCLIENT);
这是WM_PRINT,WM_PRINTCLIENT和WM_PAINT处理程序的代码
case WM_PRINT:
return DefWindowProc (hWnd, message, wParam, lParam);
case WM_PRINTCLIENT:
Screen.WMPrint (hWnd, HDC (wParam), NULL);
return true;
return DefWindowProc (hWnd, message, wParam, lParam);
case WM_PAINT:
Screen.WMPaint (hWnd);
break;
我也知道Screen.WMPrint会在HDC中涂写适当的内容。
因此,如果有人能给我一些提示或建议一种方法,我会非常感激。我可以使用Screen.WMPaint但是我只得到客户区并错过命令栏和边框。
我不想对窗口进行规范化,因为这会使用户烦恼。
答案 0 :(得分:0)
这很难,因为当你的窗口被最小化时,它看起来并不像它未被最小化的自我。
WM_PRINT
打印窗口的非客户区域(因为你传递了标志),通过调用通常的WM_NCPAINT处理程序。并且该处理程序查看窗口状态,因此如果它被最小化,您将无法获得所需的内容。然后它尝试打印客户区,但(我怀疑)这里也是最小化状态导致跳过这部分 - 最小化窗口有效没有客户区。
调用内部绘图程序可能是最简单的解决方案。是的,它只会给你客户区。请注意,当您将鼠标悬停在最小化窗口的磁贴上时,您在Windows 7任务栏上看到的预览也会排除非客户区域。我认为这太难了。
答案 1 :(得分:0)
在你的WM_PAINT处理程序中,假设你正在使用双缓冲,让你的backbuffer hdc全局,然后当你想拍摄程序的快照时,只需将HDC写入屏幕外的位图,然后就可以了
这是你的WM_PAINT处理程序应该是这样的: http://pastebin.com/aNvtHiD6
答案 2 :(得分:0)
这可能只是构造这样的位图。我认为在每次绘制操作之后,为了获得标题栏和边框,必须在整个窗口的位图上闪烁。然后可以擦除客户区。这将给出一个可以进行各种GDI操作的起点。更复杂的是,任何控件(如滚动条,日期控件,编辑框等)都必须单独捕获并添加到位图中。对于我的申请,我认为我不会处理最小化的情况。我在将控件放到新位图上时遇到了麻烦。控件的问题出现是因为人们不能简单地让它们成为主窗口的子项,因为你拥有的只是一个位图,窗口本身被最小化或控件被遮挡或离开屏幕。