I have a window I am opening from the parent Dialog by using DoModal:
CMyDlg dml;
dml.DoModal;
When the window opens I want it to run a function on open. Lets just for example say copy files and show a progress bar. Where can I put the function call so that when DoModal is called that function will execute?
I'm surprised WM_SHOW didn't work. You could try WM_ACTIVATE also. Another trick people use sometimes is to set a short timer in OnInitDialog, then start the function when the timer goes off.
OnInitDialog is called before the dialog is shown.
One simple and reliable solution to perform a lengthy task while the dialog is visible in order to show a progress bar, is to post an application-defined message from OnInitDialog.
Like in the following example:
Code:
#define WM_APP_POSTINITDIALOG (WM_APP+1)
class CMyDialog : public CDialog
{
//...
afx_msg LRESULT OnAppPostInitDialog(WPARAM wParam, LPARAM lParam);
};
Code:
// ...
//}}AFX_MSG_MAP
ON_MESSAGE(WM_APP_POSTINITDIALOG, OnAppPostInitDialog)
END_MESSAGE_MAP()
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
// ...
// ...
// Here the dialog is NOT yet visible.
PostMessage(WM_APP_POSTINITDIALOG);
return TRUE;
}
LRESULT CMyDialog::OnAppPostInitDialog(WPARAM wParam, LPARAM lParam)
{
// Here the dialog IS visible.
// do some lengthy task, show progress, etc...
return 0;
}
Last edited by ovidiucucu; September 20th, 2012 at 10:31 AM.
I'd recommend using a worker thread for your lengthy task. If you don't, you might find that other aspects of the dialog stop working or become very clunky. For example, the dialog itself might display okay but once the lengthy task is running, the dialog becomes unresponsive if you try to move it or resize it
"A problem well stated is a problem half solved.” - Charles F. Kettering
I'd recommend using a worker thread for your lengthy task [...]
Yes John, that's OK but not always. It's possible to be required to complete the task before user does some other action (and only show the progress). This case a worker thread isn't necessary.
OnInitDialog is called before the dialog is shown.
One simple and reliable solution to perform a lengthy task while the dialog is visible in order to show a progress bar, is to post an application-defined message from OnInitDialog.
Like in the following example:
Code:
#define WM_APP_POSTINITDIALOG (WM_APP+1)
class CMyDialog : public CDialog
{
//...
afx_msg LRESULT OnAppPostInitDialog(WPARAM wParam, LPARAM lParam);
};
Code:
// ...
//}}AFX_MSG_MAP
ON_MESSAGE(WM_APP_POSTINITDIALOG, OnAppPostInitDialog)
END_MESSAGE_MAP()
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
// ...
// ...
// Here the dialog is NOT yet visible.
PostMessage(WM_APP_POSTINITDIALOG);
return TRUE;
}
LRESULT CMyDialog::OnAppPostInitDialog(WPARAM wParam, LPARAM lParam)
{
// Here the dialog IS visible.
// do some lengthy task, show progress, etc...
return 0;
}
I gave this a shot and the window did not come up until the code in OnAppPostInitDialog had executed. Not really wanting to thread this.
I gave this a shot and the window did not come up until the code in OnAppPostInitDialog had executed.
This is the kind of problem that might even behave differently with different versions of Windows.
It's probably not ideal - but why not give the dialog an 'OK' button and a 'Cancel' button so that the user needs to issue a confirmation before the task gets carried out (or alternatively, cancel). You could rename them "Confirm" and "Abort" or something like that. I still think a worker thread is your best option though. I sometimes have dialog boxes where all the controls are initially grayed out until some background task has completed but I still use a worker thread so that the user can at least move, minimize or resize the dialog.
"A problem well stated is a problem half solved.” - Charles F. Kettering
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.