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:
Vadim Zeitlin
2000-01-15 22:36:52 +00:00
parent 4b89c61845
commit 0d7ea90249
8 changed files with 139 additions and 94 deletions

View File

@@ -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}

View File

@@ -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})

View File

@@ -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;

View File

@@ -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();

View File

@@ -6,7 +6,7 @@
// Created: 04/01/98 // Created: 04/01/98
// RCS-ID: $Id$ // RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem // Copyright: (c) Julian Smart and Markus Holzem
// Licence: wxWindows license // Licence: wxWindows license
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__ #ifdef __GNUG__
@@ -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,60 +43,71 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent, const wxString& message, cons
m_parent = parent; m_parent = parent;
} }
int wxMessageDialog::ShowModal(void) int wxMessageDialog::ShowModal()
{ {
HWND hWnd = 0; if ( !wxTheApp->GetTopWindow() )
if (m_parent) hWnd = (HWND) m_parent->GetHWND(); {
unsigned int msStyle = MB_OK; // when the message box is shown from wxApp::OnInit() (i.e. before the
if (m_dialogStyle & wxYES_NO) // 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
if (m_dialogStyle & wxCANCEL) // OnInit() to see it
msStyle = MB_YESNOCANCEL; while ( wxTheApp->Pending() )
wxTheApp->Dispatch();
}
HWND hWnd = 0;
if (m_parent) hWnd = (HWND) m_parent->GetHWND();
unsigned int msStyle = MB_OK;
if (m_dialogStyle & wxYES_NO)
{
if (m_dialogStyle & wxCANCEL)
msStyle = MB_YESNOCANCEL;
else
msStyle = MB_YESNO;
if (m_dialogStyle & wxNO_DEFAULT)
msStyle |= MB_DEFBUTTON2;
}
if (m_dialogStyle & wxOK)
{
if (m_dialogStyle & wxCANCEL)
msStyle = MB_OKCANCEL;
else
msStyle = MB_OK;
}
if (m_dialogStyle & wxICON_EXCLAMATION)
msStyle |= MB_ICONEXCLAMATION;
else if (m_dialogStyle & wxICON_HAND)
msStyle |= MB_ICONHAND;
else if (m_dialogStyle & wxICON_INFORMATION)
msStyle |= MB_ICONINFORMATION;
else if (m_dialogStyle & wxICON_QUESTION)
msStyle |= MB_ICONQUESTION;
if (hWnd)
msStyle |= MB_APPLMODAL;
else else
msStyle = MB_YESNO; msStyle |= MB_TASKMODAL;
if (m_dialogStyle & wxNO_DEFAULT) int msAns = MessageBox(hWnd, (LPCTSTR)m_message.c_str(),
msStyle |= MB_DEFBUTTON2; (LPCTSTR)m_caption.c_str(), msStyle);
} int ans = wxOK;
switch (msAns)
if (m_dialogStyle & wxOK) {
{ case IDCANCEL:
if (m_dialogStyle & wxCANCEL) ans = wxID_CANCEL;
msStyle = MB_OKCANCEL; break;
else case IDOK:
msStyle = MB_OK; ans = wxID_OK;
} break;
if (m_dialogStyle & wxICON_EXCLAMATION) case IDYES:
msStyle |= MB_ICONEXCLAMATION; ans = wxID_YES;
else if (m_dialogStyle & wxICON_HAND) break;
msStyle |= MB_ICONHAND; case IDNO:
else if (m_dialogStyle & wxICON_INFORMATION) ans = wxID_NO;
msStyle |= MB_ICONINFORMATION; break;
else if (m_dialogStyle & wxICON_QUESTION) }
msStyle |= MB_ICONQUESTION; return ans;
if (hWnd)
msStyle |= MB_APPLMODAL;
else
msStyle |= MB_TASKMODAL;
int msAns = MessageBox(hWnd, (LPCTSTR)(const wxChar *)m_message, (LPCTSTR)(const wxChar *)m_caption, msStyle);
int ans = wxOK;
switch (msAns)
{
case IDCANCEL:
ans = wxID_CANCEL;
break;
case IDOK:
ans = wxID_OK;
break;
case IDYES:
ans = wxID_YES;
break;
case IDNO:
ans = wxID_NO;
break;
}
return ans;
} }

View File

@@ -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));
} }
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -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;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -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;