My task is to recreate application with features similar to these of Windows' snipping tool. One of them is capturing a screenshot of a window that is currently active and that's what causes me problems. Everything is almost perfectly fine, however "snip" taken of an app is bigger than the actual app by few pixels and that's because it's window is slightly smaller than I set it to be.
Here's my CreateWindow call for the main window I test it on:
hwnd = CreateWindow(TEXT("Klasa okien"), TEXT("Screenshot"), WS_OVERLAPPEDWINDOW,
10, 10, 350, 400, NULL, NULL, hInstance, NULL);
then procedure of gathering information about that very window's size and proceeding to "taking snip" function:
RECT okno;
HWND aktywne = GetForegroundWindow();
GetWindowRect(aktywne, &okno);
CaptureScreen(okno.left, okno.top, okno.right-okno.left, okno.bottom-okno.top);
Finally part of the function that takes these snips:
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);
...
and as I said - everything is almost fine and the picture that is being created is in fact 350x400 BUT actual window's size seems to be 336x393. I'm also attaching two pictures - the perfectly snipped one is the one created by Windows' tool and the other one is mine.
Result of my tool 350x400 and Result of Windows' snipping tool 336x393
This issue is Windows 10 specific, it has to do with Windows 10 transparent borders. If for example window has re-sizing borders, then the borders on left/right/bottom are about 7 pixels.
If you are taking screen shot then you may wish to exclude the transparent borders. Replace GetWindowRect
with:
DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &rc, sizeof(RECT));
//requires at least Windows Vista
Compared to GetWindowRect
, the rectangle obtained from DwmGetWindowAttribute
could be smaller by about 7 pixels on left, right, and bottom.
#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);
...
Secondly, don't use GetDC(0)
(in that way), because it causes resource leak. You must save the handle obtained from GetDC
and release it later. For example:
HWND desktopWnd = GetDesktopWindow();
HDC hdc = GetDC(desktopWnd);
...
ReleaseDC(desktopWnd, hdc);
Edit:
or use
HDC hdc = GetDC(0);
...
ReleaseDC(0, hdc);
Before CreateWindow() call 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
);
AdjustWindowRectEx
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