Modeless sibling dialog

Serializing ASCII Data
Modeless child dialog
Modeless sibling dialog
The drag source
The MFC drop target
The TBTextTarget class
VC6 flat toolbar support


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

Code Sample for this one is

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:
    class CInterfaceView : public CView
        CWinThread *m_pDlgThread
  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;
        // returning false will make MFC doing most cleanup for us :)
        return FALSE;
  5. In your appropriate message handler, do the following:
    void CInterfaceView::OnFileOthermodeless() 
        // this block determines if we have our dialog already
        // displayed and not yet closed. You can't rely on 
        // m_pDlgThread to be NULL, because if you already have displayed 
        // and closed it, the pointer is not NULL but invalid	 
        if (AfxIsValidAddress(m_pDlgThread, sizeof(CWinThread)) &&
            AfxIsValidAddress(m_pDlgThread->m_pMainWnd, sizeof(CWnd)))
            if (::IsWindow(m_pDlgThread->m_pMainWnd->GetSafeHwnd()))
                 // the sibling dialog already exists. Just need to bring it to front
    m_pDlgThread->GetMainWnd()->SetWindowPos( &wndTop, 0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW); return; } } // OK, we need to create a new thread 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() 
        m_hIcon = AfxGetApp()->LoadIcon(IDI_MYICON);
        SetIcon(m_hIcon, TRUE);
        SetIcon(m_hIcon, FALSE);
        // and all the other stuff
  7. Don't forget to do the clean-up in the destructor:
        if (AfxIsValidAddress(m_pDlgThread, sizeof(CWinThread)) &&
            AfxIsValidAddress(m_pDlgThread->m_pMainWnd, sizeof(CWnd)))
           // retrieve the threads main window
           CDialog *pDlg = (CDialog *)m_pDlgThread->m_pMainWnd;
           if (::IsWindow(pDlg->GetSafeHwnd()))
        	    // make sure we have a CDialog-derived main 
        	    // thread window then terminate it
        	    // now give the thread some time to end, 
        	    // 2 second should be enough. You may be
        	    // able to use INFINITE as wait value, if you dare...
       	    WaitForSingleObject(m_pDlgThread->m_hThread, 2000);