我的任务是使用类似于Windows的剪切工具的功能重新创建应用程序.其中一个是捕获当前活动的窗口的屏幕截图,这就是导致我出现问题的原因.一切都几乎完全没问题,但是应用程序的"剪切"比实际的应用程序大几个像素,这是因为它的窗口比我设置的略小.
这是我在主窗口上的CreateWindow调用我测试它:
hwnd = CreateWindow(TEXT("Klasa okien"), TEXT("Screenshot"), WS_OVERLAPPEDWINDOW, 10, 10, 350, 400, NULL, NULL, hInstance, NULL);
然后收集有关该窗口大小的信息并继续"采取剪切"功能的过程:
RECT okno; HWND aktywne = GetForegroundWindow(); GetWindowRect(aktywne, &okno); CaptureScreen(okno.left, okno.top, okno.right-okno.left, okno.bottom-okno.top);
最后是获取这些剪辑的部分功能:
void CaptureScreen(int x, int y, int width, int height) { HDC hDc = CreateCompatibleDC(0); HBITMAP hBmp = CreateCompatibleBitmap(GetDC(0), width, height); SelectObject(hDc, hBmp); BitBlt(hDc, 0, 0, width, height, GetDC(0), x, y, SRCCOPY); Bitmap *p_bmp = Bitmap::FromHBITMAP(hBmp, NULL); ...
正如我所说 - 一切都很好,正在创建的图片实际上是350x400但实际窗口的大小似乎是336x393.我还附上了两张照片 - 完美的剪辑是由Windows工具创建的,另一张是我的.
我的工具350x400的结果和 Windows的截图工具336x393的结果
这个问题是Windows 10特有的,它与Windows 10透明边框有关.例如,如果窗口重新调整边框大小,则左/右/底部的边框大约为7个像素.
如果您正在拍摄屏幕截图,则可能希望排除透明边框.替换GetWindowRect
为:
DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &rc, sizeof(RECT)); //requires at least Windows Vista
与之相比GetWindowRect
,从DwmGetWindowAttribute
左侧,右侧和底部获得的矩形可以小约7个像素.
#include "Dwmapi.h" #pragma comment( lib, "Dwmapi.lib" ) ... RECT rc; DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &rc, sizeof(RECT)); int w = rc.right - rc.left; int h = rc.bottom - rc.top; HDC memdc = CreateCompatibleDC(hdc); HBITMAP bmp = CreateCompatibleBitmap(hdc, w, h); SelectObject(memdc, bmp); BitBlt(memdc, 0, 0, w, h, hdc, rc.left, rc.top, CAPTUREBLT | SRCCOPY); ...
其次,不要使用GetDC(0)
(以这种方式),因为它会导致资源泄漏.您必须保存从中获取的句柄GetDC
并在以后释放它.例如:
HWND desktopWnd = GetDesktopWindow(); HDC hdc = GetDC(desktopWnd); ... ReleaseDC(desktopWnd, hdc);
编辑:
或使用
HDC hdc = GetDC(0); ... ReleaseDC(0, hdc);