tags:

views:

40

answers:

4

Hi,

I need to somehow get width of a (fixed) window's border size (the vertical one). By default on WinXP its pretty thin but on Win7 with Aero on, its much more thick.

I thought GetSystemMetrics would do the trick but it seems it returns the same values for both XP and Win7 systems, I checked following parameters:

SM_CXBORDER
SM_CXEDGE
SM_CYFIXEDFRAME
SM_CYBORDER
SM_CXFIXEDFRAME

But as I wrote, they return the same values for both OS no matter how thick the vertical window border actually is. The window was created with flags WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX if that is of any help (it's not sizable).

Thanks for any thoughts.

Kra

A: 

Probably GetClientRect is what you need at all. Anyway, you can calculate them them from dimensions returned by GetClientRect and GetWindowRect

pseudocode:

wr = GetWindowRect()
cr = GetClientRect()

left_border_width = cr.left
right_border_width = wr.right - wr.left - cr.right
adf88
Kra
Then it must be 6. Can you give an example that this value is wrong (screenshot)? Remember that a shadow is not a part of window border.
adf88
This is how it looks like in Win7, notice that 2nd window is overlapping the border:http://img17.imageshack.us/img17/9882/win7i.pngThis is how it looks like in XP, its correctly aligned:http://img838.imageshack.us/img838/3656/85193079.pngThat value in messagebox is this:GetClientRect (hMainWnd, GetWindowRect (hMainWnd, MsgBox val = bigger.right - bigger.left - smaller.right);Note that I 2nd window left corner is aligned with fixed value, it is not computed .. yet .. after I know how to compute border, I will implement it :)
Kra
Well then it appears that outer part of border is not considered as border at all but as a graphical effect like the shadow. Probably if you maximize a window this part will go outside the screen. I think you shouldn't bother that. The best you can do is to stick to values returned by `GetWindowRect`/`GetClientect`. Also `SceenToClient` and `ClientToScreen` might be useful for you.
adf88
You can make an experiment - draw yourself (with `Rectangle` function) window borders and client area borders and you will see what is what.
adf88
Its apparently not anything I tried, it would have to differ otherwise on both OS. But its a good point I can paint border myself to be sure it will have same width everywhere .. but its just another load of work, damn :/
Kra
A: 

GetWindowRect() returns the coordinates from the DESKTOP as origin. Upper left of your screen.

GetClientRect() returns the coordinates from the WINDOW CLIENT AREA you called it against.

You have to transform the coords from one to the other.

As adf88 stated, that is done with ScreenToClient and ClientToScreen. "Screen" being the desktop.

Look up GetWindowRect(), GetClientRect(), ScreenToClient() and ClientToScreen().

HTH

JustBoo
Thanks for your comment but that still does not solve the problem. Window area width and client area width are same on two identical windows even when border thickness is different. This makes me think window area simply doesnt contain (whole) border.
Kra
Look into all the "NC" type functions then. NC mean non-client. Ex.: WM_NCHITTEST,WM_NCLBUTTONDBLCLK,WM_NCLBUTTONUP,WM_NCPAINT, etc.
JustBoo
+1  A: 

Well, after spending some time on it, here is a code that seems to return the real border width (if somebody ever needs it):

NONCLIENTMETRICS ncm;
OSVERSIONINFO OS;

OS.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);

GetVersionEx (&OS);

if (OS.dwMajorVersion < 6)
{
    ncm.cbSize = sizeof (ncm) - sizeof(ncm.iPaddedBorderWidth);
    SystemParametersInfo (SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
    BorderWidth = ncm.iBorderWidth;
}
else
{
    ncm.cbSize = sizeof (ncm);
    SystemParametersInfo (SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
    BorderWidth = ncm.iBorderWidth + ncm.iPaddedBorderWidth;
}

I guess there is still some glitch in it but its acceptable for me :)) The glitch I know about is, that it does calculate border width of a sizable window, if you have a popup window, it's border has slightly different size (but e.g. on XP it seems you cannot set popup window border size, you can do that only for sizable window).

Kra
Okay. I've been calculating borders for years using the "other" information given. But if this works, that's cool too. :-)
JustBoo
A: 

If the underlying problem is, you need to calculate the 'window' size to achieve a desirect client rect, then skip the math.

AdjustWindowRectEx is far more future proof. Even AdjustWindowRect needs to make some guesses as, without a real window it doesn't know about scroll bars or wrapping menus: Send an existing window a WM_NCCALCSIZE message and DefWindowProc will calculate and return the client area that results. Inflate the window rect by the difference between the calculated and required client area.

Chris Becke