Article View: comp.windows.ms.programmer
Article #3393Re: MDI Client Area
From: Robert Del Favero Jr.
Date: Tue, 25 Jun 1991 15:08
Date: Tue, 25 Jun 1991 15:08
143 lines
6395 bytes
6395 bytes
In article <79214@brunix.UUCP> demillo@porter.geo.brown.edu (Rob DeMillo) writes:
>OK...here's the weekly MDI question.
Yeah... :-( I've found that when I applied myself to any Win3 programming
problem, I solved it by myself in no more than a day or two, and learned
a lot more in the process of finding my problem. Not to flame Rob in
particular, but I get tired of people using the Net to replace using
their brains and the various debugging tools and books that are
available. Believe me, if I figured this out on my own, it can't be
that hard.
I can't stress strongly enough that if you want to program Windows, you
have to read and understand Petzold's book, have the SDK reference and
read it for fun, and probably have taken a look at Richter's _Windows 3:
A Developer's Guide_ at some point, especially with regard to MDI. Richter
explains the inner workings of MDI very well, and provides fixes for some
of the glitches in it.
(In light of the current anti-Visual Basic flamefest, I find it
interesting that most of the non-wizard-level questions on this group
seem to come from Turbo Pascal for Windows programmers. Perhaps matt
should be flaming Borland for making TPW available without adequate
documentation, rather than flaming VB when he's never seen it.)
Well, I feel better now. Let's answer the question.
>Now, I want to restrict the size of my MDI Client area. (In other
>words, I do *not* want it to default to the largest size it can
>be within the Frame.) After putzing around a little
>this weekend, I've come to the conclusion that, for
>MDI Client areas, the CreateWindow ignores the X, Y, WIDTH and HEIGHT
>fields. (Which is why that every example I've seen sets
>those fields to 0 all the time.) Also, the MoveWindow function
>does not seem to work on the client area.
>
>Help! The documentation about this is scanty, to say the least.
>Does anyone know how I can restrict the size of the client area?
Well, it works just fine for me, and without seeing your code I can't
be sure why it doesn't work for you, so let's cover all the details.
My program, Pickle, has an MDI client area and a Document Information
Line (DIL) at the bottom for displaying menu help and such. I display
text in the DIL by calling DrawText with vertical centering.
I'm retyping this from my PC's screen, so there may be typos. Hopefully
you'll get the gist of it.
in WinMain(), I register my windows and create my frame window:
// register frame window
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = FrameWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance, "PickleIcon");
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = COLOR_APPWORKSPACE+1;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = "PickleFrame";
RegisterClass(&wndclass);
// register DIL
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = DILWinProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = NULL;
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = "FrameDIL";
RegisterClass(&wndclass);
/* I build my frame window menu on the fly and hFrameMenu is its handle
hwndFrame = CreateWindow("PickleFrame", "Pickle",
WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, hFrameMenu, hFrameInstance, NULL);
ShowWindow(hwndFrame, nCmdShow);
UpdateWindow(hwndFrame);
/* enter message loop */
....
Then, in the frame window's window proc:
long FAR PASCAL FrameWndProc(...)
{
CLIENTCREATESTRUCT clientcreate;
....
switch(message)
{
case WM_CREATE:
DILHeight = GetSystemMetrics(SM_CYMENU) + 2;
hwndDIL = CreateWindow("FrameDIL", NULL,
WS_CHILD,
0, 0, 0, 0,
hFrameWindow,
NULL,
hFrameInstance,
NULL);
ShowWindow(hwndDIL);
SetCursor(LoadCursor(NULL, IDC_ARROW));
//"Window" menu is third in from the right.
clientcreate.hWindowMenu =
GetSubMenu(GetMenu(hwnd),
GetMenuItemCount(GetMenu(hwnd))-2);
clientcreate.idFirstChild = 1000; // arbitrary constant
hwndClient = CreateWindow("MDICLIENT", NULL,
WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL,
0, 0, 0, 0, hwnd, 1, hFrameInstance,
(LPSTR)&clientcreate);
return 0; // DON'T call DefFrameProc
case WM_COMMAND:
...
// if a command needs DefFrameProc, break.
// if a command doesnt need DefFrameProc, return
// trailing break sends all commands we don't process to
// DefFrameProc
break;
case WM_SIZE:
GetClientRect(hwnd, &rect);
if(hwndDIL)
MoveWindow(hwndDIL, rect.left, rect.bottom-DILHeight,
rect.right-rect.left, DILHeight, TRUE);
if(hwndClient)
MoveWindow(hwndClient, rect.left, rect.top,
rect.right-rect.left, rect.bottom-DILHeight,
TRUE);
return 0; // DONT call DefFrameProc
}
DefFrameProc(...);
}
I suspect that the problem everyone has is that they don't handle the
calls to DefFrameProc properly, calling it when they shouldn't or not
calling it when they should. If you watch the right windows with your
debugger or Spy, you'll see that you do resize the client properly, but
the DefFrameProc resizes it to fill the frame, so you never see your
change. Single stepping and using Spy are incredibly useful when you're
trying to understand what Windows does with your code.
-------------------------------------------------------------------------------
Robert V. Del Favero, Jr. ISC-Bunker Ramo, an Olivetti Company
rvd@clunker.shel.isc-br.com Shelton, Connecticut, USA
Technical Details
Message-ID:
<19292@bunker.isc-br.com>Path:
arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!think.com!yale.edu!yale!bunker!rvdReferences:
<79214@brunix.UUCP>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!think.com!yale.edu!yale!bunker!rvd From: rvd@bunker.isc-br.com (Robert Del Favero Jr.) Newsgroups: comp.windows.ms.programmer Subject: Re: MDI Client Area Summary: a mild toasting, followed by a solution Message-ID: <19292@bunker.isc-br.com> Date: 25 Jun 91 15:08:45 GMT References: <79214@brunix.UUCP> Reply-To: rvd@clunker.UUCP (Robert Del Favero) Organization: ISC-Bunker Ramo, an Olivetti Company, Shelton, Ct Lines: 143