]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
Moved GetDefaultAttributes outside wxUSE_RICHEDIT block
[wxWidgets.git] / src / msw / window.cpp
index 97390aeb6c9a26c0d0d2a96194676520a498db03..864a390d85bc20e351397752c1431633b3201306 100644 (file)
@@ -155,11 +155,6 @@ void wxRemoveHandleAssociation(wxWindowMSW *win);
 extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
 wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 
-// this magical function is used to translate VK_APPS key presses to right
-// mouse clicks
-static void TranslateKbdEventToMouse(wxWindowMSW *win,
-                                     int *x, int *y, WPARAM *flags);
-
 // get the text metrics for the current font
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win);
 
@@ -337,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
@@ -586,7 +581,7 @@ void wxWindowMSW::SetFocusFromKbd()
 }
 
 // Get the window with the focus
-wxWindow *wxWindowBase::FindFocus()
+wxWindow *wxWindowBase::DoFindFocus()
 {
     HWND hWnd = ::GetFocus();
     if ( hWnd )
@@ -1819,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();
@@ -1976,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
@@ -2152,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,
@@ -2503,19 +2465,23 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     // this should never happen
                     wxCHECK_MSG( win, 0,
                                  _T("FindWindowForMouseEvent() returned NULL") );
+                }
+
+                processed = win->HandleMouseEvent(message, x, y, wParam);
 
+                // if the app didn't eat the event, handle it in the default
+                // way, that is by giving this window the focus
+                if ( !processed )
+                {
                     // for the standard classes their WndProc sets the focus to
                     // them anyhow and doing it from here results in some weird
-                    // problems, but for our windows we want them to acquire
-                    // focus when clicked
+                    // problems, so don't do it for them (unnecessary anyhow)
                     if ( !win->IsOfStandardClass() )
                     {
                         if ( message == WM_LBUTTONDOWN && win->AcceptsFocus() )
                             win->SetFocus();
                     }
                 }
-
-                processed = win->HandleMouseEvent(message, x, y, wParam);
             }
             break;
 
@@ -2662,13 +2628,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     // special case of VK_APPS: treat it the same as right mouse
                     // click because both usually pop up a context menu
                     case VK_APPS:
-                        {
-                            WPARAM flags;
-                            int x, y;
-
-                            TranslateKbdEventToMouse(this, &x, &y, &flags);
-                            processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, flags);
-                        }
+                        processed = HandleMouseEvent(WM_RBUTTONDOWN, -1, -1, 0);
                         break;
 #endif // VK_APPS
 
@@ -2687,11 +2647,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             // special case of VK_APPS: treat it the same as right mouse button
             if ( wParam == VK_APPS )
             {
-                WPARAM flags;
-                int x, y;
-
-                TranslateKbdEventToMouse(this, &x, &y, &flags);
-                processed = HandleMouseEvent(WM_RBUTTONUP, x, y, flags);
+                processed = HandleMouseEvent(WM_RBUTTONUP, -1, -1, 0);
             }
             else
 #endif // VK_APPS
@@ -2736,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:
@@ -2746,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__
@@ -3122,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)
     {
@@ -3677,7 +3626,8 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id),
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
 
-        wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false );
+        wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)),
+                         false, _T("MSWOnDrawItem: bad wxMenuItem pointer") );
 
         // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent
         // the DC from being released
@@ -3734,7 +3684,8 @@ wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
 
-        wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false );
+        wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)),
+                        false, _T("MSWOnMeasureItem: bad wxMenuItem pointer") );
 
         size_t w, h;
         bool rc = pMenuItem->OnMeasureItem(&w, &h);
@@ -3782,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;
 }
@@ -4059,29 +3984,6 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
     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);
