1. fixed small bug with toolbar size updates
2. fixed bug with showing message box from wxApp::OnInit() 3. fixed crash on DDE client disconnection 4. fixed wxExecute() which was broken since quite some time (hidden window creation problems) and in wxShell() git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5434 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -1249,7 +1249,7 @@ the process (which terminates by the moment the function returns) and will be
|
|||||||
$-1$ if the process couldn't be started and typically 0 if the process
|
$-1$ if the process couldn't be started and typically 0 if the process
|
||||||
terminated successfully. Also, while waiting for the process to
|
terminated successfully. Also, while waiting for the process to
|
||||||
terminate, wxExecute will call \helpref{wxYield}{wxyield}. The caller
|
terminate, wxExecute will call \helpref{wxYield}{wxyield}. The caller
|
||||||
should ensure that this can cause no recursion, in the simples case by
|
should ensure that this can cause no recursion, in the simplest case by
|
||||||
calling \helpref{wxEnableTopLevelWindows(FALSE)}{wxenabletoplevelwindows}.
|
calling \helpref{wxEnableTopLevelWindows(FALSE)}{wxenabletoplevelwindows}.
|
||||||
|
|
||||||
For asynchronous execution, however, the return value is the process id and
|
For asynchronous execution, however, the return value is the process id and
|
||||||
@@ -1260,7 +1260,8 @@ parameter can not be non NULL for synchronous execution),
|
|||||||
\helpref{wxProcess::OnTerminate}{wxprocessonterminate} will be called when
|
\helpref{wxProcess::OnTerminate}{wxprocessonterminate} will be called when
|
||||||
the process finishes.
|
the process finishes.
|
||||||
|
|
||||||
See also \helpref{wxShell}{wxshell}, \helpref{wxProcess}{wxprocess}.
|
See also \helpref{wxShell}{wxshell}, \helpref{wxProcess}{wxprocess},
|
||||||
|
\helpref{Exec sample}{sampleexec}.
|
||||||
|
|
||||||
\wxheading{Include files}
|
\wxheading{Include files}
|
||||||
|
|
||||||
@@ -1652,7 +1653,7 @@ See also \helpref{wxGetDisplayName}{wxgetdisplayname}.
|
|||||||
Executes a command in an interactive shell window. If no command is
|
Executes a command in an interactive shell window. If no command is
|
||||||
specified, then just the shell is spawned.
|
specified, then just the shell is spawned.
|
||||||
|
|
||||||
See also \helpref{wxExecute}{wxexecute}.
|
See also \helpref{wxExecute}{wxexecute}, \helpref{Exec sample}{sampleexec}.
|
||||||
|
|
||||||
\wxheading{Include files}
|
\wxheading{Include files}
|
||||||
|
|
||||||
|
@@ -69,6 +69,13 @@ a dialog or frame. This is most typically the case for any scripting
|
|||||||
languge that would work as a wrapper for wxWindows or programs where
|
languge that would work as a wrapper for wxWindows or programs where
|
||||||
forms or similar datagrams can be created by the uses.
|
forms or similar datagrams can be created by the uses.
|
||||||
|
|
||||||
|
\subsection{Exec sample}\label{sampleexec}
|
||||||
|
|
||||||
|
The exec sample demonstrates the \helpref{wxExecute}{wxexecute} and
|
||||||
|
\helpref{wxShell}{wxshell} functions. Both of them are used to execute the
|
||||||
|
external programs and the sample shows how to do this synchronously (waiting
|
||||||
|
until the program terminates) or asynchronously (notification will come later).
|
||||||
|
|
||||||
\subsection{Scroll subwindow sample}\label{samplescrollsub}
|
\subsection{Scroll subwindow sample}\label{samplescrollsub}
|
||||||
|
|
||||||
This sample demonstrates the use of the \helpref{wxScrolledWindow}{wxscrolledwindow}
|
This sample demonstrates the use of the \helpref{wxScrolledWindow}{wxscrolledwindow}
|
||||||
@@ -105,9 +112,11 @@ The middle of the sample window is taken by the log window which shows what is
|
|||||||
going on (of course, this only works in debug builds) and may be helpful to see
|
going on (of course, this only works in debug builds) and may be helpful to see
|
||||||
the sequence of steps of data transfer.
|
the sequence of steps of data transfer.
|
||||||
|
|
||||||
Finally, the last part is used for two things: you can drag text from it to
|
Finally, the last part is used for dragging text from it to either one of the
|
||||||
either one of the listboxes (only one will accept it) or another application
|
listboxes (only one will accept it) or another application. The last
|
||||||
and, also, bitmap pasted from clipboard will be shown there.
|
functionality available from the main frame is to paste a bitmap from the
|
||||||
|
clipboard (or, in the case of Windows version, also a metafile) - it will be
|
||||||
|
shown in a new frame.
|
||||||
|
|
||||||
So far, everything we mentioned was implemented with minimal amount of code
|
So far, everything we mentioned was implemented with minimal amount of code
|
||||||
using standard wxWindows classes. The more advanced features are demonstrated
|
using standard wxWindows classes. The more advanced features are demonstrated
|
||||||
@@ -118,12 +127,13 @@ private \helpref{wxDataFormat}{wxdataformat} which means that you may cut and
|
|||||||
paste it or drag and drop (between one and the same or different shapes) from
|
paste it or drag and drop (between one and the same or different shapes) from
|
||||||
one sample instance to another (or the same). However, chances are that no
|
one sample instance to another (or the same). However, chances are that no
|
||||||
other program supports this format and so shapes can also be rendered as
|
other program supports this format and so shapes can also be rendered as
|
||||||
bitmaps which allows them to be pasted/dropped in many other applications.
|
bitmaps which allows them to be pasted/dropped in many other applications
|
||||||
|
(and, under Windows, also as metafiles which are supported by most of Windows
|
||||||
|
programs as well - try Write/Wordpad, for example).
|
||||||
|
|
||||||
Take a look at DnDShapeDataObject class to see how you may use
|
Take a look at DnDShapeDataObject class to see how you may use
|
||||||
\helpref{wxDataObject}{wxdataobject} to achieve this.
|
\helpref{wxDataObject}{wxdataobject} to achieve this.
|
||||||
|
|
||||||
|
|
||||||
\subsection{HTML samples}\label{samplehtml}
|
\subsection{HTML samples}\label{samplehtml}
|
||||||
|
|
||||||
Eight HTML samples (you can find them in directory {\tt samples/html})
|
Eight HTML samples (you can find them in directory {\tt samples/html})
|
||||||
|
@@ -1278,7 +1278,9 @@ void wxWindowBase::DoSetClientObject( wxClientData *data )
|
|||||||
|
|
||||||
wxClientData *wxWindowBase::DoGetClientObject() const
|
wxClientData *wxWindowBase::DoGetClientObject() const
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( m_clientDataType == ClientData_Object,
|
// it's not an error to call GetClientObject() on a window which doesn't
|
||||||
|
// have client data at all - NULL will be returned
|
||||||
|
wxASSERT_MSG( m_clientDataType != ClientData_Void,
|
||||||
wxT("this window doesn't have object client data") );
|
wxT("this window doesn't have object client data") );
|
||||||
|
|
||||||
return m_clientObject;
|
return m_clientObject;
|
||||||
@@ -1295,7 +1297,9 @@ void wxWindowBase::DoSetClientData( void *data )
|
|||||||
|
|
||||||
void *wxWindowBase::DoGetClientData() const
|
void *wxWindowBase::DoGetClientData() const
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( m_clientDataType == ClientData_Void,
|
// it's not an error to call GetClientData() on a window which doesn't have
|
||||||
|
// client data at all - NULL will be returned
|
||||||
|
wxASSERT_MSG( m_clientDataType != ClientData_Object,
|
||||||
wxT("this window doesn't have void client data") );
|
wxT("this window doesn't have void client data") );
|
||||||
|
|
||||||
return m_clientData;
|
return m_clientData;
|
||||||
|
@@ -175,7 +175,7 @@ static void DDEDeleteConnection(HCONV hConv)
|
|||||||
if (found)
|
if (found)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
node = wxDDEServerObjects.First();
|
node = wxDDEClientObjects.First();
|
||||||
while (node && !found)
|
while (node && !found)
|
||||||
{
|
{
|
||||||
wxDDEClient *object = (wxDDEClient *)node->Data();
|
wxDDEClient *object = (wxDDEClient *)node->Data();
|
||||||
|
@@ -21,26 +21,21 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#include <stdio.h>
|
#include "wx/defs.h"
|
||||||
#include "wx/defs.h"
|
#include "wx/utils.h"
|
||||||
#include "wx/utils.h"
|
#include "wx/dialog.h"
|
||||||
#include "wx/dialog.h"
|
#include "wx/msgdlg.h"
|
||||||
#include "wx/msgdlg.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define wxDIALOG_DEFAULT_X 300
|
|
||||||
#define wxDIALOG_DEFAULT_Y 300
|
|
||||||
|
|
||||||
IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
|
IMPLEMENT_CLASS(wxMessageDialog, wxDialog)
|
||||||
|
|
||||||
wxMessageDialog::wxMessageDialog(wxWindow *parent, const wxString& message, const wxString& caption,
|
wxMessageDialog::wxMessageDialog(wxWindow *parent,
|
||||||
long style, const wxPoint& pos)
|
const wxString& message,
|
||||||
|
const wxString& caption,
|
||||||
|
long style,
|
||||||
|
const wxPoint& WXUNUSED(pos))
|
||||||
{
|
{
|
||||||
m_caption = caption;
|
m_caption = caption;
|
||||||
m_message = message;
|
m_message = message;
|
||||||
@@ -48,8 +43,18 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent, const wxString& message, cons
|
|||||||
m_parent = parent;
|
m_parent = parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wxMessageDialog::ShowModal(void)
|
int wxMessageDialog::ShowModal()
|
||||||
{
|
{
|
||||||
|
if ( !wxTheApp->GetTopWindow() )
|
||||||
|
{
|
||||||
|
// when the message box is shown from wxApp::OnInit() (i.e. before the
|
||||||
|
// message loop is entered), this must be done or the next message box
|
||||||
|
// will never be shown - just try putting 2 calls to wxMessageBox() in
|
||||||
|
// OnInit() to see it
|
||||||
|
while ( wxTheApp->Pending() )
|
||||||
|
wxTheApp->Dispatch();
|
||||||
|
}
|
||||||
|
|
||||||
HWND hWnd = 0;
|
HWND hWnd = 0;
|
||||||
if (m_parent) hWnd = (HWND) m_parent->GetHWND();
|
if (m_parent) hWnd = (HWND) m_parent->GetHWND();
|
||||||
unsigned int msStyle = MB_OK;
|
unsigned int msStyle = MB_OK;
|
||||||
@@ -85,7 +90,8 @@ int wxMessageDialog::ShowModal(void)
|
|||||||
else
|
else
|
||||||
msStyle |= MB_TASKMODAL;
|
msStyle |= MB_TASKMODAL;
|
||||||
|
|
||||||
int msAns = MessageBox(hWnd, (LPCTSTR)(const wxChar *)m_message, (LPCTSTR)(const wxChar *)m_caption, msStyle);
|
int msAns = MessageBox(hWnd, (LPCTSTR)m_message.c_str(),
|
||||||
|
(LPCTSTR)m_caption.c_str(), msStyle);
|
||||||
int ans = wxOK;
|
int ans = wxOK;
|
||||||
switch (msAns)
|
switch (msAns)
|
||||||
{
|
{
|
||||||
|
@@ -568,7 +568,6 @@ bool wxToolBar::Realize()
|
|||||||
// the id is probably invalid?
|
// the id is probably invalid?
|
||||||
wxLogLastError("TB_SETBUTTONINFO");
|
wxLogLastError("TB_SETBUTTONINFO");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif // comctl32.dll 4.71
|
#endif // comctl32.dll 4.71
|
||||||
@@ -581,7 +580,7 @@ bool wxToolBar::Realize()
|
|||||||
TBBUTTON tbb;
|
TBBUTTON tbb;
|
||||||
wxZeroMemory(tbb);
|
wxZeroMemory(tbb);
|
||||||
tbb.idCommand = 0;
|
tbb.idCommand = 0;
|
||||||
tbb.fsState = TBSTATE_ENABLED;
|
tbb.fsState = TBSTATE_ENABLED | TBSTATE_HIDDEN;
|
||||||
tbb.fsStyle = TBSTYLE_SEP;
|
tbb.fsStyle = TBSTYLE_SEP;
|
||||||
|
|
||||||
size_t nSeparators = size.x / widthSep;
|
size_t nSeparators = size.x / widthSep;
|
||||||
@@ -808,7 +807,10 @@ wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
|
|||||||
|
|
||||||
void wxToolBar::UpdateSize()
|
void wxToolBar::UpdateSize()
|
||||||
{
|
{
|
||||||
// we must refresh the frame after the toolbar size (possibly) changed
|
// the toolbar size changed
|
||||||
|
SendMessage(GetHwnd(), TB_AUTOSIZE, 0, 0);
|
||||||
|
|
||||||
|
// we must also refresh the frame after the toolbar size (possibly) changed
|
||||||
wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
|
wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
|
||||||
if ( frame )
|
if ( frame )
|
||||||
{
|
{
|
||||||
@@ -822,7 +824,6 @@ void wxToolBar::UpdateSize()
|
|||||||
(void)::SendMessage(GetHwndOf(frame), WM_SIZE, SIZE_RESTORED,
|
(void)::SendMessage(GetHwndOf(frame), WM_SIZE, SIZE_RESTORED,
|
||||||
MAKELPARAM(r.right - r.left, r.bottom - r.top));
|
MAKELPARAM(r.right - r.left, r.bottom - r.top));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -454,7 +454,7 @@ bool wxShell(const wxString& command)
|
|||||||
cmd.Printf(wxT("%s /c %s"), shell, command.c_str());
|
cmd.Printf(wxT("%s /c %s"), shell, command.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxExecute(cmd, FALSE) != 0;
|
return wxExecute(cmd, TRUE /* sync */) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -167,9 +167,13 @@ LRESULT APIENTRY _EXPORT wxExecuteWindowCbk(HWND hWnd, UINT message,
|
|||||||
// asynchronous execution - we should do the clean up
|
// asynchronous execution - we should do the clean up
|
||||||
delete data;
|
delete data;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -247,7 +251,8 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
|
|||||||
NULL, // security attributes: defaults for both
|
NULL, // security attributes: defaults for both
|
||||||
NULL, // the process and its main thread
|
NULL, // the process and its main thread
|
||||||
FALSE, // don't inherit handles
|
FALSE, // don't inherit handles
|
||||||
CREATE_DEFAULT_ERROR_MODE, // flags
|
CREATE_DEFAULT_ERROR_MODE |
|
||||||
|
CREATE_SUSPENDED, // flags
|
||||||
NULL, // environment (use the same)
|
NULL, // environment (use the same)
|
||||||
NULL, // current directory (use the same)
|
NULL, // current directory (use the same)
|
||||||
&si, // startup info (unused here)
|
&si, // startup info (unused here)
|
||||||
@@ -259,10 +264,7 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// close unneeded handle
|
// register the class for the hidden window used for the notifications
|
||||||
if ( !::CloseHandle(pi.hThread) )
|
|
||||||
wxLogLastError("CloseHandle(hThread)");
|
|
||||||
|
|
||||||
if ( !gs_classForHiddenWindow )
|
if ( !gs_classForHiddenWindow )
|
||||||
{
|
{
|
||||||
gs_classForHiddenWindow = _T("wxHiddenWindow");
|
gs_classForHiddenWindow = _T("wxHiddenWindow");
|
||||||
@@ -276,15 +278,14 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
|
|||||||
if ( !::RegisterClass(&wndclass) )
|
if ( !::RegisterClass(&wndclass) )
|
||||||
{
|
{
|
||||||
wxLogLastError("RegisterClass(hidden window)");
|
wxLogLastError("RegisterClass(hidden window)");
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a hidden window to receive notification about process
|
// create a hidden window to receive notification about process
|
||||||
// termination
|
// termination
|
||||||
HWND hwnd = ::CreateWindow(gs_classForHiddenWindow, NULL,
|
HWND hwnd = ::CreateWindow(gs_classForHiddenWindow, NULL,
|
||||||
0, 0, 0, 0, 0, NULL,
|
WS_OVERLAPPEDWINDOW,
|
||||||
|
0, 0, 0, 0, NULL,
|
||||||
(HMENU)NULL, wxGetInstance(), 0);
|
(HMENU)NULL, wxGetInstance(), 0);
|
||||||
wxASSERT_MSG( hwnd, wxT("can't create a hidden window for wxExecute") );
|
wxASSERT_MSG( hwnd, wxT("can't create a hidden window for wxExecute") );
|
||||||
|
|
||||||
@@ -314,6 +315,18 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
|
|||||||
0,
|
0,
|
||||||
&tid);
|
&tid);
|
||||||
|
|
||||||
|
// resume process we created now - whether the thread creation succeeded or
|
||||||
|
// not
|
||||||
|
if ( ::ResumeThread(pi.hThread) == (DWORD)-1 )
|
||||||
|
{
|
||||||
|
// ignore it - what can we do?
|
||||||
|
wxLogLastError("ResumeThread in wxExecute");
|
||||||
|
}
|
||||||
|
|
||||||
|
// close unneeded handle
|
||||||
|
if ( !::CloseHandle(pi.hThread) )
|
||||||
|
wxLogLastError("CloseHandle(hThread)");
|
||||||
|
|
||||||
if ( !hThread )
|
if ( !hThread )
|
||||||
{
|
{
|
||||||
wxLogLastError("CreateThread in wxExecute");
|
wxLogLastError("CreateThread in wxExecute");
|
||||||
@@ -333,10 +346,20 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
|
|||||||
return pi.dwProcessId;
|
return pi.dwProcessId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// waiting until command executed
|
// waiting until command executed (disable everything while doing it)
|
||||||
|
#if wxUSE_GUI
|
||||||
|
wxBeginBusyCursor();
|
||||||
|
wxEnableTopLevelWindows(FALSE);
|
||||||
|
#endif // wxUSE_GUI
|
||||||
|
|
||||||
while ( data->state )
|
while ( data->state )
|
||||||
wxYield();
|
wxYield();
|
||||||
|
|
||||||
|
#if wxUSE_GUI
|
||||||
|
wxEnableTopLevelWindows(TRUE);
|
||||||
|
wxEndBusyCursor();
|
||||||
|
#endif // wxUSE_GUI
|
||||||
|
|
||||||
DWORD dwExitCode = data->dwExitCode;
|
DWORD dwExitCode = data->dwExitCode;
|
||||||
delete data;
|
delete data;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user