]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
1. corrected HAVE_PW_GECOS detection in configure (which never worked)
[wxWidgets.git] / src / msw / window.cpp
index bba5e5670564ec0febe9334ba10b5a7a338f5271..a011dca8aba618a9aed2cc679ce91bac0e9bc2e1 100644 (file)
@@ -129,10 +129,6 @@ wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 // mouse clicks
 static void TranslateKbdEventToMouse(wxWindow *win, int *x, int *y, WPARAM *flags);
 
-// get the current state of SHIFT/CTRL keys
-static inline bool IsShiftDown() { return GetKeyState(VK_SHIFT)& 0x100 != 0; }
-static inline bool IsCtrlDown() { return GetKeyState(VK_CONTROL)& 0x100 != 0; }
-
 // ---------------------------------------------------------------------------
 // event tables
 // ---------------------------------------------------------------------------
@@ -274,7 +270,8 @@ wxWindow::~wxWindow()
 
     if ( m_hWnd )
     {
-        if (::IsWindow(GetHwnd()))
+        // VZ: test temp removed to understand what really happens here
+        //if (::IsWindow(GetHwnd()))
         {
             if ( !::DestroyWindow(GetHwnd()) )
                 wxLogLastError("DestroyWindow");
@@ -305,6 +302,7 @@ bool wxWindow::Create(wxWindow *parent, wxWindowID id,
     if ( style & wxTHICK_FRAME )
         msflags |= WS_THICKFRAME;
 
+    //msflags |= WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE;
     msflags |= WS_CHILD | WS_VISIBLE;
     if ( style & wxCLIP_CHILDREN )
         msflags |= WS_CLIPCHILDREN;
@@ -368,6 +366,10 @@ bool wxWindow::Enable(bool enable)
     if ( hWnd )
         ::EnableWindow(hWnd, (BOOL)enable);
 
+    // VZ: no, this is a bad idea: imagine that you have a dialog with some
+    //     disabled controls and disable it - you really wouldn't like the
+    //     disabled controls eb reenabled too when you reenable the dialog!
+#if 0
     wxWindowList::Node *node = GetChildren().GetFirst();
     while ( node )
     {
@@ -376,6 +378,7 @@ bool wxWindow::Enable(bool enable)
 
         node = node->GetNext();
     }
+#endif // 0
 
     return TRUE;
 }
@@ -467,20 +470,20 @@ bool wxWindow::SetCursor(const wxCursor& cursor)
         return FALSE;
     }
 
-    wxASSERT_MSG( m_cursor.Ok(),
-                  wxT("cursor must be valid after call to the base version"));
-
-    HWND hWnd = GetHwnd();
+    if ( m_cursor.Ok() )
+    {
+        HWND hWnd = GetHwnd();
 
-    // Change the cursor NOW if we're within the correct window
-    POINT point;
-    ::GetCursorPos(&point);
+        // Change the cursor NOW if we're within the correct window
+        POINT point;
+        ::GetCursorPos(&point);
 
-    RECT rect;
-    ::GetWindowRect(hWnd, &rect);
+        RECT rect;
+        ::GetWindowRect(hWnd, &rect);
 
-    if ( ::PtInRect(&rect, point) && !wxIsBusy() )
-        ::SetCursor((HCURSOR)m_cursor.GetHCURSOR());
+        if ( ::PtInRect(&rect, point) && !wxIsBusy() )
+            ::SetCursor(GetHcursorOf(m_cursor));
+    }
 
     return TRUE;
 }
@@ -973,9 +976,9 @@ void wxWindow::OnIdle(wxIdleEvent& event)
             // by the time the OnIdle function is called, so 'state' may be
             // meaningless.
             int state = 0;
-            if ( ::GetKeyState(VK_SHIFT) != 0 )
+            if ( wxIsShiftDown() )
                 state |= MK_SHIFT;
-            if ( ::GetKeyState(VK_CONTROL) != 0 )
+            if ( wxIsCtrlDown() )
                 state |= MK_CONTROL;
 
             wxMouseEvent event(wxEVT_LEAVE_WINDOW);
