X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/34621cc5d6eaf8933935fbda55625124429a0ff9..884a37aed25b5cdabcc6f9f7604878aa97ecb031:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index 6f277cec40..d3745d4db5 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -332,8 +332,8 @@ wxCONSTRUCTOR_DUMMY(wxWindow) #endif // __WXUNIVERSAL__/__WXMSW__ BEGIN_EVENT_TABLE(wxWindowMSW, wxWindowBase) - EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground) EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged) + EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground) #ifdef __WXWINCE__ EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog) #endif @@ -1814,7 +1814,6 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) // here we try to do all the job which ::IsDialogMessage() usually does // internally -#if 1 if ( msg->message == WM_KEYDOWN ) { bool bCtrlDown = wxIsCtrlDown(); @@ -1971,35 +1970,6 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg) } } } -#else // 0 - // let ::IsDialogMessage() do almost everything and handle just the - // things it doesn't here: Ctrl-TAB for switching notebook pages - if ( msg->message == WM_KEYDOWN ) - { - // don't process system keys here - if ( !(HIWORD(msg->lParam) & KF_ALTDOWN) ) - { - if ( (msg->wParam == VK_TAB) && wxIsCtrlDown() ) - { - // find the first notebook parent and change its page - wxWindow *win = this; - wxNotebook *nbook = NULL; - while ( win && !nbook ) - { - nbook = wxDynamicCast(win, wxNotebook); - win = win->GetParent(); - } - - if ( nbook ) - { - bool forward = !wxIsShiftDown(); - - nbook->AdvanceSelection(forward); - } - } - } - } -#endif // 1/0 // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the // message even when there is no cancel button and when the message is @@ -2147,13 +2117,10 @@ void wxWindowMSW::UnpackScroll(WXWPARAM wParam, WXLPARAM lParam, } void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam, - WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd) + WXHDC *hdc, WXHWND *hwnd) { -#ifndef __WXMICROWIN__ - *nCtlColor = CTLCOLOR_BTN; *hwnd = (WXHWND)lParam; *hdc = (WXHDC)wParam; -#endif } void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam, @@ -2725,7 +2692,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l break; // CTLCOLOR messages are sent by children to query the parent for their - // colors#ifndef __WXMICROWIN__ + // colors #ifndef __WXMICROWIN__ case WM_CTLCOLORMSGBOX: case WM_CTLCOLOREDIT: @@ -2735,18 +2702,11 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l case WM_CTLCOLORSCROLLBAR: case WM_CTLCOLORSTATIC: { - WXWORD nCtlColor; WXHDC hdc; WXHWND hwnd; - UnpackCtlColor(wParam, lParam, &nCtlColor, &hdc, &hwnd); - - processed = HandleCtlColor(&rc.hBrush, - (WXHDC)hdc, - (WXHWND)hwnd, - nCtlColor, - message, - wParam, - lParam); + UnpackCtlColor(wParam, lParam, &hdc, &hwnd); + + processed = HandleCtlColor(&rc.hBrush, (WXHDC)hdc, (WXHWND)hwnd); } break; #endif // !__WXMICROWIN__ @@ -3111,7 +3071,7 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass, // do create the window wxWindowCreationHook hook(this); - // VZ: anyonce cares to explain why is this done for CE? + // VZ: anyone care to explain why this is done for CE? #ifdef __WXWINCE__ if (extendedStyle == 0) { @@ -3773,50 +3733,24 @@ bool wxWindowMSW::HandleDisplayChange() return GetEventHandler()->ProcessEvent(event); } -bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, - WXHDC pDC, - WXHWND pWnd, - WXUINT nCtlColor, - WXUINT message, - WXWPARAM wParam, - WXLPARAM lParam) -{ #ifndef __WXMICROWIN__ - WXHBRUSH hBrush = 0; -#ifdef __WXWINCE__ - if (false) -#else - if ( nCtlColor == CTLCOLOR_DLG ) -#endif - { - hBrush = OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam); - } +bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC pDC, WXHWND pWnd) +{ #if wxUSE_CONTROLS + wxWindow *item = FindItemByHWND(pWnd, true); + if ( item ) + *brush = item->MSWControlColor(pDC); else - { - wxControl *item = (wxControl *)FindItemByHWND(pWnd, true); - if ( item ) - hBrush = item->OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam); - } #endif // wxUSE_CONTROLS + *brush = NULL; - if ( hBrush ) - *brush = hBrush; - - return hBrush != 0; -#else // __WXMICROWIN__ - return false; -#endif + return *brush != NULL; } -// Define for each class of dialog and control -WXHBRUSH wxWindowMSW::OnCtlColor(WXHDC WXUNUSED(hDC), - WXHWND WXUNUSED(hWnd), - WXUINT WXUNUSED(nCtlColor), - WXUINT WXUNUSED(message), - WXWPARAM WXUNUSED(wParam), - WXLPARAM WXUNUSED(lParam)) +#endif // __WXMICROWIN__ + +WXHBRUSH wxWindowMSW::MSWControlColor(WXHDC WXUNUSED(hDC)) { return (WXHBRUSH)0; } @@ -4004,9 +3938,6 @@ extern wxCOLORMAP *wxGetStdColourMap() bool wxWindowMSW::HandlePaint() { -// if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND) -// return false; - HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle if ( !hRegion ) wxLogLastError(wxT("CreateRectRgn")); @@ -4046,33 +3977,6 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event) bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc) { - // Prevents flicker when dragging - if ( ::IsIconic(GetHwnd()) ) - return true; - -#if 0 - if (GetParent() && GetParent()->GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND) - { - return false; - } - - if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND) - { - if (wxUxThemeEngine::Get()) - { - WXHTHEME hTheme = wxUxThemeEngine::Get()->m_pfnOpenThemeData(GetHWND(), L"TAB"); - if (hTheme) - { - WXURECT rect; - ::GetClientRect((HWND) GetHWND(), (RECT*) & rect); - wxUxThemeEngine::Get()->m_pfnDrawThemeBackground(hTheme, hdc, 10 /* TABP_BODY */, 0, &rect, &rect); - wxUxThemeEngine::Get()->m_pfnCloseThemeData(hTheme); - return true; - } - } - } -#endif - wxDCTemp dc(hdc); dc.SetHDC(hdc); @@ -4093,29 +3997,77 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc) void wxWindowMSW::OnEraseBackground(wxEraseEvent& event) { - RECT rect; - ::GetClientRect(GetHwnd(), &rect); + // standard controls always erase their background themselves (although the + // user may try to override it in a derived class) + if ( IsOfStandardClass() ) + { + event.Skip(); + return; + } - wxColour backgroundColour( GetBackgroundColour()); - COLORREF ref = PALETTERGB(backgroundColour.Red(), - backgroundColour.Green(), - backgroundColour.Blue()); - HBRUSH hBrush = ::CreateSolidBrush(ref); - if ( !hBrush ) - wxLogLastError(wxT("CreateSolidBrush")); + if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM ) + { + // don't skip the event here, custom background means that the app + // is drawing it itself in its OnPaint(), so don't draw it at all + // now to avoid flicker + return; + } - HDC hdc = (HDC)event.GetDC()->GetHDC(); -#ifndef __WXWINCE__ - int mode = ::SetMapMode(hdc, MM_TEXT); -#endif + // do default background painting + wxDC& dc = *event.GetDC(); + HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC()); + if ( hBrush ) + { + RECT rc; + ::GetClientRect(GetHwnd(), &rc); + ::FillRect(GetHdcOf(dc), &rc, hBrush); + } + else + { + // let the system paint the background + event.Skip(); + } +} + +WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child) +{ + wxColour col = MSWGetBgColourForChild(child); + if ( col.Ok() ) + { + // draw children with the same colour as the parent + wxBrush *brush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID); - ::FillRect(hdc, &rect, hBrush); - ::DeleteObject(hBrush); + return (WXHBRUSH)brush->GetResourceHandle(); + } -#ifndef __WXWINCE__ - ::SetMapMode(hdc, mode); -#endif + return 0; +} + +wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow * WXUNUSED(child)) +{ + return m_hasBgCol ? GetBackgroundColour() : wxNullColour; +} + +WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC) +{ + return parent->MSWGetBgBrushForChild(hDC, (wxWindow *)this); +} + +WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC) +{ + for ( wxWindow *win = (wxWindow *)this; win; win = win->GetParent() ) + { + // background is not inherited beyond the containing TLW + if ( win->IsTopLevel() ) + break; + + WXHBRUSH hBrush = MSWGetBgBrushForSelf(win, hDC); + if ( hBrush ) + return hBrush; + } + + return 0; } // --------------------------------------------------------------------------- @@ -4551,7 +4503,7 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType, event.m_eventObject = (wxWindow *)this; // const_cast event.m_keyCode = id; #if wxUSE_UNICODE - event.m_uniChar = wParam; + event.m_uniChar = (wxChar) wParam; #endif event.m_rawCode = (wxUint32) wParam; event.m_rawFlags = (wxUint32) lParam; @@ -5019,6 +4971,8 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam) case VK_NUMLOCK: id = WXK_NUMLOCK; break; case VK_SCROLL: id = WXK_SCROLL; break; + // the mapping for these keys may be incorrect on non-US keyboards so + // maybe we shouldn't map them to ASCII values at all case VK_OEM_1: id = ';'; break; case VK_OEM_PLUS: id = '+'; break; case VK_OEM_COMMA: id = ','; break; @@ -5133,25 +5087,32 @@ WXWORD wxCharCodeWXToMSW(int id, bool *isVirtual) bool wxGetKeyState(wxKeyCode key) { bool bVirtual; - WORD vkey = wxCharCodeWXToMSW(key, &bVirtual); - SHORT state; - switch (key) +//High order with GetAsyncKeyState only available on WIN32 +#ifdef __WIN32__ + //If the requested key is a LED key, return + //true if the led is pressed + if (key == WXK_NUMLOCK || + key == WXK_CAPITAL || + key == WXK_SCROLL) { - case WXK_NUMLOCK: - case WXK_CAPITAL: - case WXK_SCROLL: - // get the toggle state of the special key - state = GetKeyState(vkey); - break; +#endif + //low order bit means LED is highlighted, + //high order means key is down + //Here, for compat with other ports we want both + return GetKeyState( wxCharCodeWXToMSW(key, &bVirtual) ) != 0; - default: - // Get the current state of the physical key - state = GetAsyncKeyState(vkey); - break; +#ifdef __WIN32__ + } + else + { + //normal key + //low order bit means key pressed since last call + //high order means key is down + //We want only the high order bit - the key may not be down if only low order + return ( GetAsyncKeyState( wxCharCodeWXToMSW(key, &bVirtual) ) & (1<<15) ) != 0; } - // if the most significant bit is set then the key is down - return ( state & 0x0001 ) != 0; +#endif } wxWindow *wxGetActiveWindow() @@ -5873,7 +5834,11 @@ public: static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam) { MSG *msg = (MSG*)lParam; - if ( msg->message == WM_NULL ) + + // only process the message if it is actually going to be removed from + // the message queue, this prevents that the same event from being + // processed multiple times if now someone just called PeekMessage() + if ( msg->message == WM_NULL && wParam == PM_REMOVE ) { wxTheApp->ProcessPendingEvents(); }