Dialogboxes as MDI child using pure Win32

Posted on 2003-03-24
Medium Priority
Last Modified: 2010-04-01
I am currently writing a program for college that I want to be MDI. I got the framewindow/client window set up. However, I want to use the Dialogbox editor to create the windows(Easier to make then to hardcode everything). How can I use dialogboxes as MDI childs? I am not using MFC and actually don't want to learn right now.

Question by:Toolmaker
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
  • 2
LVL 48

Expert Comment

ID: 8200785
It is not easy to write MDI application without MFC. If you want to have dialogs as MDI clients in MFC application, use CFormView class. MFC Application Wizard allows to change default class CView to any other view class. Create new application with CFormView and continue from this point.

Author Comment

ID: 8201938
Could you show me an example on how I would go and do this? I mean, explain me how I create a dialog with the App Wizard and how I do the stuff as a MFC app. I have never done MFC before.

LVL 48

Accepted Solution

AlexFM earned 255 total points
ID: 8202035
1) Open Visual Studio and select File - New. Select Projects - MFC AppWizard (exe). Fill Directory and Project Name. Press OK.

2) Select Multiple Document, press Next

3) Wizard steps 2, 3, 4, 5 - press Next (accept default choice)

4) Last Wizard step allows to change default base classes. Select view class in list box and select CFormView in Base Class combo box. Press Finish.

Now you have MDI application with CFormView child windows. Dialog template for the child view may be changed in Resource view.
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 8206141
I am sorry, but there is no straight, conventional solution for using dialog boxes as MDI childs. The MDI child window is a variety of the general purpose window, with changes issued for receiving commands from the MDI frame window, and has the classic window procedure. The dialog box has some significant peculiarities, when compared with the general-purpose application window : it has no client area, it can not be the child of another window (just owned by it, for limiting the problems created by resizing), it has a rather different function for messages processing (and even a particular message queue), etc. Dialog boxes could be owned by the MDI child windows, but I was prevented from trying it by other
Hardcoding is quite acceptable with a little bit of skill. Copy/Cut/Paste facilities can be largely and effectively employed, and small applications (fairly available) can be used as templates. Gradual development of the functions is an art, but deserves to be learned. For example, the defensive issues can be postponed for the last phases of developing a function.
MFC is not especially mandatory. It is just a popular system of encapsulating classes, but there are also some alternatives (for example one is found at www.relisoft.com).
A fine source about MDI, which was actually my passport for the MDI world, is the tutorial of Brook Miles, which uses the name "The Forger".
If really needed, I can supply a rather small hard-coded MDI application which can be used as a template.

Good luck !

Author Comment

ID: 8207160
I worked myself through the tutorial on www.winprog.org(From the Forger) today. I also discussed it with a friend programmer and he suggest to use a different approach:

Use normal CreateWindow() windows
Create border-less dialogbox
Open MDI child
Attach dialogbox to created window

I guess this would work. So, after doing the tutorial on winprog.org I am having problems with my MDI app. The frame/client windows are created like they should, however when I create a new MDI client it doesn't work.

I uploaded my entire VC 6 workspace here: <A HREF="http://home.wanadoo.nl/vdwillik/downloads/mdi.rar">http://home.wanadoo.nl/vdwillik/downloads/mdi.rar</a>

If someone would take a look I would be happy.

MirkoLMV: If you have a fairly good commented framework for a base MDI app with hardcoded windows, go ahead and sent it/link me up.


Expert Comment

ID: 8232169
Here is the promised application, which has even three different child classes.


#define IDM_MAIN 100

#define IDM_NEW1 102
#define IDM_NEW2 103
#define IDM_NEW3 104
#define IDM_ABOUT 105
#define IDM_HELP 106
#define IDM_EXIT 107
#define IDM_TILE 110
#define IDM_CASCADE 111

#define ID_MDI_FIRSTCHILD 50000

// MDI Application (a single coordinator
//   for more classes of Child Windows)
#include <windows.h>
#include "MainProg.h"

LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam);
char szAppName[] = "MDI (more assets)" ;
HINSTANCE hThisInstance ;
HWND hwndMain, hMDIClient ;
HMENU hMenuMain ;

void fnCreateMDIChildWindowClasses(void) ;
HWND fnCreateNewMDIChild(char * szMDIChildClassName) ;
char szFirstChildClassName [] = "MDI Son1" ;
char szSecondChildClassName [] = "MDI Son2" ;
char szThirdChildClassName [] = "MDI Son3" ;

