Question

I am trying to create a simple dialog box on a win32 console window project with only ok and cancel button using mfc. I have created dialog template using resource editor and necessary classes. The following code illustrates the project

/*dialog.h - dialog class inherited from Cdialog*/
#pragma once
#include "resource.h"
#include "afxwin.h"

class dialog : public CDialog
{
DECLARE_DYNAMIC(dialog)
    public:
 dialog(CWnd* pParent = NULL);   // standard constructor
 virtual ~dialog();

    // Dialog Data
enum { IDD = IDD_DIALOG1 };
    protected:
 virtual void DoDataExchange(CDataExchange* pDX);  // DDX/DDV support
     DECLARE_MESSAGE_MAP();

    public:
 BOOL OnInitDialog();
     void OnOK();
     void OnCancel();
    void PostNcDestroy();
 };

/* dialog.cpp : implementation file */

#include "stdafx.h"
#include "dialog.h"
#include "afxdialogex.h"

IMPLEMENT_DYNAMIC(dialog, CDialog)

dialog::dialog(CWnd* pParent /*=NULL*/)
: CDialog(dialog::IDD, pParent)
{}

dialog::~dialog()
{
DestroyWindow();
}
void dialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(dialog, CDialog)
END_MESSAGE_MAP()


// dialog message handlers

BOOL dialog::OnInitDialog()
{
CDialog::OnInitDialog();
return(TRUE);
}

void dialog::OnOK()
{
if (UpdateData(true))
    DestroyWindow();
}

void dialog::OnCancel()
{
DestroyWindow();
}

void dialog::PostNcDestroy()
{
CDialog::PostNcDestroy();
delete this;
}

/*dialogbox.cpp : Defines the entry point for the console application.*/
#include "stdafx.h"
#include <iostream>
#include <afxwin.h>
#include <assert.h>
#include "dialog.h"
#include <thread>
DWORD WINAPI ModelessThreadFunc(LPVOID);
int _tmain(int argc, _TCHAR* argv[])
{
    if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), SW_SHOW))
    {
        std::cout<<"Fatal Error: MFC initialization failed\n";
    }
else
{   
    CreateThread(NULL, 0, ModelessThreadFunc, NULL, 0, NULL);
    HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, L"CloseModelessDialog");
    while(WaitForSingleObject(hEvent, 0))
    {
    }
    CloseHandle(hEvent);
}
return 0;
}

DWORD WINAPI ModelessThreadFunc(LPVOID)
{
    dialog *dial = new dialog;
    assert(dial->Create(dialog::IDD));
    dial->ShowWindow(SW_SHOWNORMAL);
    HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, L"CloseModelessDialog");
    MSG msg;
    while(WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0)
    {
      while(::GetMessage(&msg, NULL, 0,0) != 0)
     {
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
     }
    }
    CloseHandle(hEvent);
    return 0;
}

The dialog box runs fine. But after pressing ok or close, the dialog box closes and my main program is not ending. I think the event is not closing. Could anyone clarify?

Was it helpful?

Solution

If you have your own UI thread, you can set the m_pMainWnd pointer with the address of your Dialog. You don't Need the own message Loop.

  1. Just create your own class derived from CWinThread.
  2. Create your Dialog in InitInistance as you do it now. Set the pointer to the Dialog in m_pMainWnd.
  3. Exit InitInstance with TRUE. So tis causes CWinThread::Run to execute.
  4. Create your thread with AfxBeginThread.
  5. When the Dialog Closes. ExitInstance will be called and the thread wil exit.

PS: Using CreateThread with MFC and the CRT can cause Memory leaks. Always use the CRT thread routines or AfxBeginThread.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top