I would like to show a dialog to inform the user that the application is busy. To avoid blocking of the main thread, I was thinking to use a std::thread to show the dialog. Consider the following code:
InProcDlg inProcess;
std::thread t([ &inProcess ] {
inProcess.DoModal();
delete inProcess;
});
// wait till process has finished
::PostMessage(inProcess.m_hWnd, WM_USER + 1, 0, 0);
if (t.joinable()){
t.join();
}
InProcDlg.cpp
BEGIN_MESSAGE_MAP(InProcDlg, CDialogEx)
...
ON_MESSAGE(WM_USER + 1, &InProcDlg::close)
END_MESSAGE_MAP()
LRESULT InProcDlg::close(WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(wParam, lParam);
EndDialog(1);
return 0;
}
Running this code the dialog is shown properly. The dialog is also closed, but the main dialog is not shown, the application hangs in CreateRunDlgIndirect()
. Trying to step in, while setting some breakpoints the main dialog is shown properly back again. Very strange. I would be very happy for any advices where I have to dive deeper in.
In the next step I would also like to show the process to the user, by sending an integer indicating the current state of process.
int *percent;
::PostMessage(inProcess.m_hWnd, WM_USER + 2, 0, reinterpret_cast<LPARAM>(percent));
How I can gain evidence that the dialog is already existing, before sending or posting a message? I'm using Visual Studio 2013.
I can think of two ways to do that:
Modeless dialog
https://www.codeproject.com/Articles/1651/Tutorial-Modeless-Dialogs-with-MFC
User thread (UI thread)
Creating a brother to the main UI thread (CWinApp) by using CWinThread. Most important is to assign CWinThread::m_pMainWnd member, with a pointer to a Dialog. If the dialog is Modal you return FALSE right after the call to DoModal, and return TRUE for Modeless.
start thread
headr file**
source file
to terminate the thread
For both ways I would highly recommend making the dialog as a top most window: