【发布时间】:2019-07-28 19:31:41
【问题描述】:
应用程序 Melon 的宽度和高度为 438 x 615 像素, ::GetWindowRect() 函数正确抓取它。
但是,::PrintWindow() 函数绘制的尺寸较小,为 348 x 489 像素,其余部分填充黑色空白(可能不绘制任何内容)
...愿一张图胜过数百条描述。
这是代码的结果
bool result = true;
HWND appHWnd = ::FindWindow(nullptr, TEXT("Melon"));
RECT appWindowRect; ::GetWindowRect(appHWnd, &appWindowRect);
HDC appDC = ::GetWindowDC(appHWnd);
// HDC appDC = ::GetDC(appHWnd); // same issue occured either
// HDC appDC = ::GetDC(nullptr);
HDC memoryDC = ::CreateCompatibleDC(appDC);
HBITMAP capturedScreenBitmap = ::CreateCompatibleBitmap(
appDC,
appWindowRect.right - appWindowRect.left,
appWindowRect.bottom - appWindowRect.top
);
HBITMAP memoryBitmap = static_cast<HBITMAP>(::SelectObject(memoryDC, capturedScreenBitmap));
result = ::PrintWindow(appHWnd, memoryDC, 0);
//copy to clipboard
OpenClipboard(nullptr);
EmptyClipboard();
SetClipboardData(CF_BITMAP, capturedScreenBitmap);
CloseClipboard();
::SelectObject(memoryDC, memoryBitmap);
::DeleteObject(capturedScreenBitmap);
::DeleteDC(memoryDC);
::ReleaseDC(appHWnd, appDC);
奇怪的是,C# 版本的代码可以正常工作。导入相同的 user32 库,使用相同的库并输出不同的结果?为什么?
【问题讨论】:
-
您应该在将
HBITMAP从memoryDC中取消选择之前将其提供给剪贴板,但更重要的是不要在将HBITMAP提供给剪贴板之后将其删除!SetClipboardData()拥有所有权,它不会复制。这在SetClipboardData()文档中有明确的解释。此外,调用OpenClipboard()将产生一个空的HWND也是SetClipboardData()文档中提到的错误。不要这样做。 -
我发现C和C#之间的区别不是::PrintWindow而是::GetWindowRect。我不知道为什么...
-
这将取决于 DPI 意识
-
@David Heffernan 完全正确。谢谢!
-
@user3244483 您可以回答自己的问题并提供解决方案以帮助其他人在此问题上进行搜索。