Does anyone know the working behing the window client area?

When you use GetClientArea you get the rect that bounds the client area of the window. When you add a statusbar to the window, and also a toolbar, the client area you eally want excludes these areas. (Well I do anyways,haha). Is there a way to change whats considered the "client area" of the window? Instead of getting the client area and adjusting the rect by subtracting the controls that are "docked" to the frame.

I guess you could create a "view" and embed that in the window as a child of the frame window and then do your calcs on the window WM_SIZE handler for where that "view" should be located. Seems like an unnecessary overhead to me, even though this is what used in MFC as a standard method.

Wondering if you guys know or have a preferred way of using the window non-client area?

I know that in MFC when you add a toolbar or statusbar, the client area returned from GetClientRect is adjusted to ommit these controls. Wondering if this is something that they keep track of in global structs, or if you can actually "inform" Windows that the Client area of this window is "now this size"

Guess, its a kinda lazy question, haha. Wouldn't kill me to keep a struct with the coordinates of the "valid" client area for my app, but hey, if its something that can be done in an API call then why not use it.

thanx guys
Posted on 2002-01-03 18:29:41 by Rockinronstar
I looked a bit at this some weeks back, and ended up writing it the
hacky way (subtracting sizes of other controls etc). I got the idea
that looking into the WM_NC* messages might be interesting,
especially WM_NCCALCSIZE . But that's as far as I got.
Posted on 2002-01-03 18:46:32 by f0dder
I played around with WM_NCCALCSIZE and did get the size of the client area to change. Only problem is the toolbar was still included in the new client, and moved with it. I ended up using the "view window" method. :)
Posted on 2002-01-03 20:38:35 by S/390
Gee, I have to admit, I am amazed that this topic is sparsely known. I logged on and expected about 100 replies telling me simple ass answer that makes me look stupid as usual, hahaha

You would think it should be as simple as something like this

invoke SetNewClientRect, hWnd, addr rect

well, if it doesn't exist, then maybe I should get off my fat hiney and try and write something that manages client area dimensions
Posted on 2002-01-03 20:51:33 by Rockinronstar
one quest.

when windows repaints its , what does it use to do this?

I know it erases the background first if you don't override the WM_ERASEBKGD message, but when it uses the Background brush you setup in the WndClass to "repaint" itself what function does it use internally, ie

PatBlt, Rectangle, FillRect

I tried manually repainting my area after overriding the WM_ERASEBKGD and I find the window resize sluggish. I tried all three of these and they seemed to perform the same.

If I don't override WM_ERASEBKGD and let Windows auto repaint itself, the sluggishness is not there as expected???

stumped on this one
Posted on 2002-01-03 20:57:36 by Rockinronstar
Hmmm, what do you mean by "sluggish"? Does it flicker?




[...]
wndclass.hbrBackground = NULL;
[...]
case WM_ERASEBKGND:
{
RECT rect;
GetClientRect (hwnd, &rect);
FillRect ((HDC) wParam, &rect, GetStockObject (BLACK_BRUSH));
}
return 1;



Played around with this and it seems unnoticable to me.
Posted on 2002-01-04 00:35:08 by Boggy
I am a little worried about the state of my computer I think. I was using RADASM for just 20 minutes last night and the computer after 20 minutes was so sluggish that resizing took forever for every window. And IE took forever to open. I also had the computer get soooo slow that a nice big long beep came from the box and then WinXP restarted without warning. Booted into the BIOS and was asking me to choose Rest Defaults to finish installing the new CPU I supposedly just installed??

I think it may be time for a change!!!! :grin:

Gotta get me a new cool computer. :cool:
Posted on 2002-01-04 06:32:58 by Rockinronstar
Rockinronstar, it can be done with a single API call. Instead of using GetClientRect, use GetEffectiveClientRect (included in comctl32.lib). The only difference is a tirth parameter, a pionter to an array of int.


void GetEffectiveClientRect(
HWND hWnd,
LPRECT lprc,
LPINT lpInfo
);

This array will be filled with couples of integers. The first element of a couple is always 1, the second is the control's ID you want to exclude from client area computation. The last element of this array must be a couple made by two 0. If you have also a menu first couple will be 1, 1 (but this is not reported on MSDN help, or at least I didn't find it). To make all clearer if you have a window with a menu, a rebar and a status bar your code (hem... again it is NOT asm...) will be:


int g_ecr[] = {1, 1, 1, ID_COOLBAR, 1, ID_STATUSBAR, 0, 0};
RECT rc;

GetEffectiveClientRect(hWnd, &rc, g_ecr);
Posted on 2002-01-04 12:51:03 by LuHa
thanx LuHa....

This should be easy to manage. Just have to manage a list of control ID's. I don't think you need to manage the menu do you?

I thought the client area never includes the menus.

Will experiment
Posted on 2002-01-04 13:37:13 by Rockinronstar
I was not fully clear, I didn't mean that if you don't put {1, 1} as first couple the menu will be overwritten by client area, but that the client area will overwrite the first control in the array (rebar in my case). Sorry, you are right, I didn't explain that in my previous post :grin:. See the screenshot.
Posted on 2002-01-04 14:24:01 by LuHa
ok, thanx.
Posted on 2002-01-04 14:28:09 by Rockinronstar