int APIENTRY WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
 LPSTR lpCmdLine, int nCmdShow) {
 MSG message;/* A Win32 message structure. */
 hThisInstance = hInstance ;
 WNDCLASSEX winclass;/* A window class structure. */
 // Create a Window Class for the Main Window
 memset (&winclass, 0, sizeof(WNDCLASSEX));
 winclass.lpszClassName = szAppName ;
 winclass.cbSize = sizeof(WNDCLASSEX);
 winclass.style = CS_DBLCLKS ;
 winclass.lpfnWndProc = MainWindowProc ;
 winclass.hInstance = hThisInstance ;
 winclass.hIcon = LoadIcon(hThisInstance, "AppIcon");
 winclass.hIconSm = LoadIcon(hThisInstance, "AppIcon");
 winclass.hCursor = LoadCursor (NULL, IDC_ARROW);
 winclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
 winclass.lpszMenuName = MAKEINTRESOURCE(IDM_MAIN) ; /* No menu */
 /* Register for use the newly-created Window Class. */
 if (!RegisterClassEx (&winclass))
 { MessageBox (NULL, "Class for Main Window not registered !",
   "Failure : First MDI", MB_OK|MB_ICONEXCLAMATION) ;
   return 1 ; } ;
 fnCreateMDIChildWindowClasses() ;

 hMenuMain = LoadMenu (hThisInstance, MAKEINTRESOURCE (IDM_MAIN)) ;
 // Create our main window using that window class.
 hwndMain = CreateWindowEx (
  0, // No extra style
  szAppName, /* Class name */
  szAppName, /* Caption */
  CW_USEDEFAULT, /* Initial x (use default) */
  CW_USEDEFAULT, /* Initial y (use default) */
  CW_USEDEFAULT, /* Initial x size (use default) */
  CW_USEDEFAULT, /* Initial y size (use default) */
  NULL, /* No parent window */
  NULL, /* No menu */
  hThisInstance, /* This program instance */
  NULL /* No creation parameters */ );
 if (!hwndMain)
  { MessageBox (NULL, "Main Window was not created !",
   "Failure : First MDI", MB_OK|MB_ICONEXCLAMATION) ;
   return 1 ; } ;
 /* Display the newly-created Window */
 ShowWindow (hwndMain, nCmdShow);
 UpdateWindow (hwndMain);
 /* The main message loop. */
 while (GetMessage (&message, NULL, 0, 0))
  if (!TranslateMDISysAccel(hMDIClient, &message))
   TranslateMessage (&message);
   DispatchMessage (&message);
 return message.wParam ;
 } // End of WinMain Function
LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam) {
 switch (nMsg) {  // Message Loop
  case WM_CREATE :
   // MainWindow is a Frame Window in this case
   // MDI Client is the MDI displaying Controller
   ccs.hWindowMenu  = GetSubMenu(GetMenu(hwnd), 1) ;
   ccs.idFirstChild = ID_MDI_FIRSTCHILD ;
   hMDIClient = CreateWindowEx(WS_EX_CLIENTEDGE, "mdiclient", NULL,
     hwnd, hMenuMain, GetModuleHandle(NULL), (LPVOID)&ccs) ;
   break ;
  case WM_COMMAND :
   switch (wParam) {
    case IDM_ABOUT :
    case IDM_HELP :
     MessageBox (NULL, "Not implemented yet...", "Classic Options",
     break ;
    case IDM_EXIT :
     SendMessage (hwnd, WM_CLOSE, 0, 0) ;
     break ;
    case IDM_NEW1 :
     fnCreateNewMDIChild(szFirstChildClassName) ;
     break ;
    case IDM_NEW2 :
     fnCreateNewMDIChild(szSecondChildClassName) ;
     break ;
    case IDM_NEW3 :
     fnCreateNewMDIChild(szThirdChildClassName) ;
     break ;
    case IDM_TILE :
     SendMessage(hMDIClient, WM_MDITILE, 0, 0) ;
     break ;
    case IDM_CASCADE :
     SendMessage(hMDIClient, WM_MDICASCADE, 0, 0) ;
     break ;
     { if(LOWORD(wParam) >= ID_MDI_FIRSTCHILD)
         DefFrameProc(hwnd, hMDIClient, nMsg, wParam, lParam) ;
        else {
         HWND hChild = (HWND)SendMessage(hMDIClient, WM_MDIGETACTIVE, 0, 0) ;
         if(hChild) SendMessage(hChild, WM_COMMAND, wParam, lParam) ;
     } // EndOf IF Block for MDI Messages
    } // End of the Commands Switch
   break ;
   MessageBox (hwnd, "Main Window",
    "Right Mouse Button", MB_OK|MB_ICONEXCLAMATION) ;
   break ;
  case WM_CLOSE :
   if (MessageBox (hwnd, "Are you sure ?", "Leave",
    DestroyWindow (hwnd) ;
   break ;
  case WM_DESTROY : // Application is closed
   PostQuitMessage (0);
  default :
   return DefFrameProc(hwnd, hMDIClient, nMsg, wParam, lParam);
   // return DefWindowProc (hwnd, nMsg, wParam, lParam);
  } // End Messages Loop
 return 0 ;
} // End of Main Window Processor
// EOF


#include <windows.h>

extern HINSTANCE hThisInstance ;
extern char szFirstChildClassName [] ;
extern char szSecondChildClassName [] ;
extern char szThirdChildClassName [] ;
extern HWND hMDIClient ;
extern HMENU hMenuMain ;

void fnCreateMDIChildWindowClasses (void) {
  wc.cbSize  = sizeof(WNDCLASSEX) ;
  wc.lpszClassName = szFirstChildClassName ;
  wc.style   = CS_HREDRAW | CS_VREDRAW ;
  wc.lpfnWndProc   = MDIChildWndProc ;
  wc.cbClsExtra = 0 ;
  wc.cbWndExtra = 0 ;
  wc.hInstance  = hThisInstance;
  wc.hIcon  = LoadIcon(hThisInstance, "AppIcon") ;
  wc.hCursor = LoadCursor(NULL, IDC_ARROW) ;
  wc.hbrBackground =  CreateSolidBrush (RGB (255, 0, 0)) ;
   // (HBRUSH)(COLOR_3DFACE+1) ;
  wc.lpszMenuName  = NULL ;
  wc.hIconSm = LoadIcon(hThisInstance, "AppIcon") ;
  if (!RegisterClassEx(&wc))
   MessageBox(0, "Could Not Register First MDIChild Window Class",
    "Failure : MDI Second", MB_ICONEXCLAMATION | MB_OK) ;
  wc.lpszClassName = szSecondChildClassName ;
  wc.hIcon  = LoadIcon(hThisInstance, "DocIcon") ;
  wc.hIconSm = LoadIcon(hThisInstance, "DocIcon") ;
  wc.hbrBackground =  CreateSolidBrush (RGB (0, 255, 0)) ;
  if (!RegisterClassEx(&wc))
   MessageBox(0, "Could Not Register Second MDIChild Window Class",
    "Failure : MDI Second", MB_ICONEXCLAMATION | MB_OK) ;
  wc.lpszClassName = szThirdChildClassName ;
  wc.hIcon  = LoadIcon(hThisInstance, "BookIcon") ;
  wc.hIconSm = LoadIcon(hThisInstance, "BookIcon") ;
  wc.hbrBackground =  CreateSolidBrush (RGB (0, 0, 255)) ;
  if (!RegisterClassEx(&wc))
   MessageBox(0, "Could Not Register Third MDIChild Window Class",
    "Failure : MDI Third", MB_ICONEXCLAMATION | MB_OK) ;
  return ;
} // EndOf CreateMDIChildWindowClasses Function
{ switch(nMsg) {
    UINT uiEnableFlag ;
    if(hwnd == (HWND)lParam) uiEnableFlag = MF_ENABLED ;
     else uiEnableFlag = MF_GRAYED ;
    EnableMenuItem(hMenuMain, 1, MF_BYPOSITION | uiEnableFlag);
    EnableMenuItem(hMenuMain, 2, MF_BYPOSITION | uiEnableFlag); }
    break ;
   default: return DefMDIChildProc(hwnd, nMsg, wParam, lParam);
   } // EndOf Message Loop
 return 0 ;
} // EndOf MDIChildWndProc
HWND fnCreateNewMDIChild(char * szMDIChildClassName) {
 HWND hChild ;
  mcs.szTitle = "[Untitled]" ;
  mcs.szClass = szMDIChildClassName ;
  mcs.hOwner  = GetModuleHandle(NULL);
  mcs.x = mcs.cx = CW_USEDEFAULT ;
  mcs.y = mcs.cy = CW_USEDEFAULT ;
 hChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LONG)&mcs);
   MessageBox(NULL, "MDI Child creation failed.", "Error",
  return hChild ;
} // EndOf fnCreateNewMDIChild Function
// EOF
If the comments are not enough, I can provide further help.

Good luck !

Featured Post

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question