Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why GetWindowRect gives wrong values by 8 pixels?

1,915 views
Skip to first unread message

JiiPee

unread,
Apr 9, 2016, 7:08:59 AM4/9/16
to
Why does GetWindowRect give like 8 pixels too wide area when I call it
for a window? I get the windows handle by
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam);

and then do:
CRect rect;
::GetWindowRect(hWnd, rect);

But for example if I maximize my notepad and take its rect with this, it
gives:
-8, -8 as a top left. Should be 0,0. Also I can see that if I place the
Notepad somewhere else on desktop the same happens.

R.Wieser

unread,
Apr 9, 2016, 7:48:34 AM4/9/16
to
JiiPee,

> But for example if I maximize my notepad and take its rect
> with this, it gives: -8, -8 as a top left.

Thats correct. The *client-area* gets enlarged to fit the full screen,
which means that the window the client-area is in must be bigger that that
(to accomodate the windows borders).

> Also I can see that if I place the Notepad somewhere else
> on desktop the same happens.

I don't think the result will be -8, -8 every time. So, how have you come
to that conclusion (what method did you use) ?

Regards,
Rudy Wieser


-- Origional message:
JiiPee <n...@notvalid.com> schreef in berichtnieuws
bp5Oy.708405$iw.7...@fx34.am4...

JiiPee

unread,
Apr 9, 2016, 11:47:50 AM4/9/16
to
On 09/04/2016 12:48, R.Wieser wrote:
> JiiPee,
>
>> But for example if I maximize my notepad and take its rect
>> with this, it gives: -8, -8 as a top left.
> Thats correct. The *client-area* gets enlarged to fit the full screen,
> which means that the window the client-area is in must be bigger that that
> (to accomodate the windows borders).
>
>> Also I can see that if I place the Notepad somewhere else
>> on desktop the same happens.
> I don't think the result will be -8, -8 every time. So, how have you come
> to that conclusion (what method did you use) ?
>
>

I mean it gives: windox.X - 8 (not sure if its always 8 though) as x
coordinate. I can see it becouse I take a screenshot and it always takes
more than the notepad (it takes some pixels from the background as well,
from the wall paper).

So I get a full screenshot of the notepad plus some extra from the wall
paper. How can I fix this so that I would get only the notepad? But in
this screenshot it does not seem to take extra pixels at the top side of
the notepad (or only little). So its not equal on every side, but on
left/right side its always something like 8.

JiiPee

unread,
Apr 9, 2016, 11:49:49 AM4/9/16
to
On 09/04/2016 12:48, R.Wieser wrote:
> JiiPee,
>
>> But for example if I maximize my notepad and take its rect
>> with this, it gives: -8, -8 as a top left.
> Thats correct. The *client-area* gets enlarged to fit the full screen,
> which means that the window the client-area is in must be bigger that that
> (to accomodate the windows borders).
>
>

but its not about the client area of the notepad.... it gives the full
notapad rectangle, I can see. It is the full notepad rectangle plus some
extra.

Geoff

unread,
Apr 9, 2016, 11:51:08 AM4/9/16
to
This is correct. The WindowRect is defined in terms of the desktop
coordinates and includes the thickness of the window borders.

Perhaps you were thinking in terms of the client rectangle?

R.Wieser

unread,
Apr 9, 2016, 12:07:20 PM4/9/16
to
JiiPee,

> I can see it becouse I take a screenshot ...

And there you have TWO problems: It might just be as you describe, but it
could as easily be that that screenshot software does something you do not
expect from it ...

> But in this screenshot

And thats problem #3: I have absolutily *no idea* what that "this
screenshot" is you are referring to, nor how you made it (which program ---
something you wrote yourself ?)

Hint: You could do worse than to try to describe the problem AND what you
use to evoke it to us as if we have absolutily no knowledge of what you are
busy with -- something thats actually even true (at least for me, as I'm not
a mindreader) :-)

Regards,
Rudy Wieser


-- Origional message:
JiiPee <n...@notvalid.com> schreef in berichtnieuws
Bu9Oy.571822$bx.1...@fx35.am4...

JiiPee

