]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
added wxSpinCtrl::SetSelection()
[wxWidgets.git] / src / msw / window.cpp
index 9dbcec6d34929eb668c45474fbebc1ba2c403fcb..62fd946240e16a271465130e1ac4d5772b67987e 100644 (file)
@@ -318,6 +318,8 @@ void wxWindowMSW::Init()
     m_mouseInWindow = FALSE;
     m_lastKeydownProcessed = FALSE;
 
+    m_childrenDisabled = NULL;
+
     // wxWnd
     m_hMenu = 0;
 
@@ -378,6 +380,8 @@ wxWindowMSW::~wxWindowMSW()
         // remove hWnd <-> wxWindow association
         wxRemoveHandleAssociation(this);
     }
+
+    delete m_childrenDisabled;
 }
 
 // real construction (Init() must have been called before!)
@@ -430,10 +434,7 @@ bool wxWindowMSW::Create(wxWindow *parent,
         msflags |= WS_VISIBLE;
     }
 
-    bool retVal = MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle);
-    if (retVal)
-        SetWindowLong( (HWND)m_hWnd, GWL_WNDPROC, (LONG)wxWndProc);
-    return retVal;
+    return MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle);
 }
 
 // ---------------------------------------------------------------------------
@@ -501,19 +502,48 @@ bool wxWindowMSW::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 be reenabled too when you reenable the dialog!
-#if 0
+    // when the parent is disabled, all of its children should be disabled as
+    // well but when it is enabled back, only those of the children which
+    // hadn't been already disabled in the beginning should be enabled again,
+    // so we have to keep the list of those children
     wxWindowList::Node *node = GetChildren().GetFirst();
     while ( node )
     {
         wxWindow *child = node->GetData();
-        child->Enable(enable);
+
+        if ( enable )
+        {
+            // enable the child back unless it had been disabled before us
+            if ( !m_childrenDisabled || !m_childrenDisabled->Find(child) )
+                child->Enable();
+        }
+        else // we're being disabled
+        {
+            if ( child->IsEnabled() )
+            {
+                // disable it as children shouldn't stay enabled while the
+                // parent is not
+                child->Disable();
+            }
+            else // child already disabled, remember it
+            {
+                // have we created the list of disabled children already?
+                if ( !m_childrenDisabled )
+                    m_childrenDisabled = new wxWindowList;
+
+                m_childrenDisabled->Append(child);
+            }
+        }
 
         node = node->GetNext();
     }
-#endif // 0
+
+    if ( enable && m_childrenDisabled )
+    {
+        // we don't need this list any more, don't keep unused memory
+        delete m_childrenDisabled;
+        m_childrenDisabled = NULL;
+    }
 
     return TRUE;
 }
@@ -1028,35 +1058,21 @@ void wxWindowMSW::UnsubclassWin()
 
 bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
 {
-#if wxUSE_UNICODE_MSLU
-    // VS: We can't use GetWindowLong(hwnd, GWL_WNDPROC) together with unicows.dll
-    //     because it doesn't return pointer to the real wnd proc but rather a handle
-    //     of a fake proc that does Unicode<->ANSI translation.
-    //
-    //     The hack bellow works, because WNDCLASS contains original window handler
-    //     rather that the unicows fake one. This may not be on purpose, though; if
-    //     it stops working with future versions of unicows.dll, we can override
-    //     unicows hooks by setting Unicows_{Set,Get}WindowLong and
-    //     Unicows_RegisterClass to our own versions that keep track of
-    //     fake<->real wnd proc mapping.
-    //
-    //     FIXME: Doesn't handle wnd procs set by SetWindowLong, only these set
-    //            with RegisterClass!!
-
-    if ( wxUsingUnicowsDll() )
+    // Unicows note: the code below works, but only because WNDCLASS contains
+    // original window handler rather that the unicows fake one. This may not
+    // be on purpose, though; if it stops working with future versions of
+    // unicows.dll, we can override unicows hooks by setting
+    // Unicows_{Set,Get}WindowLong and Unicows_RegisterClass to our own
+    // versions that keep track of fake<->real wnd proc mapping.
+    WNDCLASS cls;
+    if ( !::GetClassInfo(wxGetInstance(), wxGetWindowClass(hWnd), &cls) )
     {
-        static wxChar buffer[512];
-        WNDCLASS cls;
+        wxLogLastError(_T("GetClassInfo"));
 
-        ::GetClassName((HWND)hWnd, buffer, 512);
-        ::GetClassInfo(wxGetInstance(), buffer, &cls);
-        return wndProc == (WXFARPROC)cls.lpfnWndProc;
-    }
-    else
-#endif
-    {
-        return wndProc == (WXFARPROC)::GetWindowLong((HWND)hWnd, GWL_WNDPROC);
+        return FALSE;
     }
+
+    return wndProc == (WXFARPROC)cls.lpfnWndProc;
 }
 
 // ----------------------------------------------------------------------------
@@ -2266,7 +2282,7 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM w
     // trace all messages - useful for the debugging
 #ifdef __WXDEBUG__
     wxLogTrace(wxTraceMessages, wxT("Processing %s(wParam=%8lx, lParam=%8lx)"),
-               wxGetMessageName(message), wParam, lParam);
+               wxGetMessageName(message), (long) wParam, lParam);
 #endif // __WXDEBUG__
 
     wxWindowMSW *wnd = wxFindWinFromHandle((WXHWND) hWnd);
@@ -2869,7 +2885,7 @@ void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win)
     if ( oldWin && (oldWin != win) )
     {
         wxLogDebug(wxT("HWND %X already associated with another window (%s)"),
-                   hWnd, win->GetClassInfo()->GetClassName());
+                   (int) hWnd, win->GetClassInfo()->GetClassName());
     }
     else
 #endif // __WXDEBUG__
@@ -3315,6 +3331,13 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
     }
 #endif
 
+    // Don't send the event when in the process of being deleted.  This can
+    // only cause problems if the event handler tries to access the object.
+    if ( m_isBeingDeleted )
+    {
+        return FALSE;
+    }
+
     wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
     event.SetEventObject(this);