]> git.saurik.com Git - wxWidgets.git/commitdiff
1. wxWindowDisabler modified to bring parent window back to top under MSW
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 5 Mar 2000 02:12:04 +0000 (02:12 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 5 Mar 2000 02:12:04 +0000 (02:12 +0000)
2. modal dialogs without parent now use the app top window as parent or use
   wxWindowDisabler if none
3. modal dialogs bring parent windows to top when activated
4. wxBase dsp will now compile it with MT CRT

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6451 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

distrib/msw/tmake/vc6base.t
include/wx/utils.h
src/common/utilscmn.cpp
src/msw/dialog.cpp
src/msw/utilsexc.cpp

index e3393a020fd653f902a195f038340583bc74ef4e..dfb732331b5dbcd8071df93db52d9df5fd4733f1 100644 (file)
@@ -73,7 +73,7 @@ RSC=rc.exe
 # PROP Output_Dir "BaseRelease"
 # PROP Intermediate_Dir "BaseRelease"
 # PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D _MT /YX /FD /c
+# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D _MT /YX /FD /c
 # ADD CPP /nologo /W3 /Zi /O2 /I "$(wx)\include" /I "$(wx)\src\zlib" /D "NDEBUG" /D wxUSE_GUI=0 /D WIN95=1 /D "__WIN95__" /D "WIN32" /D "_WIN32" /D WINVER=0x400 /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN32__" /D _MT /Yu"wx/wxprec.h" /FD /c
 # ADD BASE RSC /l 0x409
 # ADD RSC /l 0x409
@@ -96,7 +96,7 @@ LIB32=link.exe -lib
 # PROP Output_Dir "BaseDebug"
 # PROP Intermediate_Dir "BaseDebug"
 # PROP Target_Dir ""
-# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D _MT /YX /FD /c
+# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D _MT /YX /FD /c
 # ADD CPP /nologo /W4 /Zi /Od /I "$(wx)\include" /I "$(wx)\src\zlib" /D "_DEBUG" /D DEBUG=1 /D WXDEBUG=1 /D "__WXDEBUG__" /D wxUSE_GUI=0 /D "__WIN95__" /D "WIN32" /D "_WIN32" /D WINVER=0x400 /D "__WINDOWS__" /D "__WIN32__" /D "__WXMSW__" /D _MT /Fr /Yu"wx/wxprec.h" /FD /c
 # ADD BASE RSC /l 0x409
 # ADD RSC /l 0x409
index e1d4168a83e32c71aee30d8e1faa5250db957a8e..09ac220a9ea1491e0eedea64da2e464842c015aa 100644 (file)
@@ -290,6 +290,10 @@ public:
 
 private:
     wxWindowList *m_winDisabled;
+
+#ifdef __WXMSW__
+    wxWindow *m_winTop;
+#endif // MSW
 };
 
 // ----------------------------------------------------------------------------
index 3f62793a9eb1930cd8b1b42371f8619e1ff288ed..c9e9207ebbb657d80a97aac7a302021e395c8950 100644 (file)
@@ -78,7 +78,7 @@
 #endif
 
 #ifdef __WXMSW__
-    #include "windows.h"
+    #include "wx/msw/private.h"
 #endif
 
 // ----------------------------------------------------------------------------
@@ -983,6 +983,12 @@ wxWindowDisabler::wxWindowDisabler(wxWindow *winToSkip)
     // remember all windows we're going to (temporarily) disable
     m_winDisabled = new wxWindowList;
 
+#ifdef __WXMSW__
+    // and the top level window too
+    HWND hwndFG = ::GetForegroundWindow();
+    m_winTop = hwndFG ? wxFindWinFromHandle((WXHWND)hwndFG) : (wxWindow *)NULL;
+#endif // MSW
+
     wxWindowList::Node *node;
     for ( node = wxTopLevelWindows.GetFirst(); node; node = node->GetNext() )
     {
@@ -1013,6 +1019,16 @@ wxWindowDisabler::~wxWindowDisabler()
     }
 
     delete m_winDisabled;
+
+#ifdef __WXMSW__
+    if ( m_winTop )
+    {
+        if ( !::SetForegroundWindow(GetHwndOf(m_winTop)) )
+        {
+            wxLogLastError("SetForegroundWindow");
+        }
+    }
+#endif // MSW
 }
 
 // Yield to other apps/messages and disable user input to all windows except
@@ -1188,7 +1204,7 @@ long wxExecute(const wxString& command, wxArrayString& output)
     {
         wxInputStream& is = *process->GetInputStream();
         wxTextInputStream tis(is);
-        while ( !is.Eof() )
+        while ( !is.Eof() && is.IsOk() )
         {
             wxString line = tis.ReadLine();
             if ( is.LastError() )
index 480836f8f956fb45f304dc200d55fbe54e58b58b..bbd4c9f3342355ed1f9871fe15af76a6d199e0e0 100644 (file)
@@ -419,8 +419,29 @@ bool wxDialog::Show(bool show)
 // Replacement for Show(TRUE) for modal dialogs - returns return code
 int wxDialog::ShowModal()
 {
+    // modal dialog needs a parent window, so try to find one
+    if ( !GetParent() )
+    {
+        wxWindow *parent = wxTheApp->GetTopWindow();
+        if ( parent && parent != this )
+        {
+            // use it
+            m_parent = parent;
+        }
+    }
+
+    wxWindowDisabler *wd = (wxWindowDisabler *)NULL;
+    if ( !GetParent() )
+    {
+        // still no parent? make the dialog app modal by disabling all windows
+        wd = new wxWindowDisabler(this);
+    }
+
     m_windowStyle |= wxDIALOG_MODAL;
     Show(TRUE);
+
+    delete wd;
+
     return GetReturnCode();
 }
 
@@ -521,6 +542,33 @@ long wxDialog::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
 
     switch ( message )
     {
+        case WM_ACTIVATE:
+            switch ( LOWORD(wParam) )
+            {
+                case WA_ACTIVE:
+                case WA_CLICKACTIVE:
+                    if ( IsModalShowing() && GetParent() )
+                    {
+                        // bring the owner window to top as the standard dialog
+                        // boxes do
+                        if ( !::SetWindowPos
+                                (
+                                    GetHwndOf(GetParent()),
+                                    GetHwnd(),
+                                    0, 0,
+                                    0, 0,
+                                    SWP_NOACTIVATE |
+                                    SWP_NOMOVE |
+                                    SWP_NOSIZE
+                                ) )
+                        {
+                            wxLogLastError("SetWindowPos(SWP_NOACTIVATE)");
+                        }
+                    }
+                    // fall through to process it normally as well
+            }
+            break;
+
         case WM_CLOSE:
             // if we can't close, tell the system that we processed the
             // message - otherwise it would close us
index 4a5489086c3efd9648841a8c1b18b92016d0305f..453b7efc5d82151bde76325650bafc3240c0027d 100644 (file)
@@ -402,14 +402,16 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
     return result;
 #else // 1
 
-    HANDLE h_readPipe[2];
-    HANDLE h_writePipe[2];
-    HANDLE h_oldreadPipe;
-    HANDLE h_oldwritePipe;
-    BOOL inheritHandles;
+    HANDLE hpipeRead[2];
+    HANDLE hpipeWrite[2];
+    HANDLE hStdIn = INVALID_HANDLE_VALUE;
+    HANDLE hStdOut = INVALID_HANDLE_VALUE;
+
+    // we need to inherit handles in the child process if we want to redirect
+    // its IO
+    BOOL inheritHandles = FALSE;
 
     // open the pipes to which child process IO will be redirected if needed
-    inheritHandles = FALSE;
     if ( handler && handler->IsRedirected() )
     {
         SECURITY_ATTRIBUTES security;
@@ -418,17 +420,17 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
         security.lpSecurityDescriptor = NULL;
         security.bInheritHandle       = TRUE;
 
-        if (! ::CreatePipe(&h_readPipe[0], &h_readPipe[1], &security, 0) )
+        if ( !::CreatePipe(&hpipeRead[0], &hpipeRead[1], &security, 0) )
         {
             wxLogSysError(_("Can't create the inter-process read pipe"));
 
             return 0;
         }
 
-        if (! ::CreatePipe(&h_writePipe[0], &h_writePipe[1], &security, 0) )
+        if ( !::CreatePipe(&hpipeWrite[0], &hpipeWrite[1], &security, 0) )
         {
-            ::CloseHandle(h_readPipe[0]);
-            ::CloseHandle(h_readPipe[1]);
+            ::CloseHandle(hpipeRead[0]);
+            ::CloseHandle(hpipeRead[1]);
 
             wxLogSysError(_("Can't create the inter-process write pipe"));
 
@@ -437,11 +439,14 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
 
         // We need to save the old stdio handles to restore them after the call
         // to CreateProcess
-        h_oldreadPipe  = GetStdHandle(STD_INPUT_HANDLE);
-        h_oldwritePipe = GetStdHandle(STD_OUTPUT_HANDLE);
+        hStdIn  = ::GetStdHandle(STD_INPUT_HANDLE);
+        hStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
 
-        SetStdHandle(STD_INPUT_HANDLE, h_readPipe[0]);
-        SetStdHandle(STD_OUTPUT_HANDLE, h_writePipe[1]);
+        if ( !::SetStdHandle(STD_INPUT_HANDLE, hpipeRead[0]) ||
+             !::SetStdHandle(STD_OUTPUT_HANDLE, hpipeWrite[1]) )
+        {
+            wxLogDebug(_T("Failed to change stdin/out handles"));
+        }
 
         inheritHandles = TRUE;
     }
@@ -470,10 +475,10 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
     {
         if ( inheritHandles )
         {
-            ::CloseHandle(h_writePipe[0]);
-            ::CloseHandle(h_writePipe[1]);
-            ::CloseHandle(h_readPipe[0]);
-            ::CloseHandle(h_readPipe[1]);
+            ::CloseHandle(hpipeWrite[0]);
+            ::CloseHandle(hpipeWrite[1]);
+            ::CloseHandle(hpipeRead[0]);
+            ::CloseHandle(hpipeRead[1]);
         }
 
         wxLogSysError(_("Execution of command '%s' failed"), command.c_str());
@@ -482,17 +487,23 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
     }
 
     // Restore the old stdio handles
-    if (inheritHandles) {
-        SetStdHandle(STD_INPUT_HANDLE, h_oldreadPipe);
-        SetStdHandle(STD_OUTPUT_HANDLE, h_oldwritePipe);
+    if ( inheritHandles )
+    {
+        if ( !::SetStdHandle(STD_INPUT_HANDLE, hStdIn) ||
+             !::SetStdHandle(STD_OUTPUT_HANDLE, hStdOut) )
+        {
+            wxLogDebug(_T("Failed to restore old stdin/out handles"));
+        }
+
+        // they're still opened in child process
+        ::CloseHandle(hpipeWrite[1]);
+        ::CloseHandle(hpipeRead[0]);
 
-        ::CloseHandle(h_writePipe[1]);
-        ::CloseHandle(h_readPipe[0]);
         // We can now initialize the wxStreams
-        wxInputStream *processOutput = new wxPipeInputStream(h_writePipe[0]);
-        wxOutputStream *processInput = new wxPipeOutputStream(h_readPipe[1]);
+        wxInputStream *inStream = new wxPipeInputStream(hpipeWrite[0]);
+        wxOutputStream *outStream = new wxPipeOutputStream(hpipeRead[1]);
 
-        handler->SetPipeStreams(processOutput, processInput);
+        handler->SetPipeStreams(inStream, outStream);
     }
 
     // register the class for the hidden window used for the notifications
@@ -528,8 +539,8 @@ long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
     data->state       = sync;
     if ( sync )
     {
-        wxASSERT_MSG( !handler, wxT("wxProcess param ignored for sync execution") );
-
+        // handler may be !NULL for capturing program output, but we don't use
+        // it wxExecuteData struct in this case
         data->handler = NULL;
     }
     else