diff --git a/distrib/msw/tmake/vc6base.t b/distrib/msw/tmake/vc6base.t index e3393a020f..dfb732331b 100644 --- a/distrib/msw/tmake/vc6base.t +++ b/distrib/msw/tmake/vc6base.t @@ -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 diff --git a/include/wx/utils.h b/include/wx/utils.h index e1d4168a83..09ac220a9e 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -290,6 +290,10 @@ public: private: wxWindowList *m_winDisabled; + +#ifdef __WXMSW__ + wxWindow *m_winTop; +#endif // MSW }; // ---------------------------------------------------------------------------- diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index 3f62793a9e..c9e9207ebb 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -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() ) diff --git a/src/msw/dialog.cpp b/src/msw/dialog.cpp index 480836f8f9..bbd4c9f334 100644 --- a/src/msw/dialog.cpp +++ b/src/msw/dialog.cpp @@ -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 diff --git a/src/msw/utilsexc.cpp b/src/msw/utilsexc.cpp index 4a5489086c..453b7efc5d 100644 --- a/src/msw/utilsexc.cpp +++ b/src/msw/utilsexc.cpp @@ -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