我的任务是重新创建具有与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'创建的照片。工具,另一个是我的。
Result of my tool 350x400和 Result of Windows' snipping tool 336x393
答案 0 :(得分:7)
此问题是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);
答案 1 :(得分:1)
在CreateWindow()调用AdjustWindowRectEx()之前:
int x = 10;
int y = 10;
int w = 350;
int h = 400;
RECT rect;
rect.left = x;
rect.top = y;
rect.right = x + w;
rect.bottom = y + h;
UINT style = WS_OVERLAPPEDWINDOW;
AdjustWindowRectEx( &rect, style, 0, 0 );
hwnd = CreateWindow(
TEXT("Klasa okien"), TEXT("Screenshot"), style,
rect.left, rect.top, rect.right-rect.left, rect.bottom-rect.top,
NULL, NULL, hInstance, NULL
);