Dialog which can be used as MDI child window

-->

Many people have asked for a dialog that can be used as an MDI child window. So here it is! I hope this will make some people happy :-)

Usage:

1.) Derive a dialog class from CMDIDialog

2.) Create a pointer to an object of the derived class: e.g., CMyMDIDialog* pDlg = new CMyMDIDialog(IDD_MYDIALOG);

3.) Call the DoInsert() function: pDlg->DoInsert()

It's important that a pointer to this dialog be created. Don't destroy the dialog by delete(pDlg). Instead, call the DestroyWindow() function and the object will be destroyed automatically. pDlg->DestroyWindow();

In addition, don't call EndDialog(ID). In order to dismiss the dialog use either the OnCancel or OnOK member functions.

Things that don't work yet: 1.) I couldn't find out how to disable the WS_VISIBLE style. If you set this style in the resource editor and also set the DS_CENTER style the dialog will jump on the screen from the normal position to the centered position. 2.) The CenterWindow() function doesn't center the dialog correctly. Therefore I added my own centering code. 3.) The window title don't appear in the window menu.

If someone fixes these problems or adds more functionality to this code please send me an eMail at: lhornbach@aol.com Regards Martin Horst


// ******************************************************************
// ** CMDIDialog: Dialog which can be used as MDI child 
// ** window
// 
// ** Written 1998 by Martin Horst
// ******************************************************************

//
========================================================================
// == CMDIDialog header file
==============================================
//
========================================================================

#if
!defined(AFX_MDIDIALOG_H__C18B3761_03C6_11D2_92BA_0040053CC5C2__INCLUDED_)
#define AFX_MDIDIALOG_H__C18B3761_03C6_11D2_92BA_0040053CC5C2__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// MDIDialog.h : header file
//

////////////////////////////////////////////////////////////////////////////
/
// CMDIDialog dialog

class CMDIDialog : public CDialog
{
// Construction
public:
        CMDIDialog(LPCTSTR lpszTemplateName, CWnd* pParent = NULL);
  CMDIDialog(UINT nIDTemplate, CWnd* pParent = NULL);

  void DoInsert();
  void CenterWindow(CWnd* pAlternateOwner = NULL);
  bool IsWndInserted() { return bInserted; };

// Dialog Data
        //{{AFX_DATA(CMDIDialog)
                // NOTE: the ClassWizard will add data members here
        //}}AFX_DATA


// Overrides
        // ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CMDIDialog)
        //}}AFX_VIRTUAL

// Implementation
protected:

