X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0369a9fedfe4a3c6d7d04be5a6196d83dd7c727a..17d98558b35b75e3cad68d96841b4fa5a0c7e6ee:/src/msw/window.cpp?ds=sidebyside diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 4d93f44092..117141a4ea 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -699,9 +699,21 @@ wxWindow *wxWindowBase::DoFindFocus() void wxWindowMSW::DoEnable( bool enable ) { - HWND hWnd = GetHwnd(); - if ( hWnd ) - ::EnableWindow(hWnd, (BOOL)enable); + MSWEnableHWND(GetHwnd(), enable); +} + +bool wxWindowMSW::MSWEnableHWND(WXHWND hWnd, bool enable) +{ + if ( !hWnd ) + return false; + + // If disabling focused control, we move focus to the next one, as if the + // user pressed Tab. That's because we can't keep focus on a disabled + // control, Tab-navigation would stop working then. + if ( !enable && ::GetFocus() == hWnd ) + Navigate(); + + return ::EnableWindow(hWnd, (BOOL)enable) != 0; } bool wxWindowMSW::Show(bool show) @@ -1076,10 +1088,14 @@ void wxWindowMSW::SetScrollbar(int orient, info.nMax = range - 1; // as both nMax and nMax are inclusive info.nPos = pos; - // enable the scrollbar if it had been disabled before by specifying - // SIF_DISABLENOSCROLL below: as we can't know whether this had been - // done or not just do it always - ::EnableScrollBar(hwnd, WXOrientToSB(orient), ESB_ENABLE_BOTH); + // We normally also reenable scrollbar in case it had been previously + // disabled by specifying SIF_DISABLENOSCROLL below but we should only + // do this if it has valid range, otherwise it would be enabled but not + // do anything. + if ( range >= pageSize ) + { + ::EnableScrollBar(hwnd, WXOrientToSB(orient), ESB_ENABLE_BOTH); + } } //else: leave all the fields to be 0 @@ -1819,6 +1835,18 @@ void wxWindowMSW::DoGetClientSize(int *x, int *y) const if ( m_pendingSize != wxDefaultSize ) { // we need to calculate the client size corresponding to pending size + // + // FIXME: Unfortunately this doesn't work correctly for the maximized + // top level windows, the returned values are too small (e.g. + // under Windows 7 on a 1600*1200 screen with task bar on the + // right the pending size for a maximized window is 1538*1200 + // and WM_NCCALCSIZE returns 1528*1172 even though the correct + // client size of such window is 1538*1182). No idea how to fix + // it though, setting WS_MAXIMIZE in GWL_STYLE before calling + // WM_NCCALCSIZE doesn't help and AdjustWindowRectEx() doesn't + // work in this direction neither. So we just have to live with + // the slightly wrong results and relayout the window when it + // gets finally shown in its maximized state (see #11762). RECT rect; rect.left = m_pendingPosition.x; rect.top = m_pendingPosition.y; @@ -1849,11 +1877,13 @@ void wxWindowMSW::DoGetPosition(int *x, int *y) const wxWindow * const parent = GetParent(); wxPoint pos; +#if wxUSE_DEFERRED_SIZING if ( m_pendingPosition != wxDefaultPosition ) { pos = m_pendingPosition; } else // use current position +#endif // wxUSE_DEFERRED_SIZING { RECT rect = wxGetWindowRect(GetHwnd()); @@ -2255,7 +2285,6 @@ static void wxYieldForCommandsOnly() bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y) { - menu->SetInvokingWindow(this); menu->UpdateUI(); if ( x == wxDefaultCoord && y == wxDefaultCoord ) @@ -2298,8 +2327,6 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y) // for example) and so we do need to process the event immediately wxYieldForCommandsOnly(); - menu->SetInvokingWindow(NULL); - return true; } @@ -2703,9 +2730,14 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM w // trace all messages: useful for the debugging but noticeably slows down // the code so don't do it by default #if wxDEBUG_LEVEL >= 2 + // notice that we cast wParam and lParam to long to avoid mismatch with + // format specifiers in 64 bit builds where they are both int64 quantities + // + // casting like this loses information, of course, but it shouldn't matter + // much for this diagnostic code and it keeps the code simple wxLogTrace("winmsg", wxT("Processing %s(hWnd=%p, wParam=%08lx, lParam=%08lx)"), - wxGetMessageName(message), hWnd, (long)wParam, lParam); + wxGetMessageName(message), hWnd, (long)wParam, (long)lParam); #endif // wxDEBUG_LEVEL >= 2 wxWindowMSW *wnd = wxFindWinFromHandle(hWnd); @@ -3640,33 +3672,22 @@ void wxWindowMSW::MSWDestroyWindow() { } -bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos, +void wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos, const wxSize& size, int& x, int& y, int& w, int& h) const { - // yes, those are just some arbitrary hardcoded numbers - static const int DEFAULT_Y = 200; + // CW_USEDEFAULT can't be used for child windows so just position them at + // the origin by default + x = pos.x == wxDefaultCoord ? 0 : pos.x; + y = pos.y == wxDefaultCoord ? 0 : pos.y; - bool nonDefault = false; - - if ( pos.x == wxDefaultCoord ) - { - // if x is set to CW_USEDEFAULT, y parameter is ignored anyhow so we - // can just as well set it to CW_USEDEFAULT as well - x = - y = CW_USEDEFAULT; - } - else - { - // OTOH, if x is not set to CW_USEDEFAULT, y shouldn't be set to it - // neither because it is not handled as a special value by Windows then - // and so we have to choose some default value for it - x = pos.x; - y = pos.y == wxDefaultCoord ? DEFAULT_Y : pos.y; + AdjustForParentClientOrigin(x, y); - nonDefault = true; - } + // We don't have any clearly good choice for the size by default neither + // but we must use something non-zero. + w = WidthDefault(size.x); + h = HeightDefault(size.y); /* NB: there used to be some code here which set the initial size of the @@ -3684,49 +3705,6 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos, this and ignore any attempts to change the window size to the size it already has - so no WM_SIZE would be sent. */ - - - // we don't use CW_USEDEFAULT here for several reasons: - // - // 1. it results in huge frames on modern screens (1000*800 is not - // uncommon on my 1280*1024 screen) which is way too big for a half - // empty frame of most of wxWidgets samples for example) - // - // 2. it is buggy for frames with wxFRAME_TOOL_WINDOW style for which - // the default is for whatever reason 8*8 which breaks client <-> - // window size calculations (it would be nice if it didn't, but it - // does and the simplest way to fix it seemed to change the broken - // default size anyhow) - // - // 3. there is just no advantage in doing it: with x and y it is - // possible that [future versions of] Windows position the new top - // level window in some smart way which we can't do, but we can - // guess a reasonably good size for a new window just as well - // ourselves - - // However, on PocketPC devices, we must use the default - // size if possible. -#ifdef _WIN32_WCE - if (size.x == wxDefaultCoord) - w = CW_USEDEFAULT; - else - w = size.x; - if (size.y == wxDefaultCoord) - h = CW_USEDEFAULT; - else - h = size.y; -#else - if ( size.x == wxDefaultCoord || size.y == wxDefaultCoord) - { - nonDefault = true; - } - w = WidthDefault(size.x); - h = HeightDefault(size.y); -#endif - - AdjustForParentClientOrigin(x, y); - - return nonDefault; } WXHWND wxWindowMSW::MSWGetParent() const @@ -4028,8 +4006,7 @@ bool wxWindowMSW::HandleDestroy() { m_dropTarget->Revoke(m_hWnd); - delete m_dropTarget; - m_dropTarget = NULL; + wxDELETE(m_dropTarget); } #endif // wxUSE_DRAG_AND_DROP @@ -4224,6 +4201,8 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd), y = pt.y; ScreenToClient(&x, &y); wxSetCursorEvent event(x, y); + event.SetId(GetId()); + event.SetEventObject(this); bool processedEvtSetCursor = HandleWindowEvent(event); if ( processedEvtSetCursor && event.HasCursor() ) @@ -4959,42 +4938,32 @@ bool wxWindowMSW::DoEraseBackground(WXHDC hDC) } WXHBRUSH -wxWindowMSW::MSWGetBgBrushForChild(WXHDC WXUNUSED(hDC), wxWindowMSW *child) +wxWindowMSW::MSWGetBgBrushForChild(WXHDC WXUNUSED(hDC), + wxWindowMSW * WXUNUSED(child)) { if ( m_hasBgCol ) { - // our background colour applies to: - // 1. this window itself, always - // 2. all children unless the colour is "not inheritable" - // 3. even if it is not inheritable, our immediate transparent - // children should still inherit it -- but not any transparent - // children because it would look wrong if a child of non - // transparent child would show our bg colour when the child itself - // does not - if ( child == this || - m_inheritBgCol || - (child->HasTransparentBackground() && - child->GetParent() == this) ) - { - // draw children with the same colour as the parent - wxBrush * - brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour()); + wxBrush * + brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour()); - return (WXHBRUSH)GetHbrushOf(*brush); - } + return (WXHBRUSH)GetHbrushOf(*brush); } return 0; } -WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC, wxWindowMSW *child) +WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC) { for ( wxWindowMSW *win = this; win; win = win->GetParent() ) { - WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, child); + WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, this); if ( hBrush ) return hBrush; + // don't use the parent background if we're not transparent + if ( !win->HasTransparentBackground() ) + break; + // background is not inherited beyond top level windows if ( win->IsTopLevel() ) break; @@ -5662,20 +5631,10 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType, event.SetTimestamp(::GetMessageTime()); #endif - // translate the position to client coords - POINT pt; -#ifdef __WXWINCE__ - GetCursorPosWinCE(&pt); -#else - GetCursorPos(&pt); -#endif - RECT rect; - GetWindowRect(GetHwnd(),&rect); - pt.x -= rect.left; - pt.y -= rect.top; - - event.m_x = pt.x; - event.m_y = pt.y; + // translate the position to client coordinates + const wxPoint mousePos = ScreenToClient(wxGetMousePosition()); + event.m_x = mousePos.x; + event.m_y = mousePos.y; return event; } @@ -5784,7 +5743,8 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel), // menu creation code wxMenuItem *item = (wxMenuItem*)mii.dwItemData; - const wxChar *p = wxStrchr(item->GetItemLabel().wx_str(), wxT('&')); + const wxString label(item->GetItemLabel()); + const wxChar *p = wxStrchr(label.wx_str(), wxT('&')); while ( p++ ) { if ( *p == wxT('&') )