@@ -4102,29 +4004,53 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 
 void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
 {
-    RECT rect;
-    ::GetClientRect(GetHwnd(), &rect);
+    switch ( GetBackgroundStyle() )
+    {
+        default:
+            wxFAIL_MSG( _T("unexpected background style") );
+            // fall through
+
+        case wxBG_STYLE_CUSTOM:
+            // don't skip the event here, custom background means that the app
+            // is drawing it itself in its OnPaint()
+            break;
 
-    wxColour backgroundColour( GetBackgroundColour());
-    COLORREF ref = PALETTERGB(backgroundColour.Red(),
-                              backgroundColour.Green(),
-                              backgroundColour.Blue());
-    HBRUSH hBrush = ::CreateSolidBrush(ref);
-    if ( !hBrush )
-        wxLogLastError(wxT("CreateSolidBrush"));
+        case wxBG_STYLE_SYSTEM:
+#if wxUSE_NOTEBOOK && wxUSE_UXTHEME && !defined(__WXUNIVERSAL__)
+            // automatically apply the tab control theme background to any
+            // child panels to have the same look as the native property sheet
+            // dialogs
+            if ( !IsOfStandardClass() )
+            {
+                for ( wxWindow *win = this; win; win = win->GetParent() )
+                {
+                    wxNotebook *nbook = wxDynamicCast(win, wxNotebook);
+                    if ( nbook )
+                    {
+                        nbook->DoEraseBackground(event);
+                        return;
+                    }
+                }
+            }
+#endif // wxUSE_NOTEBOOK
+            event.Skip();
+            break;
 
-    HDC hdc = (HDC)event.GetDC()->GetHDC();
+        case wxBG_STYLE_COLOUR:
+            // we have a fixed solid background colour, do use it
+            RECT rect;
+            ::GetClientRect(GetHwnd(), &rect);
 
-#ifndef __WXWINCE__
-    int mode = ::SetMapMode(hdc, MM_TEXT);
-#endif
+            HBRUSH hBrush = ::CreateSolidBrush(
+                                    wxColourToPalRGB(GetBackgroundColour()));
+            if ( !hBrush )
+                wxLogLastError(wxT("CreateSolidBrush"));
 
-    ::FillRect(hdc, &rect, hBrush);
-    ::DeleteObject(hBrush);
+            HDC hdc = GetHdcOf((*event.GetDC()));
 
-#ifndef __WXWINCE__
-    ::SetMapMode(hdc, mode);
-#endif
+            ::FillRect(hdc, &rect, hBrush);
+            ::DeleteObject(hBrush);
+    }
 }
 
 // ---------------------------------------------------------------------------
@@ -4149,7 +4075,8 @@ bool wxWindowMSW::HandleMaximize()
 
 bool wxWindowMSW::HandleMove(int x, int y)
 {
-    wxMoveEvent event(wxPoint(x, y), m_windowId);
+    wxPoint point(x,y);
+    wxMoveEvent event(point, m_windowId);
     event.SetEventObject(this);
 
     return GetEventHandler()->ProcessEvent(event);
@@ -4428,7 +4355,7 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //
 bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
 {
     // the mouse events take consecutive IDs from WM_MOUSEFIRST to
-    // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST
+    // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST
     // from the message id and take the value in the table to get wxWin event
     // id
     static const wxEventType eventsMouse[] =
@@ -4559,7 +4486,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;
@@ -4723,7 +4650,7 @@ int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
                         // FIXME-UNICODE: this comparison doesn't risk to work
                         // for non ASCII accelerator characters I'm afraid, but
                         // what can we do?
-                        if ( wxToupper(*p) == (wchar_t)chAccel )
+                        if ( (wchar_t)wxToupper(*p) == (wchar_t)chAccel )
                         {
                             return i;
                         }
@@ -5059,10 +4986,10 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam)
     return id;
 }
 
-int wxCharCodeWXToMSW(int id, bool *isVirtual)
+WXWORD wxCharCodeWXToMSW(int id, bool *isVirtual)
 {
     *isVirtual = true;
-    int keySym;
+    WXWORD keySym;
     switch (id)
     {
     case WXK_CANCEL:    keySym = VK_CANCEL; break;
@@ -5131,7 +5058,7 @@ int wxCharCodeWXToMSW(int id, bool *isVirtual)
     default:
         {
             *isVirtual = false;
-            keySym = id;
+            keySym = (WORD)id;
             break;
         }
     }
@@ -5141,25 +5068,32 @@ int wxCharCodeWXToMSW(int id, bool *isVirtual)
 bool wxGetKeyState(wxKeyCode key)
 {
     bool bVirtual;
-    int 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()
@@ -5716,26 +5650,6 @@ const char *wxGetMessageName(int message)
 }
 #endif //__WXDEBUG__
 
-static void TranslateKbdEventToMouse(wxWindowMSW *win,
-                                     int *x, int *y, WPARAM *flags)
-{
-    // construct the key mask
-    WPARAM& fwKeys = *flags;
-
-    fwKeys = MK_RBUTTON;
-    if ( wxIsCtrlDown() )
-        fwKeys |= MK_CONTROL;
-    if ( wxIsShiftDown() )
-        fwKeys |= MK_SHIFT;
-
-    // simulate right mouse button click
-    DWORD dwPos = ::GetMessagePos();
-    *x = GET_X_LPARAM(dwPos);
-    *y = GET_Y_LPARAM(dwPos);
-
-    win->ScreenToClient(x, y);
-}
-
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win)
 {
     // prepare the DC