wxBase/GUI separation: 1st step, wxMSW should build, all the rest is broken
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@21342 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -33,9 +33,6 @@
|
||||
#include "wx/app.h"
|
||||
#include "wx/intl.h"
|
||||
#include "wx/log.h"
|
||||
#if wxUSE_GUI // See 'dirty hack' below.
|
||||
#include "wx/frame.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __WIN32__
|
||||
@@ -43,6 +40,8 @@
|
||||
#include "wx/process.h"
|
||||
#endif
|
||||
|
||||
#include "wx/apptrait.h"
|
||||
|
||||
#include "wx/msw/private.h"
|
||||
|
||||
#include <ctype.h>
|
||||
@@ -594,8 +593,6 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
|
||||
command = cmd;
|
||||
}
|
||||
|
||||
#if defined(__WIN32__)
|
||||
|
||||
// the IO redirection is only supported with wxUSE_STREAMS
|
||||
BOOL redirect = FALSE;
|
||||
|
||||
@@ -854,100 +851,35 @@ long wxExecute(const wxString& cmd, int flags, wxProcess *handler)
|
||||
return pi.dwProcessId;
|
||||
}
|
||||
|
||||
wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
|
||||
wxCHECK_MSG( traits, -1, _T("no wxAppTraits in wxExecute()?") );
|
||||
|
||||
// disable all app windows while waiting for the child process to finish
|
||||
#if wxUSE_GUI
|
||||
void *cookie = traits->BeforeChildWaitLoop();
|
||||
|
||||
/*
|
||||
We use a dirty hack here to disable all application windows (which we
|
||||
must do because otherwise the calls to wxYield() could lead to some very
|
||||
unexpected reentrancies in the users code) but to avoid losing
|
||||
focus/activation entirely when the child process terminates which would
|
||||
happen if we simply disabled everything using wxWindowDisabler. Indeed,
|
||||
remember that Windows will never activate a disabled window and when the
|
||||
last childs window is closed and Windows looks for a window to activate
|
||||
all our windows are still disabled. There is no way to enable them in
|
||||
time because we don't know when the childs windows are going to be
|
||||
closed, so the solution we use here is to keep one special tiny frame
|
||||
enabled all the time. Then when the child terminates it will get
|
||||
activated and when we close it below -- after reenabling all the other
|
||||
windows! -- the previously active window becomes activated again and
|
||||
everything is ok.
|
||||
*/
|
||||
wxWindow *winActive;
|
||||
// wait until the child process terminates
|
||||
while ( data->state )
|
||||
{
|
||||
wxBusyCursor bc;
|
||||
|
||||
// first disable all existing windows
|
||||
wxWindowDisabler wd;
|
||||
|
||||
// then create an "invisible" frame: it has minimal size, is positioned
|
||||
// (hopefully) outside the screen and doesn't appear on the taskbar
|
||||
winActive = new wxFrame
|
||||
(
|
||||
wxTheApp->GetTopWindow(),
|
||||
-1,
|
||||
_T(""),
|
||||
wxPoint(32600, 32600),
|
||||
wxSize(1, 1),
|
||||
wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR
|
||||
);
|
||||
winActive->Show();
|
||||
#endif // wxUSE_GUI
|
||||
|
||||
// wait until the child process terminates
|
||||
while ( data->state )
|
||||
{
|
||||
#if wxUSE_STREAMS
|
||||
bufOut.Update();
|
||||
bufErr.Update();
|
||||
bufOut.Update();
|
||||
bufErr.Update();
|
||||
#endif // wxUSE_STREAMS
|
||||
|
||||
// don't eat 100% of the CPU -- ugly but anything else requires
|
||||
// real async IO which we don't have for the moment
|
||||
::Sleep(50);
|
||||
// don't eat 100% of the CPU -- ugly but anything else requires
|
||||
// real async IO which we don't have for the moment
|
||||
::Sleep(50);
|
||||
|
||||
#if wxUSE_GUI
|
||||
// repaint the GUI
|
||||
wxYield();
|
||||
#else // !GUI
|
||||
// dispatch the messages to the hidden window so that it could
|
||||
// process the wxWM_PROC_TERMINATED notification
|
||||
MSG msg;
|
||||
::PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE);
|
||||
#endif // GUI/!GUI
|
||||
}
|
||||
|
||||
#if wxUSE_GUI
|
||||
// we must process messages or we'd never get wxWM_PROC_TERMINATED
|
||||
traits->AlwaysYield();
|
||||
}
|
||||
|
||||
// finally delete the dummy frame and, as wd has been already destroyed and
|
||||
// the other windows reenabled, the activation is going to return to the
|
||||
// window which had it before
|
||||
winActive->Destroy();
|
||||
#endif // wxUSE_GUI
|
||||
traits->AfterChildWaitLoop(cookie);
|
||||
|
||||
DWORD dwExitCode = data->dwExitCode;
|
||||
delete data;
|
||||
|
||||
// return the exit code
|
||||
return dwExitCode;
|
||||
#else // Win16
|
||||
long instanceID = WinExec((LPCSTR) WXSTRINGCAST command, SW_SHOW);
|
||||
if (instanceID < 32)
|
||||
return flags & wxEXEC_SYNC ? -1 : 0;
|
||||
|
||||
if ( flags & wxEXEC_SYNC )
|
||||
{
|
||||
int running;
|
||||
do
|
||||
{
|
||||
wxYield();
|
||||
running = GetModuleUsage((HINSTANCE)instanceID);
|
||||
} while (running);
|
||||
}
|
||||
|
||||
return instanceID;
|
||||
#endif // Win16/32
|
||||
}
|
||||
|
||||
long wxExecute(wxChar **argv, int flags, wxProcess *handler)
|
||||
|
Reference in New Issue
Block a user