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
  • 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.
Independent Software Vendors: 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 On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

Question has a verified solution.

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

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

615 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