unread,
Apr 9, 2016, 1:05:08 PM4/9/16
to
On 09/04/2016 17:07, R.Wieser wrote:
> JiiPee,
>
>> I can see it becouse I take a screenshot ...
> And there you have TWO problems: It might just be as you describe, but it
> could as easily be that that screenshot software does something you do not
> expect from it ...

no, its my own code, only like 15 lines of code to use that rectangle
and then copy that part from the screen. I checked and they all use that
rect as it is.... so they do not increase the rect. So am sure there is
nothing wrong with that code.

Also, when I maximize notepad, i can see that its frame hits the desktop
left corner (but does not go over it). And we get that -8, so obviously
there is something happening there with GetWindowRectangle.

>
>> But in this screenshot
> And thats problem #3: I have absolutily *no idea* what that "this
> screenshot" is you are referring to, nor how you made it (which program ---
> something you wrote yourself ?)

ok, but this is not even needed... this information how I did it,
becaouse as I said if I set notepad exatcly at the top left of the
screen it gives wrong -8,-8 , the GetWinRect function. There is not need
to really investigate other things untill this problem is first
solved... you agree? Why does rect return -8,-8 even though the notapads
frame is not outside the screen?

>
> Hint: You could do worse than to try to describe the problem AND what you
> use to evoke it to us as if we have absolutily no knowledge of what you are
> busy with -- something thats actually even true (at least for me, as I'm not
> a mindreader) :-)

my opinion is that it is not needed to discuss more than why we get that
-8,-8. That error needs to be solved first... and then the others...

Its like investigating why something is flying wrongly... well, we can
investigate the flying object, but maybe its better to go to the source
first and see how it was shot... error there really tells everything and
we do not need to even investigate things after that.

>
> Regards,
> Rudy Wieser
>
>
>

JiiPee

unread,
Apr 9, 2016, 1:10:50 PM4/9/16
to
not sure if we are talking about the same thing. This is what happens:
the rectangle of notepad is (*including the frame, menu... everything*):
Rect(100,100, 300, 350)
ok... then if I take the windowrectangle with that function it gives:
Rect(92,92, 308, 353)... something like that. So this is not about
client area....
>
> Perhaps you were thinking in terms of the client rectangle?

which client you are talking about ?


Geoff

unread,
Apr 9, 2016, 2:03:52 PM4/9/16
to
I was referring to using GetClientRect rather than GetWindowRect.

R.Wieser

unread,
Apr 9, 2016, 2:52:03 PM4/9/16
to
JiiPee,

> no, its my own code, only like 15 lines of code to use
> that rectangle and then copy that part from the screen.

I'm afraid I can't help you any further. You've got problems with some code
you wrote yourself, but all we currently have to work with is a complaint
about a single function which does exactly what it should do, with an
expected -8,-8 top-left result for a full-screen app. That function does
not seem to be the problem at all.

Regards,
Rudy Wieser


-- Origional message:
JiiPee <n...@notvalid.com> schreef in berichtnieuws
2DaOy.724660$fy.7...@fx45.am4...

JiiPee

unread,
Apr 9, 2016, 6:52:09 PM4/9/16
to
On 09/04/2016 19:51, R.Wieser wrote:
> JiiPee,
>
>> no, its my own code, only like 15 lines of code to use
>> that rectangle and then copy that part from the screen.
> I'm afraid I can't help you any further. You've got problems with some code
> you wrote yourself, but all we currently have to work with is a complaint
> about a single function which does exactly what it should do, with an
> expected -8,-8 top-left result for a full-screen app. That function does
> not seem to be the problem at all.
>
>

but why is there -8? its not becouse of the frame, becouse the frame it
touching the edge of the screen

JiiPee

unread,
Apr 9, 2016, 7:07:56 PM4/9/16
to
but that does not give the notepads frame, only the text control

Geoff

unread,
Apr 9, 2016, 9:58:20 PM4/9/16
to
I cannot offer you any more advice since it's no longer clear to me
what your goal is or whether you are asking the right question.

I will offer this:
Consider using the window's device context and deal with the rectangle
in its DC rather than it's desktop position:

