If you use Spy++ and find the open/save dialogs in the hierarchy, I think you'll find that they're parented by the desktop, not your own application window. However, they appear to be owned by the appropriate window of your application, so maybe searching for them that way will work.
How to find window associated with CFileDialog Open File from AfxGetMainWindow() in MFC Application
Hello everyone,
I am trying to close an MFC application from code. I have added code to save any open documents before the close function is called. I would like to close all open dialog boxes from the application before the main frame exits by sending a close message as shown below:
AfxGetMainWnd()->SendMessage(WM_CLOSE);
PostQuitMessage(0);
I am able to successfully capture dialog box instances within the application (derived from CDialog) and send an IDCancel to their dialog boxes to close them. However, I am encountering issues with capturing the dialog window for any CFileDialog window (either Open File or Save As). I'm only interested in modal dialogs and below is the code I use to capture the window instances corresponding to open dialogs.
vector<CWnd*> GetAllActiveModalDialogWindow(const CWnd* pWnd)
{
vector<CWnd*> allDialogWindows;
CWnd* pChildWnd = pWnd ? pWnd->GetNextWindow(GW_HWNDPREV) : NULL;
while (pChildWnd)
{
if (pWnd == pChildWnd->GetTopLevelParent() &&
(pChildWnd->IsKindOf(RUNTIME_CLASS(CDialog))|| pChildWnd->IsKindOf(RUNTIME_CLASS(CFileDialog)) ||
pChildWnd->IsKindOf(RUNTIME_CLASS(CPropertySheet))))
{
allDialogWindows.push_back(pChildWnd);
}
pChildWnd = pChildWnd->GetNextWindow(GW_HWNDPREV);
}
return allDialogWindows;
}
The above only seems to return windows that correspond to dialogs part of my application and none of CFileDialog. Upon using Spy++, I notice that the classname for any dialog (incl. for File Open) is "#32770".
I tried the below code to try and capture all dialogs but once again I only seem to be returned dialogs from my application.
vector<CWnd*> GetAllActiveModalDialogWindow(const CWnd* pWnd)
{
vector<CWnd*> allDialogWindows;
TCHAR szClassName[MAX_PATH];
CWnd* pWndChild = pWnd->GetWindow(GW_CHILD);
while (pWndChild)
{
::GetClassName(pWndChild->GetSafeHwnd(), szClassName, MAX_PATH);
if (_tcscmp(szClassName, "#32770") == 0)
allDialogWindows.push_back(pWndChild);
pWndChild = pWndChild->GetWindow(GW_HWNDNEXT);
}
return allDialogWindows;
}
The pWnd parameter in above function is pointer to main window in the application i.e AfxGetMainWnd()
I've been stuck on this problem for weeks now and I would really appreciate some insights and opinions.
Supporting Information: VS2019, include afxdlgs.h
Thank you all and I hope you have a wonderful day!
Best,
Aakash
Windows development | Windows API - Win32
Developer technologies | C++
1 additional answer
Sort by: Most helpful
-
Aakash 60 Reputation points
2023-11-28T18:52:49.15+00:00 Thanks to @David Lowndes comment on Spy++ and window hierarchy, I was able to find a solution. For those interested, I basically call the GetDesktopWindow() and loop over the child windows and during the process I check if the owner of this child window is any of the dialog window (or the parent window) from my application. This way I avoid capturing open dialogs that are unrelated to my application. It might not be the most efficient solution but it seems to get the job done.