Здравствуйте, уважаемые!
Мне тут понадобилась возможность принудительно позакрывать все диалоги в моем приложении. Покопался в форумах, что-то по этому поводу было, но проблемма так и не была решена. Набросал такую функцию:
Таймер создаю и жду с помощью AtlWaitWithMessageLoop чтобы не дублировать код цикла ожидания сообщений. А сообщения надо пообрабатывать чтобы диалог реально разрушился (вычитал в MSDN'е что EndDialog() только взводит флаг, который анализируется системой при обработке первого сообщения).
Тем не менее, вызов GetLastActivePopup() внутри цикла не возвращает мне m_hWnd, как я ожидал (похоже, там так и остается HWND только что прибитого окна).
Может, кто-нибудь подскажет мне недостающее звено?
Забыл уточнить:
1. Ф-я должна вернуть TRUE, когда прибьет все окна диалога.
2. Ф-ю вызываю из окна верхнего уровня — главного окна приложения.
3. Одно окно диалога она мне прибивает, но возвращает FALSE.
4. Если окон диалога несколько (напр. одно открыло другое и т.д.), то закрывается только последнее.
Здравствуйте Мыкола, Вы писали:
М>Здравствуйте, уважаемые! М>Мне тут понадобилась возможность принудительно позакрывать все диалоги в моем приложении. Покопался в форумах, что-то по этому поводу было, но проблемма так и не была решена. Набросал такую функцию:
Делай так
#define WM_KILLDIALOG (WM_APP+1)
{
AfxGetMainWnd()->PostMessage(WM_KILLDIALOG); // сообщение должно разойтись по всем окнам
}
И в каждый диаложек добавляешь
BEGIN_MESSAGE_MAP( CDialog, CMyDialogN102 )
//{{AFX_MSG_MAP( CMyWnd
// ... Possibly more entries to handle additional messages
ON_MESSAGE(WM_KILLDIALOG,OnKillDialog)
//}}AFX_MSG_MAP
END_MESSAGE_MAP( )
afx_msg LRESULT CMyDialogN102::OnKillDialog(WPARAM, LPARAM)
{
if(m_bModal)
{
// Тут его прибиваем
}
}
Еще нужно переопределить метод DoModal — он виртуальный
int CMyDialogN102::DoModal()
{
int iRet; // это чтоб можно было диалог юзать и модально, и немодально
m_bModal = TRUE;
CDialog::DoModal();
return iRet;
}
Ну и в заголовочный файл добавить соответствующие описания методов и BOOL m_bModal;
Эхе-хе...
Муторно это — все диалоги в приложении так дополнять. А вдруг кого забуду? А если еще месседжбокс болтается?
Я так попробовал: в цикле перед EndDialog() всобачил ::SetActiveWindow(::GetParent(hWnd)); В простом тесте сработало. Но насколько это будет универсальным решением?.. Вдруг парентом будет нулл...
Суть шаманского прикола в том, чтобы сделать активным предыдущее (следующее? ) открытое окно диалога в проге, а когда таких окон больше нет — главное окно программы. Тогда GetLastActivePopup() вернет то что надо. Но как бы это сделать не ссылаясь на парента?