Click here to Skip to main content
Licence 
First Posted 9 Nov 2000
Views 107,597
Bookmarked 31 times

Create a modeless dialog box as sibling of the app's main window

By | 9 Nov 2000 | Article
Simple step by step article explaining how to create a modeless dialog box as sibling of the app's main window.

This article is part of the drag and drop interface samples.

  1. Serializing ASCII Data
  2. Modeless child dialog
  3. Modeless sibling dialog
  4. The drag source
  5. The MFC drop target
  6. The TBTextTarget class

  • Download source files - 20 Kb

    It's nearly as short as the child version of modeless dialogs

    Follow these steps:

    1. Create a new dialog resource and use the Class Wizard for making a new CDialog based class COtherDropDialog
    2. In the class maintaining the modeless dialog (here it's CInterfaceView) add a member variable of type pointer to CWinThread and make sure you have a destructor:
      <font color="#000080">class</font> CInterfaceView : public CView
      {
      ...
          CWinThread *m_pDlgThread
          ~CInterfaceView();
      ...
      }
    3. Use ClassWizard to create a new CWinThread-based class COtherDropDialogThread
    4. Override COtherRopDialogThread::InitInstance():
      If you forget to change the m_pMainWnd variable, the dialog will stay modal!
      BOOL COtherDropDialogThread::InitInstance()
      {
          COtherDropDialog dlg;
      
          m_pMainWnd = &dlg;
          dlg.DoModal();  <font color="#008000">// returning false will make MFC doing the cleanup for us :)</font>
                
          return FALSE;
      }
    5. In your appropriate message handler, do the following:
      <FONT COLOR=#008080>void</FONT> CInterfaceView::OnFileOthermodeless() 
      {
          <FONT COLOR=#008000>// this block determines if we have our dialog already</FONT>
          <FONT COLOR=#008000>// displayed and not yet closed. You can't rely on </FONT>
          <FONT COLOR=#008000>// m_pDlgThread to be NULL, because if you already have displayed </FONT>
          <FONT COLOR=#008000>// and closed it, the pointer is not NULL but invalid	 </FONT>
          <FONT COLOR=#804040>if</FONT> (AfxIsValidAddress(m_pDlgThread, <FONT COLOR=#804040>sizeof</FONT>(CWinThread)) &&
              AfxIsValidAddress(m_pDlgThread->m_pMainWnd, <FONT COLOR=#804040>sizeof</FONT>(CWnd)))
          {
              <FONT COLOR=#804040>if</FONT> (::IsWindow(m_pDlgThread->m_pMainWnd->GetSafeHwnd()))
              {    m_pDlgThread->GetMainWnd()->SetWindowPos(
      	                &wndTop, <FONT COLOR=#aa6400>0</FONT>,<FONT COLOR=#aa6400>0</FONT>,<FONT COLOR=#aa6400>0</FONT>,<FONT COLOR=#aa6400>0</FONT>,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
                   <FONT COLOR=#804040>return</FONT>;
              }
          }
          <FONT COLOR=#008000>// OK, we need to create a new thread</FONT>
          m_pDlgThread=AfxBeginThread( RUNTIME_CLASS(COtherDropDialogThread) );	
      }
      
      
    6. If you like your top-level window to have an icon displayed in the taskbar, add the following to COtherDropDialog:: OnInitDialog (ommited in the sample):
      BOOL COtherDropDialog::OnInitDialog() 
      {
          CDialog::OnInitDialog();
          m_hIcon = AfxGetApp()->LoadIcon(IDI_MYICON);
          SetIcon(m_hIcon, TRUE);
          SetIcon(m_hIcon, FALSE);
      <font color="#008000">    // and all the other stuff
          //...
      </font>}
    7. Don't forget to do the clean-up in the destructor:
      CInterfaceView::~CInterfaceView()
      {
          <font color="#000080">if</font> (AfxIsValidAddress(m_pDlgThread, <font color="#000080">sizeof</font>(CWinThread)) &&
      	AfxIsValidAddress(m_pDlgThread->m_pMainWnd, <font color="#000080">sizeof</font>(CWnd)))
          {
      	// retrieve the threads main window
      	CDialog *pDlg = (CDialog *)m_pDlgThread->m_pMainWnd;
      
      	<font color="#000080">if</font> (::IsWindow(pDlg->GetSafeHwnd()))
      	{
      <font color="#008000">	    // make sure we have a CDialog-derived main 
      	    // thread window then terminate it
      </font>	    ASSERT(pDlg->IsKindOf(RUNTIME_CLASS(CDialog)));
      	    pDlg->EndDialog(IDCANCEL);
      
      <font color="#008000">	    // now give the thread some time to end, 
      	    // 2 second should be enough. You may 
      	    // able to use INFINITE as wait value, if you dare...
      </font>	    WaitForSingleObject(m_pDlgThread->m_hThread, 2000);
      	    m_pDlgThread=NULL;
      	}
          }
      }
  • License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here

    About the Author

    Thomas Blenkers

    Web Developer

    Germany Germany

    Member

    PhD Chemist,
    programming with MSVC & MFC since 1996

    Sign Up to vote   Poor Excellent
    Add a reason or comment to your vote: x
    Votes of 3 or less require a comment

    Comments and Discussions

     
    You must Sign In to use this message board. (secure sign-in)
     
    Search this forum  
     FAQ
        Noise  Layout  Per page   
      Refresh
    GeneralSystem crashes Pinmemberken1239:00 25 Apr '05  
    The program crashes at
    pDlg->EndDialog(IDCANCEL);
    When the above statement is encountered, the dialog's m_hWnd is ??? Can you tell me the reason why dialog's m_hWnd is unknown?
    Thanks.
    Generalprobelm with CPU usage PinsussAnonymous20:50 14 Apr '03  

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

    Permalink | Advertise | Privacy | Mobile
    Web04 | 2.5.120528.1 | Last Updated 10 Nov 2000
    Article Copyright 2000 by Thomas Blenkers
    Everything else Copyright © CodeProject, 1999-2012
    Terms of Use
    Layout: fixed | fluid