X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7561aacd5e3bcd5f98f4cdadcec5e94d1550b369..eaac8805cd0fc233aeb0fc40a31bf8d8e03bf59c:/src/msw/window.cpp?ds=sidebyside diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 184d7da24b..fb93646628 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -84,7 +84,7 @@ #include -#ifndef __GNUWIN32_OLD__ +#if !defined(__GNUWIN32_OLD__) || defined(__CYGWIN10__) #include #include #endif @@ -93,7 +93,7 @@ #include #endif -#if !defined(__GNUWIN32_OLD__) && !defined(__TWIN32__) +#if (!defined(__GNUWIN32_OLD__) && !defined(__TWIN32__)) || defined(__CYGWIN10__) #ifdef __WIN95__ #include #endif @@ -289,11 +289,26 @@ wxWindow::~wxWindow() MSWDetachWindowMenu(); - if ( m_parent ) - m_parent->RemoveChild(this); + // VS: make sure there's no wxFrame with last focus set to us: + for (wxWindow *win = GetParent(); win; win = win->GetParent()) + { + wxFrame *frame = wxDynamicCast(win, wxFrame); + if ( frame ) + { + if ( frame->GetLastFocus() == this ) + frame->SetLastFocus((wxWindow*)NULL); + break; + } + } + // VS: destroy children first and _then_ detach *this from its parent. + // If we'd do it the other way around, children wouldn't be able + // find their parent frame (see above). DestroyChildren(); + if ( m_parent ) + m_parent->RemoveChild(this); + if ( m_hWnd ) { // VZ: test temp removed to understand what really happens here @@ -431,7 +446,11 @@ bool wxWindow::Show(bool show) // Raise the window to the top of the Z order void wxWindow::Raise() { +#ifdef __WIN16__ ::BringWindowToTop(GetHwnd()); +#else // Win32 + ::SetForegroundWindow(GetHwnd()); +#endif } // Lower the window to the bottom of the Z order @@ -1469,6 +1488,23 @@ void wxWindow::GetCaretPos(int *x, int *y) const // popup menu // --------------------------------------------------------------------------- +// yield for WM_COMMAND events only, i.e. process all WM_COMMANDs in the queue +// immediately, without waiting for the next event loop iteration +// +// NB: this function should probably be made public later as it can almost +// surely replace wxYield() elsewhere as well +static void wxYieldForCommandsOnly() +{ + // peek all WM_COMMANDs (it will always return WM_QUIT too but we don't + // want to process it here) + MSG msg; + while ( ::PeekMessage(&msg, (HWND)0, WM_COMMAND, WM_COMMAND, PM_REMOVE) + && msg.message != WM_QUIT ) + { + wxTheApp->DoMessage((WXMSG *)&msg); + } +} + bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) { menu->SetInvokingWindow(this); @@ -1482,7 +1518,16 @@ bool wxWindow::DoPopupMenu(wxMenu *menu, int x, int y) ::ClientToScreen(hWnd, &point); wxCurrentPopupMenu = menu; ::TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL); - wxYieldIfNeeded(); + + // we need to do it righ now as otherwise the events are never going to be + // sent to wxCurrentPopupMenu from HandleCommand() + // + // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't + // help and we'd still need wxYieldForCommandsOnly() as the menu may be + // destroyed as soon as we return (it can be a local variable in the caller + // for example) and so we do need to process the event immediately + wxYieldForCommandsOnly(); + wxCurrentPopupMenu = NULL; menu->SetInvokingWindow(NULL); @@ -2246,13 +2291,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam) wxPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt); - GetEventHandler()->ProcessEvent(evtCtx); - - // set processed to true even if the event is not handled - // because if we don't windows will propogate the - // WM_CONTEXTMENU up the parent window chain, which we have - // already done ourselves. - processed = true; + processed = GetEventHandler()->ProcessEvent(evtCtx); } break; #endif // __WIN32__ @@ -3426,6 +3465,9 @@ bool wxWindow::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam) return GetEventHandler()->ProcessEvent(event); #else + (void) wParam; + (void) lParam; + return FALSE; #endif }