        // Generated message map functions
        //{{AFX_MSG(CMDIDialog)
        virtual void OnCancel();
        virtual void OnOK();
        afx_msg void OnDestroy();
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()

private:
  bool bInserted;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations
immediately before the previous line.

#endif //
!defined(AFX_MDIDIALOG_H__C18B3761_03C6_11D2_92BA_0040053CC5C2__INCLUDED_)



//
========================================================================
// == MDIDialog.cpp : implementation file
=================================
//
========================================================================

// MDIDialog.cpp : implementation file
//

#include "stdafx.h"
#include "Unp70.h"
#include "MDIDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

////////////////////////////////////////////////////////////////////////////
/
// CMDIDialog dialog

CMDIDialog::CMDIDialog(LPCTSTR lpszTemplateName, CWnd* pParent /*=
NULL*)
        : CDialog(lpszTemplateName, pParent)
{
  bInserted = false;
}

CMDIDialog::CMDIDialog(UINT nIDTemplate, CWnd* pParent /*= NULL*)
        : CDialog(nIDTemplate, pParent)
{
  bInserted = false;
}



BEGIN_MESSAGE_MAP(CMDIDialog, CDialog)
        //{{AFX_MSG_MAP(CMDIDialog)
        ON_WM_DESTROY()
        //}}AFX_MSG_MAP
END_MESSAGE_MAP()

////////////////////////////////////////////////////////////////////////////
/
// CMDIDialog message handlers

void CMDIDialog::OnCancel()
{
  if ( bInserted )
     DestroyWindow();
  else
     CDialog::OnCancel();
}

void CMDIDialog::OnOK()
{
  if ( bInserted )
     DestroyWindow();
  else
     CDialog::OnOK();
}

void CMDIDialog::OnDestroy()
{
  CDialog::OnDestroy();
  if ( bInserted )
     delete(this);
}

void CMDIDialog::DoInsert()
{
CMDIFrameWnd* pWnd = (CMDIFrameWnd*) AfxGetMainWnd();
CWnd* pChildWnd    = FromHandle(pWnd -> m_hWndMDIClient);

  bInserted = true;
  Create(m_lpszTemplateName, NULL);

  SetParent(pChildWnd);

  if ( GetStyle() & DS_CENTER )
     CenterWindow();

  SetFocus();
  ShowWindow(SW_SHOW);
}

void CMDIDialog::CenterWindow(CWnd* pAlternateOwner)
{
CWnd* pWnd = AfxGetMainWnd();
CRect Rect;
int nX, nY;

  if ( bInserted || )
     if ( pAlternateOwner != NULL )
        CDialog::CenterWindow(pAlternateOwner);
     else
        {
        pWnd = AfxGetMainWnd();

        pWnd -> GetClientRect(&Rect);
        nX = Rect.Width() / 2;
        nY = Rect.Height() / 2;

        GetWindowRect(&Rect);
        nX -= Rect.Width() / 2;
        if ( nX < 0 ) nX = 0;
        nY -= Rect.Height() / 2;
        if ( nY < 0 ) nY = 0;

        SetWindowPos(NULL, nX, nY, 0, 0, SWP_NOSIZE);
        }
  else
     CDialog::CenterWindow(pAlternateOwner);
}




Comments

  • Software Developer

    Posted by linliu1 on 02/02/2014 08:57pm

    I do not know why people think it is no easy to use MDI with wpf. I used the LinsUIWPF Suite. It is so easy to create a MDI window. And even better, the user can switch from MDI to TDI during the run time. And it even support both Metro style and traditional windows style. Users can switch between these syle during run time too.

    Reply
  • ghd Styler caramelo Tutorial: Ondas Glamour Retro-Inspirados

    Posted by hanmeihm on 05/30/2013 10:02am

    [url=http://www.ghd-espana.webnode.es/]ghd españa[/url] Con varias nuevas caractersticas funcionales de las planchas de pelo GHD y planchas son simplemente magnfico para el estilo de su cabello. De las celebridades a la chica de al lado de los alisadores de pelo GHD son el gran favorito de todas las personas conscientes de la moda. [url=http://www.planchasespanaghdtop.net/ghdtienda/]GHD Plancha de pelo[/url] Traccin hecho, la validacin por slo estilistas legendarios implementadas y marketing referencia expulsados ??en: ghd nunca pareca volver de nuevo! Amplia inversin en soluciones de marketing en lnea y tambin verifican el hecho de que la posicin de ghd evolucion y se desarroll. [url=http://www.ghdplanchasde.blinkweb.com/]planchas ghd baratas[/url] Haga su mejor para el pelo secar al aire. Esta es la mejor manera de conseguir el equilibrio natural de la humedad y secar la parte posterior de. Si usted necesita utilizar un secador de pelo, use una difusin. De salida para romper el flujo de aire para que no se rompa el pelo y darles volando alrededor.

    Reply
  • How can I do this in C language?

    Posted by Legacy on 11/14/1999 12:00am

    Originally posted by: Rafa Alonso

    Someone can explain me how can I do this in c language.

    Reply
  • CWnd::GetDlgItem() returns temporary pointer

    Posted by Legacy on 02/16/1999 12:00am

    Originally posted by: Stephen K. Terry

    Your CMDIDialog has been a big help in converting my dialog based application to a MDIFrame application.
    However, I am having a couple of problems. 
    
    

    Most notably, I have some member variables that contain window handles. These handles are initialized in OnInitDialog() using GetDlgItem(IDC_xxxx). Unfortunately, the handles become invalid sometime after then I try and process a message. The code works fine when I open the dialog with .DoModal(). However, when I use DoInsert() to create an MDI child window, the window handles are invalid.

    In the MSDN documentation, Microsoft states: "The returned pointer may be temporary and should not be stored for later use.".

    This means that I will have to make some additional modifications.


    Reply
  • How to create an MDI child window in a dll?

    Posted by Legacy on 02/09/1999 12:00am

    Originally posted by: Dmitry Babitsky

    I want to be able to dynamically extend my application at run time
    by allowing MDI child windows to be loaded from a Dll.
    Pre-conditions: the main application does not know what Child windows
    are available until the run time. The functionality should be similar
    to COM Component Categories.

    To complicate the matter even further the main application may not be
    an MFC app.

    Is that possible and if so does anybody have any ideas?

    Dmitry.

    Reply
  • Hit "Enter" Key Will Colose the Frame.

    Posted by Legacy on 01/04/1999 12:00am

    Originally posted by: Wenfei Wu

    It's a very interesting idea. However, when I hit "Enter" key, the frame closed. Could you tell me how to fix it.

    TIA

    Reply
  • An easier way...

    Posted by Legacy on 11/21/1998 12:00am

    Originally posted by: Rossetti Gianluca

    There is no need to define any kind of new classes if you want to 
    
    use a dialog as a Child MDI Window, because the MDI Class CFormView
    do this for you.

    The first thing to do is create a new dialog not visible and with the
    style CHILD. Using class wizard you should create a new class derived
    from CFormView. Let me call this class CMyFormView.

    As second thing define a new Document template in this way:

    CMultiDocTemplate* pMyDocTemplate;
    pMyDocTemplate = new CMultiDocTemplate(
    IDR_MYFORMTYPE,
    RUNTIME_CLASS(CDocument),
    RUNTIME_CLASS(CMDIChildFrame),
    RUNTIME_CLASS(CMyFormView));
    AfxGetApp()->AddDocTemplate(pMyDocTemplate);
    CFrameWnd* MyFrame = CreateNewFrame( "pointer to your document or NULL",
    "pointer to yur frame or NULL").
    MyFrame->ShowWindow(SW_SHOWNORMAL);


    Some remarks:
    1) If you are working with some your Document and View classes, use them
    instead of classes CDocument, CMDIChildFrame;
    2) If you're not working with a document-View architecture, use NULL
    when you call CreateNewFrame();
    3) If you're not interested to create a new document template, don't
    call AddDocTemplate(). In this way you can call only one view and the
    dialog is fully simulated.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • A majority of organizations are operating under the assumption that their network has already been compromised, or will be, according to a survey conducted by the SANS Institute. With many high profile breaches in 2013 occurring on endpoints, interest in improving endpoint security is top-of-mind for many information security professionals. The full results of the inaugural SANS Endpoint Security Survey are summarized in this white paper to help information security professionals track trends in endpoint …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds