В предисловии у нас есть странное требование, что все диалоги должны быть немодальными для приложения MFC. Существует специальный диалог, использующий рисование региона и некоторые пользовательские элементы управления для выбора даты и времени для просмотра прошлых и будущих данных для каждого вида. Мне нужно иметь возможность закрыть это окно, когда оно теряет фокус, основное приложение получает системную команду и т. Д.
Я подумал, что самый простой способ сделать это - зарегистрировать класс следующим образом:
// for CWnd::FindWindow
WNDCLASS wndcls;
SecureZeroMemory(&wndcls, sizeof(WNDCLASS));
wndcls.lpszClassName = L"CTransactionDialog";
wndcls.style = CS_HREDRAW | CS_VREDRAW;
wndcls.lpfnWndProc = AfxWndProc;
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;
wndcls.hInstance = AfxGetInstanceHandle();
wndcls.hIcon = NULL;
#ifndef _WIN32_WCE_NO_CURSOR
wndcls.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
#else
wndcls.hCursor = 0;
#endif
wndcls.hbrBackground = (HBRUSH) (COLOR_BACKGROUND + 1);
wndcls.lpszMenuName = NULL;
BOOL retVal = AfxRegisterClass(&wndcls);
if (!retVal)
AfxMessageBox(L"AfxRegisterClass(CTransactionDialog) Failed");
Затем в ответ на различные обработчики событий и сообщения, где я хотел бы, чтобы эти немодальные окна или окна были закрыты, чтобы сделать что-то простое, как это:
CWnd* pFound = NULL;
while ((pFound = CWnd::FindWindow(L"CTransactionDialog", NULL)) != NULL)
pFound->DestroyWindow();
Однако, несмотря на успешную регистрацию класса и просмотр GetRuntimeClass
рассматриваемого диалогового окна при отладке и обнаружение, что оно совпадает с ожидаемым, FindWindow
никогда не находит или не закрывает эти немодальные диалоговые окна, как ожидалось.
Что я делаю не так или есть лучший способ сделать это?
Обновление: Так создается диалог с помощью статического метода в классе диалога. У ресурса диалога для идентификатора, указанного в create, установлено свойство Popup, которое должно соответствовать стилю WS_POPUP
под обложками MFC. Насколько мне известно, в диалоге не должно быть и не должно быть родителя.
CTransactionDialog* CTransactionDialog::ShowTransactionDialog(const CRect& crCtrlToFloatAbove, UINT dialogID, Itime defaultTime, Itime initialTime)
{
CTransactionDialog* pCTDialog = new CTransactionDialog(crCtrlToFloatAbove, dialogID, defaultTime, initialTime);
pCTDialog->Create(CTransactionDialog::IDD);
pCTDialog->ShowWindow(SW_SHOW);
return pCTDialog;
}
Обновление: Дох! FindWindowEx
тоже ничего не находит.
CWnd::FindWindowEx(AfxGetMainWnd()->GetSafeHwnd(), NULL, L"CTransactionDialog", NULL);
Однако у меня есть новый план. Я просто собираюсь сделать свое собственное оконное сообщение и обработать его в основном фрейме. Я думаю, что смогу обойтись без передачи указателя на диалоговое окно в качестве lParam сообщения, а затем приведение его к CWnd*
с последующим вызовом DestroyWindow
. В большинстве случаев это будет работать очень по-разному. У меня могут возникнуть проблемы с минимизацией и максимизацией основного окна фрейма для диалогов, в которых ничто не удерживает указатель, но мы увидим.