CWindowDC winDC(pWnd);
pWnd->GetWindowRect(rect);
int nBPP = winDC.GetDeviceCaps(BITSPIXEL) *
winDC.GetDeviceCaps(PLANES);
if (nBPP < 24)
nBPP = 24;
bStat = image.Create(rect.Width(), rect.Height(), nBPP);
ASSERT(bStat);
if (!bStat)
return;
CImageDC imageDC(image);
::BitBlt(imageDC, 0, 0, rect.Width(), rect.Height(), winDC, 0, 0,
SRCCOPY);

This code is from Microsoft AllVCSamples, the DLLScreenCap project.

JiiPee

unread,
Apr 10, 2016, 5:01:19 AM4/10/16
to
On 10/04/2016 02:58, Geoff wrote:
> On Sun, 10 Apr 2016 00:07:52 +0100, JiiPee <n...@notvalid.com> wrote:
>
>> On 09/04/2016 19:03, Geoff wrote:
>>> On Sat, 9 Apr 2016 18:10:46 +0100, JiiPee <n...@notvalid.com> wrote:
>>>
>>> which client you are talking about ?
>>>
>>> I was referring to using GetClientRect rather than GetWindowRect.
>> but that does not give the notepads frame, only the text control
> I cannot offer you any more advice since it's no longer clear to me
> what your goal is or whether you are asking the right question.
>
> I will offer this:
> Consider using the window's device context and deal with the rectangle
> in its DC rather than it's desktop position:
>
> CWindowDC winDC(pWnd);
> pWnd->GetWindowRect(rect);

But, I dont understand how would this work better than my version
becouse here you will also do exactly the same this:

pWnd->GetWindowRect(rect);


what I do, and thus this would set rect to be: -8,-8. Now, the below
code would (I think) use that -8 and capture again bigger image than
needed. Or does the code below somehow "ignore" or adjust the -8 to 0? I
cannot see it doing it:

