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
terminated successfully. Also, while waiting for the process to
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}.
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
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}
@ -1652,7 +1653,7 @@ See also \helpref{wxGetDisplayName}{wxgetdisplayname}.
Executes a command in an interactive shell window. If no command is
specified, then just the shell is spawned.
See also \helpref{wxExecute}{wxexecute}.
See also \helpref{wxExecute}{wxexecute}, \helpref{Exec sample}{sampleexec}.
\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
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}
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
the sequence of steps of data transfer.
Finally, the last part is used for two things: you can drag text from it to
either one of the listboxes (only one will accept it) or another application
and, also, bitmap pasted from clipboard will be shown there.
Finally, the last part is used for dragging text from it to either one of the
listboxes (only one will accept it) or another application. The last
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
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
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
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
\helpref{wxDataObject}{wxdataobject} to achieve this.
\subsection{HTML samples}\label{samplehtml}
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
{
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") );
return m_clientObject;
@ -1295,7 +1297,9 @@ void wxWindowBase::DoSetClientData( void *data )
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") );
return m_clientData;

View File

@ -175,7 +175,7 @@ static void DDEDeleteConnection(HCONV hConv)
if (found)
return;
node = wxDDEServerObjects.First();
node = wxDDEClientObjects.First();
while (node && !found)
{
wxDDEClient *object = (wxDDEClient *)node->Data();

View File

@ -6,7 +6,7 @@
// Created: 04/01/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem
// Licence: wxWindows license
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
@ -21,26 +21,21 @@
#endif
#ifndef WX_PRECOMP
#include <stdio.h>
#include "wx/defs.h"
#include "wx/utils.h"
#include "wx/dialog.h"
#include "wx/msgdlg.h"
#include "wx/defs.h"
#include "wx/utils.h"
#include "wx/dialog.h"
#include "wx/msgdlg.h"
#endif
#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)
wxMessageDialog::wxMessageDialog(wxWindow *parent, const wxString& message, const wxString& caption,
long style, const wxPoint& pos)
wxMessageDialog::wxMessageDialog(wxWindow *parent,
const wxString& message,
const wxString& caption,
long style,
const wxPoint& WXUNUSED(pos))
{
m_caption = caption;
m_message = message;
@ -48,60 +43,71 @@ wxMessageDialog::wxMessageDialog(wxWindow *parent, const wxString& message, cons
m_parent = parent;
}
int wxMessageDialog::ShowModal(void)
int wxMessageDialog::ShowModal()
{
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;
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;
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
msStyle = MB_YESNO;
msStyle |= MB_TASKMODAL;
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
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;
int msAns = MessageBox(hWnd, (LPCTSTR)m_message.c_str(),
(LPCTSTR)m_caption.c_str(), 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?
wxLogLastError("TB_SETBUTTONINFO");
}
}
else
#endif // comctl32.dll 4.71
@ -581,7 +580,7 @@ bool wxToolBar::Realize()
TBBUTTON tbb;
wxZeroMemory(tbb);
tbb.idCommand = 0;
tbb.fsState = TBSTATE_ENABLED;
tbb.fsState = TBSTATE_ENABLED | TBSTATE_HIDDEN;
tbb.fsStyle = TBSTYLE_SEP;
size_t nSeparators = size.x / widthSep;
@ -808,7 +807,10 @@ wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
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);
if ( frame )
{
@ -822,7 +824,6 @@ void wxToolBar::UpdateSize()
(void)::SendMessage(GetHwndOf(frame), WM_SIZE, SIZE_RESTORED,
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());
}
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
delete data;
}
}
return 0;
return 0;
}
else
{
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
#endif
@ -247,7 +251,8 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
NULL, // security attributes: defaults for both
NULL, // the process and its main thread
FALSE, // don't inherit handles
CREATE_DEFAULT_ERROR_MODE, // flags
CREATE_DEFAULT_ERROR_MODE |
CREATE_SUSPENDED, // flags
NULL, // environment (use the same)
NULL, // current directory (use the same)
&si, // startup info (unused here)
@ -259,10 +264,7 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
return 0;
}
// close unneeded handle
if ( !::CloseHandle(pi.hThread) )
wxLogLastError("CloseHandle(hThread)");
// register the class for the hidden window used for the notifications
if ( !gs_classForHiddenWindow )
{
gs_classForHiddenWindow = _T("wxHiddenWindow");
@ -276,15 +278,14 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
if ( !::RegisterClass(&wndclass) )
{
wxLogLastError("RegisterClass(hidden window)");
return FALSE;
}
}
// create a hidden window to receive notification about process
// termination
HWND hwnd = ::CreateWindow(gs_classForHiddenWindow, NULL,
0, 0, 0, 0, 0, NULL,
WS_OVERLAPPEDWINDOW,
0, 0, 0, 0, NULL,
(HMENU)NULL, wxGetInstance(), 0);
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,
&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 )
{
wxLogLastError("CreateThread in wxExecute");
@ -333,10 +346,20 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
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 )
wxYield();
#if wxUSE_GUI
wxEnableTopLevelWindows(TRUE);
wxEndBusyCursor();
#endif // wxUSE_GUI
DWORD dwExitCode = data->dwExitCode;
delete data;