How can I use a dialogbox resource in a .RC file as a MDI child windows ???
I'm coding in C, not in C++ with BCPP.
Thanks
Fred.
There are some considerations.
First: how does one create a MDI child window. Three methods are documented:
1. Call the CreateMDIChild() API.
2. Send the WM_MDICREATE message (that calls CreateMDIChild on your behalf -
Super! not).
3. Call "CreateWindowEx" and ensure that the WS_EX_MDICHILD style is
specified.
How do you create a modeless dialog:
1. CreateDialogParam()
Well, we know (I know and I'm telling you) that CreateDialogParam
essentially calls CreateWindowEx internally, so all we must do is ensure
that the dialog style has the WS_EX_MDICHILD style set. This part might
require some work on your part as its not in the resource editor as an
option. A little manual (ie text) editing of the .rc file is called for.
The second consideration is a little more tricky. The window class. Most
dialogs are created with the default dialog class (called "#32768" or
something horrible like that). Most MDI child windows are application
registered classes - the important thing being that the window proc used for
dialogs is usually "DefDlgProc". The window proc used for MDI children is...
DefMDIChildProc.
So, the next step is to ensure that we can control the windowproc of the
dialog. A normal dialog proc doesn't give us quite enough control to hand
off massages to the correct "DefXXXProc" API.
So, back to the resource editor, and specify that the dialog has a custom
class: "MYMDIDIALOG" or some such.
Back to the code. Sometime early in the applications life (ie before a
dialog can be created) we need to add a call to RegisterClassEx. The
WNDCLASSEX should look pretty normal - the class name would match that set
in the resource editor ("MYMDIDIALOG"), and the window proc should point to
a window proc I shall now discuss:
This windowproc that must be written must be a little clever - some messages
must get sent to DefDlgProc, and some to DefMDIProc. None (read carefully
now!) to DefWindowProc(). Some may need to be sent to both.
Basically all messages should be routed to DefDlgProc - it will do some
stuff itself, and pass the messages on to your dialogproc (which should
remain unchanged despite this major plumbing work taking place).
Some messages however must get sent to DefMDIChildProc, they are listed in
MSDN under "Writing the Child Window Procedure" subsection of the MDI
documentation: WM_CHILDACTIVATE, WM_GETMINMAXINFO, WM_MENUCHAR, WM_MOVE,
WM_SETFOCUS, WM_SIZE, WM_SYSCOMMAND. There - thats it.
You now have a windowproc that sends _all_ messages to "DefDlgProc" except
the above messages - that get sent to "DefMDIChildProc".
So, we now have a window class that should look enough like a dialog to be
treated as a dialog by the system, and enough as a MDIChild to fool the MDI
subsystem.
We have changed the resource script so it knows to create the dialog using
the window class the uses the wierd window proc we just made, and we have
given the dialog the necessary style WS_EX_MDICHILD.
All that remains is:
Your application message pump. Has doubtless been modified to process MDI
accellerators. More modifications are necessary. Dialogs typically have
controls that you can tab bewteen. this is not done by the dialog itslef,
but by special processing in the applications message loop: The
IsDialogMessage() function must be called for each modeless dialog you
create (passing NULL as the hDlg is NOT appropriate!). Your documentation
should be clear on how to use this function (if not why).
Quite frankly - after all that I'd be tempted to create a normal MDI child
window, and create the dialog as its child (strip off the dialogs border and
caption styles). Who'd know you'd cheated and it'd be far more likely to
work (you still need to do the IsDialogMessage() thing though - its required
for any/all modeless dialogs your app might want to show).
Chris.
--
VisualC++ & Win32 FAQ: http://www.mvps.org/vcfaq
My Win32 Page: http://www.mvps.org/user32