- ::EnableWindow((HWND) win->GetHWND(), FALSE);
- DisabledWindows.Append(win);
- }
- node = node->Next();
- }
-
- ShowWindow((HWND) GetHWND(), SW_SHOW);
- EnableWindow((HWND) GetHWND(), TRUE);
- BringWindowToTop((HWND) GetHWND());
-
- if (!wxModalDialogs.Member(this))
- wxModalDialogs.Append(this);
-
- MSG msg;
- // Must test whether this dialog still exists: we may not process
- // a message before the deletion.
- while (wxModalDialogs.Member(this) && m_modalShowing && GetMessage(&msg, NULL, 0, 0))
- {
- if (m_acceleratorTable.Ok() &&
- ::TranslateAccelerator((HWND) GetHWND(), (HACCEL) m_acceleratorTable.GetHACCEL(), &msg))
- {
- // Have processed the message
- }
- else if (!IsDialogMessage((HWND) GetHWND(), &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
+ // find the top level window which had focus before - we will restore
+ // focus to it later
+ m_hwndOldFocus = 0;
+ for ( HWND hwnd = ::GetFocus(); hwnd; hwnd = ::GetParent(hwnd) )
+ {
+ m_hwndOldFocus = (WXHWND)hwnd;
+ }
+
+ if (m_modalShowing)
+ {
+ BringWindowToTop((HWND) GetHWND());
+ return TRUE;
+ }
+
+ m_modalShowing = TRUE;
+ wxNode *node = wxModalDialogs.First();
+ while (node)
+ {
+ wxDialog *box = (wxDialog *)node->Data();
+ if (box != this)
+ ::EnableWindow((HWND) box->GetHWND(), FALSE);
+ node = node->Next();
+ }
+
+ // if we don't do it, some window might be deleted while we have pointers
+ // to them in our disabledWindows list and the program will crash when it
+ // will try to reenable them after the modal dialog end
+ wxTheApp->DeletePendingObjects();
+ wxList disabledWindows;
+
+ node = wxModelessWindows.First();
+ while (node)
+ {
+ wxWindow *win = (wxWindow *)node->Data();
+ if (::IsWindowEnabled((HWND) win->GetHWND()))
+ {
+ ::EnableWindow((HWND) win->GetHWND(), FALSE);
+ disabledWindows.Append(win);
+ }
+ node = node->Next();
+ }
+
+ ShowWindow((HWND) GetHWND(), SW_SHOW);
+ EnableWindow((HWND) GetHWND(), TRUE);
+ BringWindowToTop((HWND) GetHWND());
+
+ if ( !wxModalDialogs.Find(this) )
+ wxModalDialogs.Append(this);
+
+ MSG msg;
+ // Must test whether this dialog still exists: we may not process
+ // a message before the deletion.
+ while (wxModalDialogs.Find(this) && m_modalShowing && GetMessage(&msg, NULL, 0, 0))
+ {
+ if ( m_acceleratorTable.Ok() &&
+ ::TranslateAccelerator((HWND)GetHWND(),
+ (HACCEL)m_acceleratorTable.GetHACCEL(),
+ &msg) )
+ {
+ // Have processed the message
+ }
+ else if ( !wxTheApp->ProcessMessage((WXMSG *)&msg) )
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ // If we get crashes (as per George Tasker's message) with nested modal dialogs,
+ // we should try removing the m_modalShowing test
+
+ if (m_modalShowing && !::PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE))
+ // dfgg: NB MUST test m_modalShowing again as the message loop could have triggered
+ // a Show(FALSE) in the mean time!!!
+ // Without the test, we might delete the dialog before the end of modal showing.
+ {
+ while (wxTheApp->ProcessIdle() && m_modalShowing)
+ {
+ // Keep going until we decide we've done enough
+ }
+ }
+ }
+ // dfgg: now must specifically re-enable all other app windows that we disabled earlier
+ node=disabledWindows.First();
+ while(node) {
+ wxWindow* win = (wxWindow*) node->Data();
+ if (wxModalDialogs.Find(win) || wxModelessWindows.Find(win))
+ {
+ HWND hWnd = (HWND) win->GetHWND();
+ if (::IsWindow(hWnd))
+ ::EnableWindow(hWnd,TRUE);
+ }
+ node=node->Next();
+ }