1. small fix in wxDirDialog: SHBrowseForFolder() doesn't like '/'s
2. streamlined DDE code (better error handling, range checking) 3. hack in wxExecute to allow launching DDE servers 4. changed wxTreeCtrl::m_filename scope from private to protected 5. corrected creating wxBitmaps from XBMs 6. wxListCtrl no longer sends bogus ACTIVATED events git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@5488 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -155,7 +155,7 @@ public:
|
||||
bool Modified() const { return IsModified(); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
protected:
|
||||
// the name of the last file loaded with LoadFile() which will be used by
|
||||
// SaveFile() by default
|
||||
wxString m_filename;
|
||||
|
@@ -758,13 +758,15 @@ wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
strKey << wxT("\\shell\\") << verb << wxT("\\command");
|
||||
wxRegKey key(wxRegKey::HKCR, strKey);
|
||||
strKey << wxT("\\shell\\") << verb;
|
||||
wxRegKey key(wxRegKey::HKCR, strKey + _T("\\command"));
|
||||
wxString command;
|
||||
if ( key.Open() ) {
|
||||
// it's the default value of the key
|
||||
if ( key.QueryValue(wxT(""), command) ) {
|
||||
// transform it from '%1' to '%s' style format string
|
||||
// transform it from '%1' to '%s' style format string (now also
|
||||
// test for %L - apparently MS started using it as well for the
|
||||
// same purpose)
|
||||
|
||||
// NB: we don't make any attempt to verify that the string is valid,
|
||||
// i.e. doesn't contain %2, or second %1 or .... But we do make
|
||||
@@ -773,7 +775,9 @@ wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const
|
||||
size_t len = command.Len();
|
||||
for ( size_t n = 0; (n < len) && !foundFilename; n++ ) {
|
||||
if ( command[n] == wxT('%') &&
|
||||
(n + 1 < len) && command[n + 1] == wxT('1') ) {
|
||||
(n + 1 < len) &&
|
||||
(command[n + 1] == wxT('1') ||
|
||||
command[n + 1] == wxT('L')) ) {
|
||||
// replace it with '%s'
|
||||
command[n + 1] = wxT('s');
|
||||
|
||||
@@ -781,8 +785,33 @@ wxString wxFileTypeImpl::GetCommand(const wxChar *verb) const
|
||||
}
|
||||
}
|
||||
|
||||
if ( !foundFilename ) {
|
||||
// we didn't find any '%1'!
|
||||
// look whether we must issue some DDE requests to the application
|
||||
// (and not just launch it)
|
||||
strKey += _T("\\DDEExec");
|
||||
wxRegKey keyDDE(wxRegKey::HKCR, strKey);
|
||||
if ( keyDDE.Open() ) {
|
||||
wxString ddeCommand, ddeServer, ddeTopic;
|
||||
keyDDE.QueryValue(_T(""), ddeCommand);
|
||||
ddeCommand.Replace(_T("%1"), _T("%s"));
|
||||
|
||||
wxRegKey(wxRegKey::HKCR, strKey + _T("\\Application")).
|
||||
QueryValue(_T(""), ddeServer);
|
||||
wxRegKey(wxRegKey::HKCR, strKey + _T("\\Topic")).
|
||||
QueryValue(_T(""), ddeTopic);
|
||||
|
||||
// HACK: we use a special feature of wxExecute which exists
|
||||
// just because we need it here: it will establish DDE
|
||||
// conversation with the program it just launched
|
||||
command.Prepend(_T("WX_DDE#"));
|
||||
command << _T('#') << ddeServer
|
||||
<< _T('#') << ddeTopic
|
||||
<< _T('#') << ddeCommand;
|
||||
}
|
||||
else if ( !foundFilename ) {
|
||||
// we didn't find any '%1' - the application doesn't know which
|
||||
// file to open (note that we only do it if there is no DDEExec
|
||||
// subkey)
|
||||
//
|
||||
// HACK: append the filename at the end, hope that it will do
|
||||
command << wxT(" %s");
|
||||
}
|
||||
@@ -1779,7 +1808,8 @@ wxMimeTypesManagerImpl::wxMimeTypesManagerImpl()
|
||||
};
|
||||
|
||||
// first read the system wide file(s)
|
||||
for ( size_t n = 0; n < WXSIZEOF(aStandardLocations); n++ ) {
|
||||
size_t n;
|
||||
for ( n = 0; n < WXSIZEOF(aStandardLocations); n++ ) {
|
||||
wxString dir = aStandardLocations[n];
|
||||
|
||||
wxString file = dir + wxT("/mailcap");
|
||||
@@ -1810,7 +1840,7 @@ wxMimeTypesManagerImpl::wxMimeTypesManagerImpl()
|
||||
// read KDE/GNOME tables
|
||||
ArrayIconHandlers& handlers = GetIconHandlers();
|
||||
size_t count = handlers.GetCount();
|
||||
for ( size_t n = 0; n < count; n++ )
|
||||
for ( n = 0; n < count; n++ )
|
||||
handlers[n]->GetMimeInfoRecords(this);
|
||||
}
|
||||
|
||||
|
@@ -1627,7 +1627,7 @@ static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxW
|
||||
|
||||
static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
|
||||
GdkEventButton *WXUNUSED(gdk_event),
|
||||
wxWindow *win )
|
||||
wxWindow *WXUNUSED(win))
|
||||
{
|
||||
DEBUG_MAIN_THREAD
|
||||
|
||||
@@ -1650,7 +1650,7 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
|
||||
|
||||
static gint gtk_scrollbar_button_release_callback( GtkRange *WXUNUSED(widget),
|
||||
GdkEventButton *WXUNUSED(gdk_event),
|
||||
wxWindow *win )
|
||||
wxWindow *WXUNUSED(win))
|
||||
{
|
||||
DEBUG_MAIN_THREAD
|
||||
|
||||
|
@@ -1627,7 +1627,7 @@ static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxW
|
||||
|
||||
static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
|
||||
GdkEventButton *WXUNUSED(gdk_event),
|
||||
wxWindow *win )
|
||||
wxWindow *WXUNUSED(win))
|
||||
{
|
||||
DEBUG_MAIN_THREAD
|
||||
|
||||
@@ -1650,7 +1650,7 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
|
||||
|
||||
static gint gtk_scrollbar_button_release_callback( GtkRange *WXUNUSED(widget),
|
||||
GdkEventButton *WXUNUSED(gdk_event),
|
||||
wxWindow *win )
|
||||
wxWindow *WXUNUSED(win))
|
||||
{
|
||||
DEBUG_MAIN_THREAD
|
||||
|
||||
|
@@ -227,25 +227,63 @@ wxBitmap::~wxBitmap()
|
||||
wxTheBitmapList->DeleteObject(this);
|
||||
}
|
||||
|
||||
wxBitmap::wxBitmap(const char bits[], int the_width, int the_height, int no_bits)
|
||||
wxBitmap::wxBitmap(const char bits[], int width, int height, int depth)
|
||||
{
|
||||
Init();
|
||||
|
||||
wxBitmapRefData *refData = new wxBitmapRefData;
|
||||
m_refData = refData;
|
||||
|
||||
refData->m_width = the_width;
|
||||
refData->m_height = the_height;
|
||||
refData->m_depth = no_bits;
|
||||
refData->m_width = width;
|
||||
refData->m_height = height;
|
||||
refData->m_depth = depth;
|
||||
refData->m_numColors = 0;
|
||||
refData->m_selectedInto = NULL;
|
||||
|
||||
HBITMAP hbmp = ::CreateBitmap(the_width, the_height, 1, no_bits, bits);
|
||||
char *data;
|
||||
if ( depth == 1 )
|
||||
{
|
||||
// we assume that it is in XBM format which is not quite the same as
|
||||
// the format CreateBitmap() wants because the order of bytes in the
|
||||
// line is inversed!
|
||||
static const size_t bytesPerLine = (width + 7) / 8;
|
||||
static const size_t padding = bytesPerLine % 2;
|
||||
static const size_t len = height * ( padding + bytesPerLine );
|
||||
data = (char *)malloc(len);
|
||||
const char *src = bits;
|
||||
char *dst = data;
|
||||
|
||||
for ( int rows = 0; rows < height; rows++ )
|
||||
{
|
||||
// note that offset cannot be size_t due to >= 0 test!
|
||||
for ( int offset = bytesPerLine - 1; offset >= 0; offset-- )
|
||||
{
|
||||
*dst++ = *(src + offset);
|
||||
}
|
||||
|
||||
if ( padding )
|
||||
*dst++ = 0;
|
||||
|
||||
src += bytesPerLine;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// bits should already be in Windows standard format
|
||||
data = (char *)bits; // const_cast is harmless
|
||||
}
|
||||
|
||||
HBITMAP hbmp = ::CreateBitmap(width, height, 1, depth, data);
|
||||
if ( !hbmp )
|
||||
{
|
||||
wxLogLastError("CreateBitmap");
|
||||
}
|
||||
|
||||
if ( data != bits )
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
|
||||
SetHBITMAP((WXHBITMAP)hbmp);
|
||||
}
|
||||
|
||||
|
@@ -204,10 +204,9 @@ bool wxControl::MSWOnNotify(int idCtrl,
|
||||
|
||||
void wxControl::OnEraseBackground(wxEraseEvent& event)
|
||||
{
|
||||
// In general, you don't want to erase the background of a control,
|
||||
// or you'll get a flicker.
|
||||
// TODO: move this 'null' function into each control that
|
||||
// might flicker.
|
||||
// notice that this 'dumb' implementation may cause flicker for some of the
|
||||
// controls in which case they should intercept wxEraseEvent and process it
|
||||
// themselves somehow
|
||||
|
||||
RECT rect;
|
||||
::GetClientRect(GetHwnd(), &rect);
|
||||
|
617
src/msw/dde.cpp
617
src/msw/dde.cpp
@@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: dde.cpp
|
||||
// Name: msw/dde.cpp
|
||||
// Purpose: DDE classes
|
||||
// Author: Julian Smart
|
||||
// Modified by:
|
||||
@@ -9,6 +9,14 @@
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ============================================================================
|
||||
// declarations
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation "dde.h"
|
||||
#endif
|
||||
@@ -20,10 +28,6 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/defs.h"
|
||||
#endif
|
||||
|
||||
#if wxUSE_IPC
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
@@ -35,35 +39,45 @@
|
||||
#include "wx/dde.h"
|
||||
|
||||
#include "wx/msw/private.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
#include <ddeml.h>
|
||||
|
||||
#ifndef __TWIN32__
|
||||
#if !wxUSE_NORLANDER_HEADERS
|
||||
#ifdef __GNUWIN32__
|
||||
#if defined(__TWIN32__) || defined(__GNUWIN32_OLD__)
|
||||
#include "wx/msw/gnuwin32/extra.h"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
// ----------------------------------------------------------------------------
|
||||
// macros and constants
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __WIN32__
|
||||
#define _EXPORT /**/
|
||||
#define _EXPORT
|
||||
#else
|
||||
#define _EXPORT _export
|
||||
#endif
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxDDEServer, wxServerBase)
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxDDEClient, wxClientBase)
|
||||
IMPLEMENT_CLASS(wxDDEConnection, wxConnectionBase)
|
||||
#if wxUSE_UNICODE
|
||||
#define DDE_CP CP_WINUNICODE
|
||||
#else
|
||||
#define DDE_CP CP_WINANSI
|
||||
#endif
|
||||
|
||||
#define GetHConv() ((HCONV)m_hConv)
|
||||
|
||||
// default timeout for DDE operations (5sec)
|
||||
#define DDE_TIMEOUT 5000
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// private functions
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static wxDDEConnection *DDEFindConnection(HCONV hConv);
|
||||
static void DDEDeleteConnection(HCONV hConv);
|
||||
static wxDDEServer *DDEFindServer(const wxString& s);
|
||||
|
||||
extern "C" HDDEDATA EXPENTRY _EXPORT _DDECallback(
|
||||
WORD wType,
|
||||
extern "C" HDDEDATA EXPENTRY _EXPORT _DDECallback(WORD wType,
|
||||
WORD wFmt,
|
||||
HCONV hConv,
|
||||
HSZ hsz1,
|
||||
@@ -75,7 +89,18 @@ DWORD lData2);
|
||||
// Add topic name to atom table before using in conversations
|
||||
static HSZ DDEAddAtom(const wxString& string);
|
||||
static HSZ DDEGetAtom(const wxString& string);
|
||||
static void DDEPrintError(void);
|
||||
|
||||
// string handles
|
||||
static HSZ DDEAtomFromString(const wxString& s);
|
||||
static wxString DDEStringFromAtom(HSZ hsz);
|
||||
|
||||
// error handling
|
||||
static wxString DDEGetErrorMsg(UINT error);
|
||||
static void DDELogError(const wxString& s, UINT error = DMLERR_NO_ERROR);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// global variables
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static DWORD DDEIdInst = 0L;
|
||||
static wxDDEConnection *DDECurrentlyConnecting = NULL;
|
||||
@@ -86,30 +111,61 @@ static wxList wxDDEServerObjects;
|
||||
|
||||
char *DDEDefaultIPCBuffer = NULL;
|
||||
int DDEDefaultIPCBufferSize = 0;
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
*
|
||||
*/
|
||||
|
||||
static bool DDEInitialized = FALSE;
|
||||
|
||||
void wxDDEInitialize()
|
||||
// ----------------------------------------------------------------------------
|
||||
// private classes
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// A module to allow DDE cleanup without calling these functions
|
||||
// from app.cpp or from the user's application.
|
||||
|
||||
class wxDDEModule : public wxModule
|
||||
{
|
||||
if (DDEInitialized)
|
||||
return;
|
||||
DDEInitialized = TRUE;
|
||||
public:
|
||||
wxDDEModule() {}
|
||||
bool OnInit() { return TRUE; }
|
||||
void OnExit() { wxDDECleanUp(); }
|
||||
|
||||
private:
|
||||
DECLARE_DYNAMIC_CLASS(wxDDEModule)
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxWin macros
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxDDEServer, wxServerBase)
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxDDEClient, wxClientBase)
|
||||
IMPLEMENT_CLASS(wxDDEConnection, wxConnectionBase)
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxDDEModule, wxModule)
|
||||
|
||||
// ============================================================================
|
||||
// implementation
|
||||
// ============================================================================
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// initialization and cleanup
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
extern void wxDDEInitialize()
|
||||
{
|
||||
if ( !DDEInitialized )
|
||||
{
|
||||
// Should insert filter flags
|
||||
DdeInitialize(&DDEIdInst, (PFNCALLBACK)MakeProcInstance(
|
||||
(FARPROC)_DDECallback, wxGetInstance()),
|
||||
APPCLASS_STANDARD,
|
||||
0L);
|
||||
PFNCALLBACK callback = (PFNCALLBACK)
|
||||
MakeProcInstance((FARPROC)_DDECallback, wxGetInstance());
|
||||
UINT rc = DdeInitialize(&DDEIdInst, callback, APPCLASS_STANDARD, 0L);
|
||||
if ( rc != DMLERR_NO_ERROR )
|
||||
{
|
||||
DDELogError(_T("Failed to initialize DDE"), rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
DDEInitialized = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* CleanUp
|
||||
*/
|
||||
|
||||
void wxDDECleanUp()
|
||||
{
|
||||
@@ -118,24 +174,13 @@ void wxDDECleanUp()
|
||||
DdeUninitialize(DDEIdInst);
|
||||
DDEIdInst = 0;
|
||||
}
|
||||
if (DDEDefaultIPCBuffer)
|
||||
|
||||
delete [] DDEDefaultIPCBuffer;
|
||||
}
|
||||
|
||||
// A module to allow DDE initialization/cleanup
|
||||
// without calling these functions from app.cpp or from
|
||||
// the user's application.
|
||||
|
||||
class wxDDEModule: public wxModule
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS(wxDDEModule)
|
||||
public:
|
||||
wxDDEModule() {}
|
||||
bool OnInit() { wxDDEInitialize(); return TRUE; };
|
||||
void OnExit() { wxDDECleanUp(); };
|
||||
};
|
||||
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxDDEModule, wxModule)
|
||||
// ----------------------------------------------------------------------------
|
||||
// functions working with the global connection list(s)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Global find connection
|
||||
static wxDDEConnection *DDEFindConnection(HCONV hConv)
|
||||
@@ -200,40 +245,44 @@ static wxDDEServer *DDEFindServer(const wxString& s)
|
||||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
* Server
|
||||
*
|
||||
*/
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDDEServer
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxDDEServer::wxDDEServer(void)
|
||||
wxDDEServer::wxDDEServer()
|
||||
{
|
||||
m_serviceName = "";
|
||||
wxDDEInitialize();
|
||||
|
||||
wxDDEServerObjects.Append(this);
|
||||
}
|
||||
|
||||
bool wxDDEServer::Create(const wxString& server_name)
|
||||
bool wxDDEServer::Create(const wxString& server)
|
||||
{
|
||||
m_serviceName = server_name;
|
||||
HSZ serviceName = DdeCreateStringHandle(DDEIdInst, WXSTRINGCAST server_name, CP_WINANSI);
|
||||
m_serviceName = server;
|
||||
|
||||
if (DdeNameService(DDEIdInst, serviceName, (HSZ) NULL, DNS_REGISTER) == 0)
|
||||
if ( !DdeNameService(DDEIdInst, DDEAtomFromString(server), (HSZ)NULL, DNS_REGISTER) )
|
||||
{
|
||||
DDEPrintError();
|
||||
DDELogError(wxString::Format(_("Failed to register DDE server '%s'"),
|
||||
server.c_str()));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
wxDDEServer::~wxDDEServer(void)
|
||||
wxDDEServer::~wxDDEServer()
|
||||
{
|
||||
if (m_serviceName != wxT(""))
|
||||
if ( !!m_serviceName )
|
||||
{
|
||||
HSZ serviceName = DdeCreateStringHandle(DDEIdInst, WXSTRINGCAST m_serviceName, CP_WINANSI);
|
||||
if (DdeNameService(DDEIdInst, serviceName, NULL, DNS_UNREGISTER) == 0)
|
||||
if ( !DdeNameService(DDEIdInst, DDEAtomFromString(m_serviceName),
|
||||
(HSZ)NULL, DNS_UNREGISTER) )
|
||||
{
|
||||
DDEPrintError();
|
||||
DDELogError(wxString::Format(_("Failed to unregister DDE server '%s'"),
|
||||
m_serviceName.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
wxDDEServerObjects.DeleteObject(this);
|
||||
|
||||
wxNode *node = m_connections.First();
|
||||
@@ -293,19 +342,18 @@ bool wxDDEServer::DeleteConnection(WXHCONV conv)
|
||||
return found;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDDEClient
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Client
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
wxDDEClient::wxDDEClient(void)
|
||||
wxDDEClient::wxDDEClient()
|
||||
{
|
||||
wxDDEInitialize();
|
||||
|
||||
wxDDEClientObjects.Append(this);
|
||||
}
|
||||
|
||||
wxDDEClient::~wxDDEClient(void)
|
||||
wxDDEClient::~wxDDEClient()
|
||||
{
|
||||
wxDDEClientObjects.DeleteObject(this);
|
||||
wxNode *node = m_connections.First();
|
||||
@@ -322,14 +370,18 @@ bool wxDDEClient::ValidHost(const wxString& /* host */)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
wxConnectionBase *wxDDEClient::MakeConnection(const wxString& /* host */, const wxString& server_name, const wxString& topic)
|
||||
wxConnectionBase *wxDDEClient::MakeConnection(const wxString& WXUNUSED(host),
|
||||
const wxString& server,
|
||||
const wxString& topic)
|
||||
{
|
||||
HSZ serviceName = DdeCreateStringHandle(DDEIdInst, WXSTRINGCAST server_name, CP_WINANSI);
|
||||
HSZ topic_atom = DdeCreateStringHandle(DDEIdInst, WXSTRINGCAST topic, CP_WINANSI);
|
||||
|
||||
HCONV hConv = DdeConnect(DDEIdInst, serviceName, topic_atom, (PCONVCONTEXT)NULL);
|
||||
if (hConv == (HCONV) NULL)
|
||||
return (wxConnectionBase*) NULL;
|
||||
HCONV hConv = DdeConnect(DDEIdInst, DDEAtomFromString(server), DDEAtomFromString(topic),
|
||||
(PCONVCONTEXT)NULL);
|
||||
if ( !hConv )
|
||||
{
|
||||
DDELogError(wxString::Format(_("Failed to create connection to "
|
||||
"server '%s' on topic '%s'"),
|
||||
server.c_str(), topic.c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
wxDDEConnection *connection = (wxDDEConnection*) OnMakeConnection();
|
||||
@@ -341,11 +393,12 @@ wxConnectionBase *wxDDEClient::MakeConnection(const wxString& /* host */, const
|
||||
m_connections.Append(connection);
|
||||
return connection;
|
||||
}
|
||||
else return (wxConnectionBase*) NULL;
|
||||
}
|
||||
}
|
||||
|
||||
wxConnectionBase *wxDDEClient::OnMakeConnection(void)
|
||||
return (wxConnectionBase*) NULL;
|
||||
}
|
||||
|
||||
wxConnectionBase *wxDDEClient::OnMakeConnection()
|
||||
{
|
||||
return new wxDDEConnection;
|
||||
}
|
||||
@@ -382,9 +435,9 @@ bool wxDDEClient::DeleteConnection(WXHCONV conv)
|
||||
return found;
|
||||
}
|
||||
|
||||
/*
|
||||
* Connection
|
||||
*/
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxDDEConnection
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
wxDDEConnection::wxDDEConnection(char *buffer, int size)
|
||||
{
|
||||
@@ -401,8 +454,6 @@ wxDDEConnection::wxDDEConnection(char *buffer, int size)
|
||||
m_bufSize = size;
|
||||
}
|
||||
|
||||
m_topicName = "";
|
||||
|
||||
m_client = NULL;
|
||||
m_server = NULL;
|
||||
|
||||
@@ -410,7 +461,7 @@ wxDDEConnection::wxDDEConnection(char *buffer, int size)
|
||||
m_sendingData = NULL;
|
||||
}
|
||||
|
||||
wxDDEConnection::wxDDEConnection(void)
|
||||
wxDDEConnection::wxDDEConnection()
|
||||
{
|
||||
m_hConv = 0;
|
||||
m_sendingData = NULL;
|
||||
@@ -421,10 +472,9 @@ wxDDEConnection::wxDDEConnection(void)
|
||||
|
||||
m_bufPtr = DDEDefaultIPCBuffer;
|
||||
m_bufSize = DDEDefaultIPCBufferSize;
|
||||
m_topicName = "";
|
||||
}
|
||||
|
||||
wxDDEConnection::~wxDDEConnection(void)
|
||||
wxDDEConnection::~wxDDEConnection()
|
||||
{
|
||||
if (m_server)
|
||||
m_server->GetConnections().DeleteObject(this);
|
||||
@@ -433,22 +483,40 @@ wxDDEConnection::~wxDDEConnection(void)
|
||||
}
|
||||
|
||||
// Calls that CLIENT can make
|
||||
bool wxDDEConnection::Disconnect(void)
|
||||
bool wxDDEConnection::Disconnect()
|
||||
{
|
||||
DDEDeleteConnection((HCONV) m_hConv);
|
||||
return (DdeDisconnect((HCONV) m_hConv) != 0);
|
||||
DDEDeleteConnection(GetHConv());
|
||||
|
||||
bool ok = DdeDisconnect(GetHConv()) != 0;
|
||||
if ( !ok )
|
||||
{
|
||||
DDELogError(_T("Failed to disconnect from DDE server gracefully"));
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool wxDDEConnection::Execute(const wxChar *data, int size, wxIPCFormat format)
|
||||
{
|
||||
DWORD result;
|
||||
if (size < 0)
|
||||
size = wxStrlen(data);
|
||||
{
|
||||
size = wxStrlen(data) + 1;
|
||||
}
|
||||
|
||||
size ++;
|
||||
bool ok = DdeClientTransaction((LPBYTE)data, size,
|
||||
GetHConv(),
|
||||
NULL,
|
||||
format,
|
||||
XTYP_EXECUTE,
|
||||
DDE_TIMEOUT,
|
||||
&result) != 0;
|
||||
if ( !ok )
|
||||
{
|
||||
DDELogError(_T("DDE execute request failed"));
|
||||
}
|
||||
|
||||
return (DdeClientTransaction((LPBYTE)data, size, (HCONV) m_hConv,
|
||||
NULL, format, XTYP_EXECUTE, 5000, &result) ? TRUE : FALSE);
|
||||
return ok;
|
||||
}
|
||||
|
||||
char *wxDDEConnection::Request(const wxString& item, int *size, wxIPCFormat format)
|
||||
@@ -456,32 +524,50 @@ char *wxDDEConnection::Request(const wxString& item, int *size, wxIPCFormat form
|
||||
DWORD result;
|
||||
HSZ atom = DDEGetAtom(item);
|
||||
|
||||
HDDEDATA returned_data = DdeClientTransaction(NULL, 0, (HCONV) m_hConv,
|
||||
atom, format, XTYP_REQUEST, 5000, &result);
|
||||
HDDEDATA returned_data = DdeClientTransaction(NULL, 0,
|
||||
GetHConv(),
|
||||
atom, format,
|
||||
XTYP_REQUEST,
|
||||
DDE_TIMEOUT,
|
||||
&result);
|
||||
if ( !returned_data )
|
||||
{
|
||||
DDELogError(_T("DDE data request failed"));
|
||||
|
||||
DWORD len = DdeGetData(returned_data, (LPBYTE)(m_bufPtr), m_bufSize, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD len = DdeGetData(returned_data, (LPBYTE)m_bufPtr, m_bufSize, 0);
|
||||
|
||||
DdeFreeDataHandle(returned_data);
|
||||
|
||||
if (size) *size = (int)len;
|
||||
if (len > 0)
|
||||
{
|
||||
if (size)
|
||||
*size = (int)len;
|
||||
|
||||
return m_bufPtr;
|
||||
}
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
bool wxDDEConnection::Poke(const wxString& item, wxChar *data, int size, wxIPCFormat format)
|
||||
{
|
||||
DWORD result;
|
||||
if (size < 0)
|
||||
size = wxStrlen(data);
|
||||
|
||||
size ++;
|
||||
{
|
||||
size = wxStrlen(data) + 1;
|
||||
}
|
||||
|
||||
HSZ item_atom = DDEGetAtom(item);
|
||||
return (DdeClientTransaction((LPBYTE)data, size, (HCONV) m_hConv,
|
||||
item_atom, format, XTYP_POKE, 5000, &result) ? TRUE : FALSE);
|
||||
bool ok = DdeClientTransaction((LPBYTE)data, size,
|
||||
GetHConv(),
|
||||
item_atom, format,
|
||||
XTYP_POKE,
|
||||
DDE_TIMEOUT,
|
||||
&result) != 0;
|
||||
if ( !ok )
|
||||
{
|
||||
DDELogError(_("DDE poke request failed"));
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool wxDDEConnection::StartAdvise(const wxString& item)
|
||||
@@ -489,8 +575,18 @@ bool wxDDEConnection::StartAdvise(const wxString& item)
|
||||
DWORD result;
|
||||
HSZ atom = DDEGetAtom(item);
|
||||
|
||||
return (DdeClientTransaction(NULL, 0, (HCONV) m_hConv,
|
||||
atom, CF_TEXT, XTYP_ADVSTART, 5000, &result) ? TRUE : FALSE);
|
||||
bool ok = DdeClientTransaction(NULL, 0,
|
||||
GetHConv(),
|
||||
atom, CF_TEXT,
|
||||
XTYP_ADVSTART,
|
||||
DDE_TIMEOUT,
|
||||
&result) != 0;
|
||||
if ( !ok )
|
||||
{
|
||||
DDELogError(_("Failed to establish an advise loop with DDE server"));
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool wxDDEConnection::StopAdvise(const wxString& item)
|
||||
@@ -498,71 +594,89 @@ bool wxDDEConnection::StopAdvise(const wxString& item)
|
||||
DWORD result;
|
||||
HSZ atom = DDEGetAtom(item);
|
||||
|
||||
return (DdeClientTransaction(NULL, 0, (HCONV) m_hConv,
|
||||
atom, CF_TEXT, XTYP_ADVSTOP, 5000, &result) ? TRUE : FALSE);
|
||||
bool ok = DdeClientTransaction(NULL, 0,
|
||||
GetHConv(),
|
||||
atom, CF_TEXT,
|
||||
XTYP_ADVSTOP,
|
||||
DDE_TIMEOUT,
|
||||
&result) != 0;
|
||||
if ( !ok )
|
||||
{
|
||||
DDELogError(_("Failed to terminate the advise loop with DDE server"));
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Calls that SERVER can make
|
||||
bool wxDDEConnection::Advise(const wxString& item, wxChar *data, int size, wxIPCFormat format)
|
||||
bool wxDDEConnection::Advise(const wxString& item,
|
||||
wxChar *data,
|
||||
int size,
|
||||
wxIPCFormat format)
|
||||
{
|
||||
if (size < 0)
|
||||
size = wxStrlen(data);
|
||||
|
||||
size ++;
|
||||
{
|
||||
size = wxStrlen(data) + 1;
|
||||
}
|
||||
|
||||
HSZ item_atom = DDEGetAtom(item);
|
||||
HSZ topic_atom = DDEGetAtom(m_topicName);
|
||||
m_sendingData = data;
|
||||
m_dataSize = size;
|
||||
m_dataType = format;
|
||||
return (DdePostAdvise(DDEIdInst, topic_atom, item_atom) != 0);
|
||||
|
||||
bool ok = DdePostAdvise(DDEIdInst, topic_atom, item_atom) != 0;
|
||||
if ( !ok )
|
||||
{
|
||||
DDELogError(_("Failed to send DDE advise notification"));
|
||||
}
|
||||
|
||||
bool wxDDEConnection::OnDisconnect(void)
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool wxDDEConnection::OnDisconnect()
|
||||
{
|
||||
delete this;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// _DDECallback
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define DDERETURN HDDEDATA
|
||||
|
||||
HDDEDATA EXPENTRY _EXPORT _DDECallback(
|
||||
WORD wType,
|
||||
HDDEDATA EXPENTRY _EXPORT
|
||||
_DDECallback(WORD wType,
|
||||
WORD wFmt,
|
||||
HCONV hConv,
|
||||
HSZ hsz1,
|
||||
HSZ hsz2,
|
||||
HDDEDATA hData,
|
||||
DWORD /* lData1 */,
|
||||
DWORD /* lData2 */)
|
||||
DWORD WXUNUSED(lData1),
|
||||
DWORD WXUNUSED(lData2))
|
||||
{
|
||||
switch (wType)
|
||||
{
|
||||
case XTYP_CONNECT:
|
||||
{
|
||||
wxChar topic_buf[100];
|
||||
wxChar server_buf[100];
|
||||
DdeQueryString(DDEIdInst, hsz1, (LPTSTR)topic_buf, WXSIZEOF(topic_buf),
|
||||
CP_WINANSI);
|
||||
DdeQueryString(DDEIdInst, hsz2, (LPTSTR)server_buf, WXSIZEOF(topic_buf),
|
||||
CP_WINANSI);
|
||||
wxDDEServer *server = DDEFindServer(server_buf);
|
||||
wxString topic = DDEStringFromAtom(hsz1),
|
||||
srv = DDEStringFromAtom(hsz2);
|
||||
wxDDEServer *server = DDEFindServer(srv);
|
||||
if (server)
|
||||
{
|
||||
wxDDEConnection *connection =
|
||||
(wxDDEConnection*) server->OnAcceptConnection(wxString(topic_buf));
|
||||
(wxDDEConnection*) server->OnAcceptConnection(topic);
|
||||
if (connection)
|
||||
{
|
||||
connection->m_server = server;
|
||||
server->GetConnections().Append(connection);
|
||||
connection->m_hConv = 0;
|
||||
connection->m_topicName = topic_buf;
|
||||
connection->m_topicName = topic;
|
||||
DDECurrentlyConnecting = connection;
|
||||
return (DDERETURN)(DWORD)TRUE;
|
||||
}
|
||||
}
|
||||
else return (DDERETURN)0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -574,7 +688,6 @@ DWORD /* lData2 */)
|
||||
DDECurrentlyConnecting = NULL;
|
||||
return (DDERETURN)(DWORD)TRUE;
|
||||
}
|
||||
else return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -586,7 +699,6 @@ DWORD /* lData2 */)
|
||||
DDEDeleteConnection(hConv); // Delete mapping: hConv => connection
|
||||
return (DDERETURN)(DWORD)TRUE;
|
||||
}
|
||||
else return (DDERETURN)0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -596,14 +708,21 @@ DWORD /* lData2 */)
|
||||
|
||||
if (connection)
|
||||
{
|
||||
DWORD len = DdeGetData(hData, (LPBYTE)(connection->m_bufPtr), connection->m_bufSize, 0);
|
||||
DWORD len = DdeGetData(hData,
|
||||
(LPBYTE)connection->m_bufPtr,
|
||||
connection->m_bufSize,
|
||||
0);
|
||||
DdeFreeDataHandle(hData);
|
||||
if (connection->OnExecute(connection->m_topicName, connection->m_bufPtr, (int)len, (wxIPCFormat) wFmt))
|
||||
if ( connection->OnExecute(connection->m_topicName,
|
||||
connection->m_bufPtr,
|
||||
(int)len,
|
||||
(wxIPCFormat) wFmt) )
|
||||
{
|
||||
return (DDERETURN)(DWORD)DDE_FACK;
|
||||
else
|
||||
}
|
||||
}
|
||||
|
||||
return (DDERETURN)DDE_FNOTPROCESSED;
|
||||
} else return (DDERETURN)DDE_FNOTPROCESSED;
|
||||
break;
|
||||
}
|
||||
|
||||
case XTYP_REQUEST:
|
||||
@@ -612,21 +731,28 @@ DWORD /* lData2 */)
|
||||
|
||||
if (connection)
|
||||
{
|
||||
wxChar item_name[200];
|
||||
DdeQueryString(DDEIdInst, hsz2, (LPTSTR)item_name, WXSIZEOF(item_name),
|
||||
CP_WINANSI);
|
||||
wxString item_name = DDEStringFromAtom(hsz2);
|
||||
|
||||
int user_size = -1;
|
||||
char *data = connection->OnRequest(connection->m_topicName, wxString(item_name), &user_size, (wxIPCFormat) wFmt);
|
||||
char *data = connection->OnRequest(connection->m_topicName,
|
||||
item_name,
|
||||
&user_size,
|
||||
(wxIPCFormat) wFmt);
|
||||
if (data)
|
||||
{
|
||||
if (user_size < 0) user_size = strlen(data);
|
||||
if (user_size < 0)
|
||||
user_size = wxStrlen(data) + 1;
|
||||
|
||||
HDDEDATA handle = DdeCreateDataHandle(DDEIdInst,
|
||||
(LPBYTE)data, user_size + 1, 0, hsz2, wFmt, 0);
|
||||
(LPBYTE)data,
|
||||
user_size,
|
||||
0,
|
||||
hsz2,
|
||||
wFmt,
|
||||
0);
|
||||
return (DDERETURN)handle;
|
||||
} else return (DDERETURN)0;
|
||||
} else return (DDERETURN)0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -636,15 +762,26 @@ DWORD /* lData2 */)
|
||||
|
||||
if (connection)
|
||||
{
|
||||
wxChar item_name[200];
|
||||
DdeQueryString(DDEIdInst, hsz2, (LPTSTR)item_name, WXSIZEOF(item_name),
|
||||
CP_WINANSI);
|
||||
DWORD len = DdeGetData(hData, (LPBYTE)(connection->m_bufPtr), connection->m_bufSize, 0);
|
||||
wxString item_name = DDEStringFromAtom(hsz2);
|
||||
|
||||
DWORD len = DdeGetData(hData,
|
||||
(LPBYTE)connection->m_bufPtr,
|
||||
connection->m_bufSize,
|
||||
0);
|
||||
DdeFreeDataHandle(hData);
|
||||
connection->OnPoke(connection->m_topicName, wxString(item_name), connection->m_bufPtr, (int)len, (wxIPCFormat) wFmt);
|
||||
return (DDERETURN)(DWORD)DDE_FACK;
|
||||
} else return (DDERETURN)DDE_FNOTPROCESSED;
|
||||
break;
|
||||
|
||||
connection->OnPoke(connection->m_topicName,
|
||||
item_name,
|
||||
connection->m_bufPtr,
|
||||
(int)len,
|
||||
(wxIPCFormat) wFmt);
|
||||
|
||||
return (DDERETURN)DDE_FACK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (DDERETURN)DDE_FNOTPROCESSED;
|
||||
}
|
||||
}
|
||||
|
||||
case XTYP_ADVSTART:
|
||||
@@ -653,12 +790,12 @@ DWORD /* lData2 */)
|
||||
|
||||
if (connection)
|
||||
{
|
||||
wxChar item_name[200];
|
||||
DdeQueryString(DDEIdInst, hsz2, (LPTSTR)item_name, WXSIZEOF(item_name),
|
||||
CP_WINANSI);
|
||||
wxString item_name = DDEStringFromAtom(hsz2);
|
||||
|
||||
return (DDERETURN)connection->
|
||||
OnStartAdvise(connection->m_topicName, item_name);
|
||||
}
|
||||
|
||||
return (DDERETURN)(DWORD)connection->OnStartAdvise(connection->m_topicName, wxString(item_name));
|
||||
} else return (DDERETURN)0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -668,11 +805,12 @@ DWORD /* lData2 */)
|
||||
|
||||
if (connection)
|
||||
{
|
||||
wxChar item_name[200];
|
||||
DdeQueryString(DDEIdInst, hsz2, (LPTSTR)item_name, WXSIZEOF(item_name),
|
||||
CP_WINANSI);
|
||||
return (DDERETURN)(DWORD)connection->OnStopAdvise(connection->m_topicName, wxString(item_name));
|
||||
} else return (DDERETURN)0;
|
||||
wxString item_name = DDEStringFromAtom(hsz2);
|
||||
|
||||
return (DDERETURN)connection->
|
||||
OnStopAdvise(connection->m_topicName, item_name);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -682,12 +820,22 @@ DWORD /* lData2 */)
|
||||
|
||||
if (connection && connection->m_sendingData)
|
||||
{
|
||||
HDDEDATA data = DdeCreateDataHandle(DDEIdInst,
|
||||
HDDEDATA data = DdeCreateDataHandle
|
||||
(
|
||||
DDEIdInst,
|
||||
(LPBYTE)connection->m_sendingData,
|
||||
connection->m_dataSize, 0, hsz2, connection->m_dataType, 0);
|
||||
connection->m_dataSize,
|
||||
0,
|
||||
hsz2,
|
||||
connection->m_dataType,
|
||||
0
|
||||
);
|
||||
|
||||
connection->m_sendingData = NULL;
|
||||
|
||||
return (DDERETURN)data;
|
||||
} else return (DDERETURN)NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -697,27 +845,38 @@ DWORD /* lData2 */)
|
||||
|
||||
if (connection)
|
||||
{
|
||||
wxChar item_name[200];
|
||||
DdeQueryString(DDEIdInst, hsz2, (LPTSTR)item_name, WXSIZEOF(item_name),
|
||||
CP_WINANSI);
|
||||
wxString item_name = DDEStringFromAtom(hsz2);
|
||||
|
||||
DWORD len = DdeGetData(hData, (LPBYTE)(connection->m_bufPtr), connection->m_bufSize, 0);
|
||||
DWORD len = DdeGetData(hData,
|
||||
(LPBYTE)connection->m_bufPtr,
|
||||
connection->m_bufSize,
|
||||
0);
|
||||
DdeFreeDataHandle(hData);
|
||||
if (connection->OnAdvise(connection->m_topicName, wxString(item_name), connection->m_bufPtr, (int)len, (wxIPCFormat) wFmt))
|
||||
if ( connection->OnAdvise(connection->m_topicName,
|
||||
item_name,
|
||||
connection->m_bufPtr,
|
||||
(int)len,
|
||||
(wxIPCFormat) wFmt) )
|
||||
{
|
||||
return (DDERETURN)(DWORD)DDE_FACK;
|
||||
else
|
||||
}
|
||||
}
|
||||
|
||||
return (DDERETURN)DDE_FNOTPROCESSED;
|
||||
} else return (DDERETURN)DDE_FNOTPROCESSED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
return (DDERETURN)0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// DDE strings and atoms
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Atom table stuff
|
||||
static HSZ DDEAddAtom(const wxString& string)
|
||||
{
|
||||
HSZ atom = DdeCreateStringHandle(DDEIdInst, WXSTRINGCAST string, CP_WINANSI);
|
||||
HSZ atom = DDEAtomFromString(string);
|
||||
wxAtomTable.Append(string, (wxObject *)atom);
|
||||
return atom;
|
||||
}
|
||||
@@ -734,70 +893,114 @@ static HSZ DDEGetAtom(const wxString& string)
|
||||
}
|
||||
}
|
||||
|
||||
void DDEPrintError(void)
|
||||
// atom <-> strings
|
||||
static HSZ DDEAtomFromString(const wxString& s)
|
||||
{
|
||||
wxChar *err = NULL;
|
||||
switch (DdeGetLastError(DDEIdInst))
|
||||
wxASSERT_MSG( DDEIdInst, _T("DDE not initialized") );
|
||||
|
||||
HSZ hsz = DdeCreateStringHandle(DDEIdInst, s, DDE_CP);
|
||||
if ( !hsz )
|
||||
{
|
||||
DDELogError(_("Failed to create DDE string"));
|
||||
}
|
||||
|
||||
return hsz;
|
||||
}
|
||||
|
||||
static wxString DDEStringFromAtom(HSZ hsz)
|
||||
{
|
||||
// all DDE strings are normally limited to 255 bytes
|
||||
static const size_t len = 256;
|
||||
|
||||
wxString s;
|
||||
(void)DdeQueryString(DDEIdInst, hsz, s.GetWriteBuf(len), len, DDE_CP);
|
||||
s.UngetWriteBuf();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// error handling
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static void DDELogError(const wxString& s, UINT error)
|
||||
{
|
||||
if ( !error )
|
||||
{
|
||||
error = DdeGetLastError(DDEIdInst);
|
||||
}
|
||||
|
||||
wxLogError(s + _T(": ") + DDEGetErrorMsg(error));
|
||||
}
|
||||
|
||||
static wxString DDEGetErrorMsg(UINT error)
|
||||
{
|
||||
wxString err;
|
||||
switch ( error )
|
||||
{
|
||||
case DMLERR_NO_ERROR:
|
||||
err = _("no DDE error.");
|
||||
break;
|
||||
|
||||
case DMLERR_ADVACKTIMEOUT:
|
||||
err = wxT("A request for a synchronous advise transaction has timed out.");
|
||||
err = _("a request for a synchronous advise transaction has timed out.");
|
||||
break;
|
||||
case DMLERR_BUSY:
|
||||
err = wxT("The response to the transaction caused the DDE_FBUSY bit to be set.");
|
||||
err = _("the response to the transaction caused the DDE_FBUSY bit to be set.");
|
||||
break;
|
||||
case DMLERR_DATAACKTIMEOUT:
|
||||
err = wxT("A request for a synchronous data transaction has timed out.");
|
||||
err = _("a request for a synchronous data transaction has timed out.");
|
||||
break;
|
||||
case DMLERR_DLL_NOT_INITIALIZED:
|
||||
err = wxT("A DDEML function was called without first calling the DdeInitialize function,\n\ror an invalid instance identifier\n\rwas passed to a DDEML function.");
|
||||
err = _("a DDEML function was called without first calling the DdeInitialize function,\n\ror an invalid instance identifier\n\rwas passed to a DDEML function.");
|
||||
break;
|
||||
case DMLERR_DLL_USAGE:
|
||||
err = wxT("An application initialized as APPCLASS_MONITOR has\n\rattempted to perform a DDE transaction,\n\ror an application initialized as APPCMD_CLIENTONLY has \n\rattempted to perform server transactions.");
|
||||
err = _("an application initialized as APPCLASS_MONITOR has\n\rattempted to perform a DDE transaction,\n\ror an application initialized as APPCMD_CLIENTONLY has \n\rattempted to perform server transactions.");
|
||||
break;
|
||||
case DMLERR_EXECACKTIMEOUT:
|
||||
err = wxT("A request for a synchronous execute transaction has timed out.");
|
||||
err = _("a request for a synchronous execute transaction has timed out.");
|
||||
break;
|
||||
case DMLERR_INVALIDPARAMETER:
|
||||
err = wxT("A parameter failed to be validated by the DDEML.");
|
||||
err = _("a parameter failed to be validated by the DDEML.");
|
||||
break;
|
||||
case DMLERR_LOW_MEMORY:
|
||||
err = wxT("A DDEML application has created a prolonged race condition.");
|
||||
err = _("a DDEML application has created a prolonged race condition.");
|
||||
break;
|
||||
case DMLERR_MEMORY_ERROR:
|
||||
err = wxT("A memory allocation failed.");
|
||||
err = _("a memory allocation failed.");
|
||||
break;
|
||||
case DMLERR_NO_CONV_ESTABLISHED:
|
||||
err = wxT("A client's attempt to establish a conversation has failed.");
|
||||
err = _("a client's attempt to establish a conversation has failed.");
|
||||
break;
|
||||
case DMLERR_NOTPROCESSED:
|
||||
err = wxT("A transaction failed.");
|
||||
err = _("a transaction failed.");
|
||||
break;
|
||||
case DMLERR_POKEACKTIMEOUT:
|
||||
err = wxT("A request for a synchronous poke transaction has timed out.");
|
||||
err = _("a request for a synchronous poke transaction has timed out.");
|
||||
break;
|
||||
case DMLERR_POSTMSG_FAILED:
|
||||
err = wxT("An internal call to the PostMessage function has failed. ");
|
||||
err = _("an internal call to the PostMessage function has failed. ");
|
||||
break;
|
||||
case DMLERR_REENTRANCY:
|
||||
err = wxT("Reentrancy problem.");
|
||||
err = _("reentrancy problem.");
|
||||
break;
|
||||
case DMLERR_SERVER_DIED:
|
||||
err = wxT("A server-side transaction was attempted on a conversation\n\rthat was terminated by the client, or the server\n\rterminated before completing a transaction.");
|
||||
err = _("a server-side transaction was attempted on a conversation\n\rthat was terminated by the client, or the server\n\rterminated before completing a transaction.");
|
||||
break;
|
||||
case DMLERR_SYS_ERROR:
|
||||
err = wxT("An internal error has occurred in the DDEML.");
|
||||
err = _("an internal error has occurred in the DDEML.");
|
||||
break;
|
||||
case DMLERR_UNADVACKTIMEOUT:
|
||||
err = wxT("A request to end an advise transaction has timed out.");
|
||||
err = _("a request to end an advise transaction has timed out.");
|
||||
break;
|
||||
case DMLERR_UNFOUND_QUEUE_ID:
|
||||
err = wxT("An invalid transaction identifier was passed to a DDEML function.\n\rOnce the application has returned from an XTYP_XACT_COMPLETE callback,\n\rthe transaction identifier for that callback is no longer valid.");
|
||||
err = _("an invalid transaction identifier was passed to a DDEML function.\n\rOnce the application has returned from an XTYP_XACT_COMPLETE callback,\n\rthe transaction identifier for that callback is no longer valid.");
|
||||
break;
|
||||
default:
|
||||
err = wxT("Unrecognised error type.");
|
||||
break;
|
||||
err.Printf(_("Unknown DDE error %08x"), error);
|
||||
}
|
||||
MessageBox((HWND) NULL, (LPCTSTR)err, wxT("DDE Error"), MB_OK | MB_ICONINFORMATION);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -88,6 +88,7 @@ wxDirDialog::wxDirDialog(wxWindow *parent,
|
||||
m_message = message;
|
||||
m_parent = parent;
|
||||
m_path = defaultPath;
|
||||
m_path.Replace(_T("/"), _T("\\")); // SHBrowseForFolder doesn't like '/'s
|
||||
}
|
||||
|
||||
int wxDirDialog::ShowModal()
|
||||
|
@@ -1420,9 +1420,16 @@ bool wxListCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
|
||||
}
|
||||
|
||||
// else translate it into wxEVT_COMMAND_LIST_ITEM_ACTIVATED event
|
||||
// if it happened on an item (and not on empty place)
|
||||
{
|
||||
eventType = wxEVT_COMMAND_LIST_ITEM_ACTIVATED;
|
||||
NM_LISTVIEW* hdr = (NM_LISTVIEW*)lParam;
|
||||
if ( hdr->iItem == -1 )
|
||||
{
|
||||
// not on item
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
eventType = wxEVT_COMMAND_LIST_ITEM_ACTIVATED;
|
||||
event.m_itemIndex = hdr->iItem;
|
||||
}
|
||||
break;
|
||||
|
@@ -102,8 +102,6 @@ long wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
||||
}
|
||||
break;
|
||||
|
||||
// VZ: I will remove (or change) this soon... (15.11.99)
|
||||
#if 0
|
||||
case WM_ERASEBKGND:
|
||||
// prevent wxControl from processing this message because it will
|
||||
// erase the background incorrectly and there is no way for us to
|
||||
@@ -112,7 +110,6 @@ long wxStaticBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
|
||||
// without painting over other controls - and if we don't,
|
||||
// wxControl still gets it)
|
||||
return MSWDefWindowProc(nMsg, wParam, lParam);
|
||||
#endif
|
||||
}
|
||||
|
||||
return wxControl::MSWWindowProc(nMsg, wParam, lParam);
|
||||
|
@@ -74,6 +74,8 @@
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wx/dde.h" // for WX_DDE hack in wxExecute
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// constants
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -177,9 +179,78 @@ LRESULT APIENTRY _EXPORT wxExecuteWindowCbk(HWND hWnd, UINT message,
|
||||
}
|
||||
#endif
|
||||
|
||||
long wxExecute(const wxString& command, bool sync, wxProcess *handler)
|
||||
long wxExecute(const wxString& cmd, bool sync, wxProcess *handler)
|
||||
{
|
||||
wxCHECK_MSG( !!command, 0, wxT("empty command in wxExecute") );
|
||||
wxCHECK_MSG( !!cmd, 0, wxT("empty command in wxExecute") );
|
||||
|
||||
// DDE hack: this is really not pretty, but we need to allow this for
|
||||
// transparent handling of DDE servers in wxMimeTypesManager. Usually it
|
||||
// returns the command which should be run to view/open/... a file of the
|
||||
// given type. Sometimes, however, this command just launches the server
|
||||
// and an additional DDE request must be made to really open the file. To
|
||||
// keep all this well hidden from the application, we allow a special form
|
||||
// of command: WX_DDE:<command>:DDE_SERVER:DDE_TOPIC:DDE_COMMAND in which
|
||||
// case we execute just <command> and process the rest below
|
||||
wxString command, ddeServer, ddeTopic, ddeCommand;
|
||||
static const size_t lenDdePrefix = 7; // strlen("WX_DDE:")
|
||||
if ( cmd.Left(lenDdePrefix) == _T("WX_DDE#") )
|
||||
{
|
||||
const wxChar *p = cmd.c_str() + 7;
|
||||
while ( *p && *p != _T('#') )
|
||||
{
|
||||
command += *p++;
|
||||
}
|
||||
|
||||
if ( *p )
|
||||
{
|
||||
// skip '#'
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG(_T("invalid WX_DDE command in wxExecute"));
|
||||
}
|
||||
|
||||
while ( *p && *p != _T('#') )
|
||||
{
|
||||
ddeServer += *p++;
|
||||
}
|
||||
|
||||
if ( *p )
|
||||
{
|
||||
// skip '#'
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG(_T("invalid WX_DDE command in wxExecute"));
|
||||
}
|
||||
|
||||
while ( *p && *p != _T('#') )
|
||||
{
|
||||
ddeTopic += *p++;
|
||||
}
|
||||
|
||||
if ( *p )
|
||||
{
|
||||
// skip '#'
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG(_T("invalid WX_DDE command in wxExecute"));
|
||||
}
|
||||
|
||||
while ( *p )
|
||||
{
|
||||
ddeCommand += *p++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no DDE
|
||||
command = cmd;
|
||||
}
|
||||
|
||||
#if defined(__WIN32__) && !defined(__TWIN32__)
|
||||
// the old code is disabled because we really need a process handle
|
||||
@@ -237,6 +308,7 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
|
||||
|
||||
return result;
|
||||
#else // 1
|
||||
|
||||
// create the process
|
||||
STARTUPINFO si;
|
||||
wxZeroMemory(si);
|
||||
@@ -338,6 +410,20 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
|
||||
return pi.dwProcessId;
|
||||
}
|
||||
|
||||
// second part of DDE hack: now establish the DDE conversation with the
|
||||
// just launched process
|
||||
if ( !!ddeServer )
|
||||
{
|
||||
wxDDEClient client;
|
||||
wxConnectionBase *conn = client.MakeConnection(_T(""),
|
||||
ddeServer,
|
||||
ddeTopic);
|
||||
if ( !conn || !conn->Execute(ddeCommand) )
|
||||
{
|
||||
wxLogError(_("Couldn't launch DDE server '%s'."), command.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if ( !sync )
|
||||
{
|
||||
// clean up will be done when the process terminates
|
||||
|
Reference in New Issue
Block a user