From d7cbabe039556a1eb77a578de72b90bc784c3f31 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Fri, 30 Aug 2002 00:34:08 +0000
Subject: [PATCH] disable children when the parent is disabled

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@16857 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt         |  1 +
 docs/latex/wx/window.tex |  4 +++-
 include/wx/msw/window.h  |  3 +++
 src/msw/window.cpp       | 45 ++++++++++++++++++++++++++++++++++------
 4 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/docs/changes.txt b/docs/changes.txt
index ccfc809cda..94eb8e268b 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -266,6 +266,7 @@ wxMSW:
 - fixed bugs in multiple selection wxCheckListBox
 - default button handling is now closer to expected
 - setting tooltips for wxSlider now works
+- disabling a parent window also disables all of its children (as in wxGTK)
 - multiple events avoided in wxComboBox
 - tooltip asserts avoided for read-only wxComboBox
 - fixed a race condition during a thread exit and a join
diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex
index 1c7e69c99a..8458805f35 100644
--- a/docs/latex/wx/window.tex
+++ b/docs/latex/wx/window.tex
@@ -421,7 +421,9 @@ Windows only.
 
 \func{virtual bool}{Enable}{\param{bool}{ enable = {\tt TRUE}}}
 
-Enable or disable the window for user input.
+Enable or disable the window for user input. Note that when a parent window is
+disabled, all of its children are disabled as well and they are reenabled again
+when the parent is.
 
 \wxheading{Parameters}
 
diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h
index 28045117b7..ff29093534 100644
--- a/include/wx/msw/window.h
+++ b/include/wx/msw/window.h
@@ -488,6 +488,9 @@ private:
     bool HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result);
 #endif // __WIN95__
 
+    // list of disabled children before last call to our Disable()
+    wxWindowList *m_childrenDisabled;
+
     DECLARE_DYNAMIC_CLASS(wxWindowMSW)
     DECLARE_NO_COPY_CLASS(wxWindowMSW)
     DECLARE_EVENT_TABLE()
diff --git a/src/msw/window.cpp b/src/msw/window.cpp
index d6c6ca249d..62fd946240 100644
--- a/src/msw/window.cpp
+++ b/src/msw/window.cpp
@@ -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!)
@@ -498,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;
 }
-- 
2.50.0