::BitBlt(imageDC, 0, 0, rect.Width(), rect.Height(), winDC


here it starts taking the image from coordinates -8,-8 and sure that is
not the top corner of the desktop we see? Or the screen starts from -8?

JiiPee

unread,
Apr 10, 2016, 5:07:59 AM4/10/16
to
here is my code (Derived from CImage). where does it go wron?:

BOOL CScreenImage::CaptureRect(const CRect& rect)
{
// detach and destroy the old bitmap if any attached
CImage::Destroy();

// create a screen and a memory device context
HDC hDCScreen = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
HDC hDCMem = ::CreateCompatibleDC(hDCScreen);
// create a compatible bitmap and select it in the memory DC
HBITMAP hBitmap =
::CreateCompatibleBitmap(hDCScreen, rect.Width(), rect.Height());
HBITMAP hBmpOld = (HBITMAP)::SelectObject(hDCMem, hBitmap);

// bit-blit from screen to memory device context
// note: CAPTUREBLT flag is required to capture layered windows
DWORD dwRop = SRCCOPY | CAPTUREBLT;
BOOL bRet = ::BitBlt(hDCMem, 0, 0, rect.Width(), rect.Height(),
hDCScreen,
rect.left, rect.top, dwRop);
// attach bitmap handle to this object
Attach(hBitmap);

// restore the memory DC and perform cleanup
::SelectObject(hDCMem, hBmpOld);
::DeleteDC(hDCMem);
::DeleteDC(hDCScreen);

return bRet;
}

BOOL CScreenImage::CaptureWindow(HWND hWnd)
{
CImage::Destroy();

BOOL bRet = FALSE;
if(::IsWindow(hWnd))
{
CRect rect;
::GetWindowRect(hWnd, rect);
bRet = CaptureRect(rect);
}
return bRet;
}

JiiPee

unread,
Apr 10, 2016, 5:08:30 AM4/10/16
to
I posted the code below, in the other post...

Geoff

unread,
Apr 10, 2016, 9:57:54 PM4/10/16
to
Oh. I see this is not your code but comes from:
http://www.codeguru.com/cpp/article.php/c18347/C-Programming-Easy-Screen-Capture-Using-MFCATL.htm

Running the CaptureDemo application I see the behavior you are talking
about.

The demo _almost_ behaves correctly for capturing a non-maximized
window but extends the bottom right corner by 8 points but gets the
-8, -8 for the top left corner of a maximized window and 8 pixels too
large for the extent of the bottom right. It gets correct corner
coordinates for capturing the full screen image.

The question now is, did it ever work correctly?


The solution I found, although it feels like a bit of a hack, was to
use GetWindowInfo to obtain the rcClient rectangle and pass it to
CaptureRect instead of the window rectangle.

BOOL CScreenImage::CaptureWindow(HWND hWnd)
{
WINDOWINFO info;
info.cbSize = sizeof(WINDOWINFO);
BOOL bRet = FALSE;
if(::IsWindow(hWnd))
{
//CRect rect;
//::GetWindowRect(hWnd, rect);
::GetWindowInfo(hWnd, &info);
bRet = CaptureRect(info.rcClient);
}
return bRet;
}


I think this might be a legacy problem from earlier versions of
Windows that had borders. Windows 7 thru 10 windows don't have visible
borders anymore and I think when maximized the windows were clipped at
the desktop margins and the borders disappeared. Unfortunately, I
don't have any older systems running anymore on which to test.

Geoff

unread,
Apr 10, 2016, 10:00:51 PM4/10/16
to
On Sun, 10 Apr 2016 18:57:45 -0700, Geoff <ge...@invalid.invalid>
wrote:

>
>I think this might be a legacy problem from earlier versions of
>Windows that had borders. Windows 7 thru 10 windows don't have visible
>borders anymore and I think when maximized the windows were clipped at
>the desktop margins and the borders disappeared. Unfortunately, I
>don't have any older systems running anymore on which to test.

I should also add, in Windows 10 it appears to me the borders still
exist but are rendered invisible as they allow for a mouse drag target
for resizing.

JiiPee

unread,
Apr 11, 2016, 2:16:10 AM4/11/16
to
oh cool, I will try that code later

Geoff

unread,
Apr 12, 2016, 2:46:40 PM4/12/16
to
On Sun, 10 Apr 2016 18:57:45 -0700, Geoff <ge...@invalid.invalid>
wrote:

>BOOL CScreenImage::CaptureWindow(HWND hWnd)
>{
> WINDOWINFO info;
> info.cbSize = sizeof(WINDOWINFO);
> BOOL bRet = FALSE;
> if(::IsWindow(hWnd))
> {
> //CRect rect;
> //::GetWindowRect(hWnd, rect);
> ::GetWindowInfo(hWnd, &info);
> bRet = CaptureRect(info.rcClient);
> }
> return bRet;
>}

Well, I knew this was too easy a hack and I don't like the results.
This is too simplistic because you have to take into account the style
of the window frame and the state of the window when taking the
borders into account.

Geoff

unread,
Apr 13, 2016, 5:14:06 AM4/13/16
to
On Tue, 12 Apr 2016 11:46:35 -0700, Geoff <ge...@invalid.invalid>
wrote:
Here is a "working" solution that is far from perfect and can probably
fail for certain windows. It's very much a hack. I'd like to see
something that works perfectly the way alt-Print Screen works.

BOOL CScreenImage::CaptureWindow(HWND hWnd)
{
CImage image;
WINDOWINFO info;
info.cbSize = sizeof(WINDOWINFO);
BOOL bRet = FALSE;
if (::IsWindow(hWnd))
{
CRect rect;
::GetWindowRect(hWnd, rect);
::GetWindowInfo(hWnd, &info);
if (IsZoomed(hWnd))
{
OutputDebugString("Is Maximized\n");
rect.top += info.cyWindowBorders;
rect.left += info.cxWindowBorders;
rect.bottom -= info.cyWindowBorders;
rect.right -= info.cxWindowBorders;
}
else if (!(info.dwStyle & WS_THICKFRAME))
{
OutputDebugString("Is a popup window\n");
rect.top += info.cyWindowBorders / 4;
rect.left += info.cxWindowBorders / 4;
rect.bottom -= info.cyWindowBorders / 4;
rect.right -= info.cxWindowBorders / 4;
}
else if (info.dwStyle & WS_OVERLAPPEDWINDOW)
{
OutputDebugString("Is a Thickframe window\n");
rect.left += info.cxWindowBorders;
rect.bottom -= info.cyWindowBorders;
rect.right -= info.cxWindowBorders;
0 new messages