@@ -1482,8 +1485,8 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
 
         if ( bProcess )
         {
-            bool bCtrlDown = IsCtrlDown();
-            bool bShiftDown = IsShiftDown();
+            bool bCtrlDown = wxIsCtrlDown();
+            bool bShiftDown = wxIsShiftDown();
 
             // WM_GETDLGCODE: ask the control if it wants the key for itself,
             // don't process it if it's the case (except for Ctrl-Tab/Enter
@@ -1598,7 +1601,7 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
             // don't process system keys here
             if ( !(HIWORD(msg->lParam) & KF_ALTDOWN) )
             {
-                if ( (msg->wParam == VK_TAB) && IsCtrlDown() )
+                if ( (msg->wParam == VK_TAB) && wxIsCtrlDown() )
                 {
                     // find the first notebook parent and change its page
                     wxWindow *win = this;
@@ -1611,7 +1614,7 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
 
                     if ( nbook )
                     {
-                        bool forward = !IsShiftDown();
+                        bool forward = !wxIsShiftDown();
 
                         nbook->AdvanceSelection(forward);
                     }
@@ -2352,7 +2355,11 @@ bool wxWindow::MSWCreate(int id,
     {
         int controlId = 0;
         if ( style & WS_CHILD )
+          {
             controlId = id;
+            // all child windows should clip their siblings
+            // style |= WS_CLIPSIBLINGS;
+          }
 
         wxString className(wclass);
         if ( GetWindowStyleFlag() & wxNO_FULL_REPAINT_ON_RESIZE )
@@ -2664,54 +2671,87 @@ bool wxWindow::HandleSetCursor(WXHWND hWnd,
                                short nHitTest,
                                int WXUNUSED(mouseMsg))
 {
-    // don't set cursor for other windows, only for this one: this prevents
-    // children of this window from getting the same cursor as the parent has
-    // (don't forget that this message is propagated by default up the window
-    // parent-child hierarchy)
-    if ( GetHWND() == hWnd )
+    // the logic is as follows:
+    // -1. don't set cursor for non client area, including but not limited to
+    //     the title bar, scrollbars, &c
+    //  0. allow the user to override default behaviour by using EVT_SET_CURSOR
+    //  1. if we have the cursor set it unless wxIsBusy()
+    //  2. if we're a top level window, set some cursor anyhow
+    //  3. if wxIsBusy(), set the busy cursor, otherwise the global one
+
+    if ( nHitTest != HTCLIENT )
     {
-        // don't set cursor when the mouse is not in the client part
-        if ( nHitTest == HTCLIENT || nHitTest == HTERROR )
-        {
-            HCURSOR hcursor = 0;
-            if ( wxIsBusy() )
-            {
-                // from msw\utils.cpp
-                extern HCURSOR gs_wxBusyCursor;
+        return FALSE;
+    }
 
-                hcursor = gs_wxBusyCursor;
-            }
-            else
-            {
-                wxCursor *cursor = NULL;
+    HCURSOR hcursor = 0;
 
-                if ( m_cursor.Ok() )
-                {
-                    cursor = &m_cursor;
-                }
-                else
-                {
-                    // from msw\data.cpp
-                    extern wxCursor *g_globalCursor;
+    // first ask the user code - it may wish to set the cursor in some very
+    // specific way (for example, depending on the current position)
+    POINT pt;
+#ifdef __WIN32__
+    if ( !::GetCursorPos(&pt) )
+    {
+        wxLogLastError("GetCursorPos");
+    }
+#else
+    // In WIN16 it doesn't return a value.
+    ::GetCursorPos(&pt);
+#endif
 
-                    if ( g_globalCursor && g_globalCursor->Ok() )
-                        cursor = g_globalCursor;
-                }
+    int x = pt.x,
+        y = pt.y;
+    ScreenToClient(&x, &y);
+    wxSetCursorEvent event(x, y);
 
-                if ( cursor )
-                    hcursor = (HCURSOR)cursor->GetHCURSOR();
-            }
+    bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
+    if ( processedEvtSetCursor && event.HasCursor() )
+    {
+        hcursor = GetHcursorOf(event.GetCursor());
+    }
 
-            if ( hcursor )
-            {
-                ::SetCursor(hcursor);
+    if ( !hcursor )
+    {
+        bool isBusy = wxIsBusy();
 
-                return TRUE;
+        // the test for processedEvtSetCursor is here to prevent using m_cursor
+        // if the user code caught EVT_SET_CURSOR() and returned nothing from
+        // it - this is a way to say that our cursor shouldn't be used for this
+        // point
+        if ( !processedEvtSetCursor && m_cursor.Ok() )
+        {
+            hcursor = GetHcursorOf(m_cursor);
+        }
+
+        if ( !GetParent() )
+        {
+            if ( isBusy )
+            {
+                hcursor = wxGetCurrentBusyCursor();
+            }
+            else if ( !hcursor )
+            {
+                const wxCursor *cursor = wxGetGlobalCursor();
+                if ( cursor && cursor->Ok() )
+                {
+                    hcursor = GetHcursorOf(*cursor);
+                }
             }
         }
     }
 
-    return FALSE;
+    if ( hcursor )
+    {
+        ::SetCursor(hcursor);
+
+        // cursor set, stop here
+        return TRUE;
+    }
+    else
+    {
+        // pass up the window chain
+        return FALSE;
+    }
 }
 
 // ---------------------------------------------------------------------------
@@ -3020,13 +3060,14 @@ bool wxWindow::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
         return popupMenu->MSWCommand(cmd, id);
     }
 
-    wxWindow *win;
+    wxWindow *win = (wxWindow*) NULL;
     if ( cmd == 0 || cmd == 1 ) // menu or accel - use id
     {
         // must cast to a signed type before comparing with other ids!
         win = FindItem((signed short)id);
     }
-    else
+
+    if (!win && control)
     {
         // find it from HWND - this works even with the broken programs using
         // the same ids for different controls
@@ -3034,17 +3075,25 @@ bool wxWindow::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
     }
 
     if ( win )
+    {
         return win->MSWCommand(cmd, id);
-    else
+    }
+
+    // the messages sent from the in-place edit control used by the treectrl
+    // for label editing have id == 0, but they should _not_ be treated as menu
+    // messages (they are EN_XXX ones, in fact) so don't translate anything
+    // coming from a control to wxEVT_COMMAND_MENU_SELECTED
+    if ( !control )
     {
-        // If no child window, it may be an accelerator, e.g. for
-        // a popup menu command.
+        // If no child window, it may be an accelerator, e.g. for a popup menu
+        // command
 
         wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED);
         event.SetEventObject(this);
         event.SetId(id);
         event.SetInt(id);
-        return ProcessEvent(event);
+
+        return GetEventHandler()->ProcessEvent(event);
     }
 
     return FALSE;
@@ -3158,8 +3207,8 @@ wxKeyEvent wxWindow::CreateKeyEvent(wxEventType evType,
 {
     wxKeyEvent event(evType);
     event.SetId(GetId());
-    event.m_shiftDown = IsShiftDown();
-    event.m_controlDown = IsCtrlDown();
+    event.m_shiftDown = wxIsShiftDown();
+    event.m_controlDown = wxIsCtrlDown();
     event.m_altDown = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN;
 
     event.m_eventObject = (wxWindow *)this; // const_cast
@@ -3713,8 +3762,8 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
 
             event.m_eventObject = NULL;
             event.m_keyCode = id;
-            event.m_shiftDown = IsShiftDown();
-            event.m_controlDown = IsCtrlDown();
+            event.m_shiftDown = wxIsShiftDown();
+            event.m_controlDown = wxIsCtrlDown();
             event.SetTimestamp(s_currentMsg.time);
 
             wxWindow *win = wxGetActiveWindow();
@@ -4166,9 +4215,9 @@ static void TranslateKbdEventToMouse(wxWindow *win, int *x, int *y, WPARAM *flag
     WPARAM& fwKeys = *flags;
 
     fwKeys = MK_RBUTTON;
-    if ( (::GetKeyState(VK_CONTROL) & 0x100) != 0 )
+    if ( wxIsCtrlDown() )
         fwKeys |= MK_CONTROL;
-    if ( (::GetKeyState(VK_SHIFT) & 0x100) != 0 )
+    if ( wxIsShiftDown() )
         fwKeys |= MK_SHIFT;
 
     // simulate right mouse button click