[comp.windows.ms.programmer] MDI Client Area

demillo@porter.geo.brown.edu (Rob DeMillo) (06/25/91)

OK...here's the weekly MDI question.

I have an MDI Frame, and I have just setup an MDI Client area
within that frame. This works great...all the MDI children I
create fall within the frame, etc etc etc.

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?

Thanks

Oh, by the way, how long should I be waiting for the Pertzold
book from Borland's offer? They cashed my check weeks ago, but
I still haven't seen the book yet.

Thanks again...

-- Rob


 - Rob DeMillo			     | Internet: demillo@juliet.ll.mit.edu
   Mass Inst of Tech/Lincoln Lab     | Also:     demillo@porter.geo.brown.edu
   Weather Sensing Project-Group 43  | Reality:  401-273-0804 (home)
"I say you *are* the Messiah, Lord! And I ought to know, I've followed a few!"

rvd@bunker.isc-br.com (Robert Del Favero Jr.) (06/25/91)

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

demillo@porter.geo.brown.edu (Rob DeMillo) (06/26/91)

In article <19292@bunker.isc-br.com> rvd@clunker.UUCP (Robert Del Favero) writes:
>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.

Well, I took it as a flame, anyway.

Look at it this way...I do a *lot* of programming...I put in about
60-75 hours/week working on various systems ranging from Win3 to
X Windows (I even have the Perzold book, pretty amazing
that I couldn't find the answer in there, huh?)
...concepts are all identical, but they are implemented
differently. I spend a *lot* of time tracking down the answers
to questions myself...and, in fact, I rarely post to here. 
On the other hand, isn't that what the ...programmer suffix means?
Programming related newsgroups?

I do not consider my question superficial in any way, Robert...in fact,
since the answer involves using the Client window differently than
you do other window objects (i.e. DefFrameProc() behaves differently
than one might expect) - you yourself suggested that you foiund the
problem by "stepping around with Spy" - I think this was a legitimate
"has anyone else out there figured this out" question.

Now, you gave me the answer I was looking for, so I am not going
to sit here and start name calling because of a bruised ego, but...

There is a huge programming community out here, Robert. If you want
to sit around and be an ass to people who have legitimate questions,
go ahead...to yourself! Don't pompously post a response like
this, complete with "gee whiz look at all of this code *I*
wrote on my *own*" examples and expect to cover it up 
with "not to flame Rob in particular."

You *can* take that as a flame.

...and, by the way, thanks for the response.



 - Rob DeMillo			     | Internet: demillo@juliet.ll.mit.edu
   Mass Inst of Tech/Lincoln Lab     | Also:     demillo@porter.geo.brown.edu
   Weather Sensing Project-Group 43  | Reality:  401-273-0804 (home)
"I say you *are* the Messiah, Lord! And I ought to know, I've followed a few!"

al@well.sf.ca.us (Alfred Fontes) (06/27/91)

I get the feeling that a lot of people want to have those slick status
bars on the bottoms of their MDI applications.

A book by Jeffrey M. Richter, called "Windows 3: A Developer's Guide",
has a chapter that explains how to do this.  You can get the source
code through the mail, or buy a copy of the book with disks in it.
The book also tells you how to make one of those "ribbon" things at 
the top of the screen.

I can't offer any opinion about this book, because I've only read about
25% of it.  I haven't read the MDI chapter, but the sample application
that goes with it runs well on my machine.

Al Fontes, Jr.
al@well.sf.ca.us