// Name: client.cpp
// Purpose: DDE sample: client
// Author: Julian Smart
-// Modified by:
+// Modified by: Jurgen Doornik
// Created: 25/01/99
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Settings common to both executables: determines whether
// we're using TCP/IP or real DDE.
-#include "ddesetup.h"
+#include "ipcsetup.h"
#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) || defined(__WXMAC__)
#include "mondrian.xpm"
#endif
+#include "wx/datetime.h"
#include "client.h"
// ----------------------------------------------------------------------------
IMPLEMENT_APP(MyApp)
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
- EVT_MENU(CLIENT_QUIT, MyFrame::OnExit)
- EVT_MENU(CLIENT_EXECUTE, MyFrame::OnExecute)
- EVT_MENU(CLIENT_POKE, MyFrame::OnPoke)
- EVT_MENU(CLIENT_REQUEST, MyFrame::OnRequest)
+ EVT_MENU(wxID_EXIT, MyFrame::OnExit)
+ EVT_CLOSE( MyFrame::OnClose )
+ EVT_BUTTON( ID_START, MyFrame::OnStart )
+ EVT_CHOICE( ID_SERVERNAME, MyFrame::OnServername )
+ EVT_CHOICE( ID_HOSTNAME, MyFrame::OnHostname )
+ EVT_CHOICE( ID_TOPIC, MyFrame::OnTopic )
+ EVT_BUTTON( ID_DISCONNECT, MyFrame::OnDisconnect )
+ EVT_BUTTON( ID_STARTADVISE, MyFrame::OnStartAdvise )
+ EVT_BUTTON( ID_STOPADVISE, MyFrame::OnStopAdvise )
+ EVT_BUTTON( ID_POKE, MyFrame::OnPoke )
+ EVT_BUTTON( ID_EXECUTE, MyFrame::OnExecute )
+ EVT_BUTTON( ID_REQUEST, MyFrame::OnRequest )
END_EVENT_TABLE()
// ----------------------------------------------------------------------------
// globals
// ----------------------------------------------------------------------------
-wxListBox *the_list = NULL;
-
-MyConnection *the_connection = NULL;
-MyClient *my_client;
-
// ============================================================================
// implementation
// ============================================================================
// main frame
bool MyApp::OnInit()
{
- // service name (DDE classes) or port number (TCP/IP based classes)
- wxString service = IPC_SERVICE;
-
- // ignored under DDE, host name in TCP/IP based classes
- wxString hostName = _T("localhost");
-
- if (argc > 1)
- service = argv[1];
- if (argc > 2)
- hostName = argv[2];
-
- // Create a new client
- my_client = new MyClient;
-
- // suppress the log messages from MakeConnection()
- {
- wxLogNull nolog;
- the_connection = (MyConnection *)
- my_client->MakeConnection(hostName, service, IPC_TOPIC);
-
- while ( !the_connection )
- {
- if ( wxMessageBox(_T("Failed to make connection to server.\nRetry?"),
- _T("Client Demo Error"),
- wxICON_ERROR | wxYES_NO | wxCANCEL ) != wxYES )
- {
- // no server
- return false;
- }
-
- the_connection = (MyConnection *)my_client->MakeConnection(hostName, service, _T("IPC TEST"));
- }
- }
-
- if (!the_connection->StartAdvise(IPC_ADVISE_NAME))
- wxMessageBox(_T("StartAdvise failed"), _T("Client Demo Error"));
-
// Create the main frame window
- (new MyFrame(NULL, _T("Client")))->Show(true);
+ m_frame = new MyFrame(NULL, _T("Client"));
+ m_frame->Show(true);
return true;
}
int MyApp::OnExit()
{
- // will delete the connection too
- // Update: Seems it didn't delete the_connection, because there's a leak.
- // Deletion is now explicitly done a few lines up.
- // another Update: in fact it's because OnDisconnect should delete it, but
- // it wasn't
- delete my_client;
-
-
return 0;
}
// Define my frame constructor
MyFrame::MyFrame(wxFrame *frame, const wxString& title)
- : wxFrame(frame, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200))
+ : wxFrame(frame, wxID_ANY, title, wxDefaultPosition, wxSize(400, 300))
{
// Give it an icon
SetIcon(wxICON(mondrian));
// Make a menubar
wxMenu *file_menu = new wxMenu;
- file_menu->Append(CLIENT_EXECUTE, _T("&Execute\tCtrl-E"));
- file_menu->Append(CLIENT_REQUEST, _T("&Request\tCtrl-R"));
- file_menu->Append(CLIENT_POKE, _T("&Poke\tCtrl-P"));
- file_menu->Append(CLIENT_QUIT, _T("&Quit\tCtrl-Q"));
+ file_menu->Append(wxID_EXIT, _T("&Quit\tCtrl-Q"));
wxMenuBar *menu_bar = new wxMenuBar;
// Associate the menu bar with the frame
SetMenuBar(menu_bar);
- // Make a listbox which shows the choices made in the server
- the_list = new wxListBox(this, CLIENT_LISTBOX, wxPoint(5, 5));
- the_list->Append(_T("Apple"));
- the_list->Append(_T("Pear"));
- the_list->Append(_T("Orange"));
- the_list->Append(_T("Banana"));
- the_list->Append(_T("Fruit"));
+ // set a dialog background
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
+
+ // add the controls to the frame
+ wxString strs4[] =
+ {
+ IPC_SERVICE, _T("...")
+ };
+ wxString strs5[] =
+ {
+ IPC_HOST, _T("...")
+ };
+ wxString strs6[] =
+ {
+ IPC_TOPIC, _T("...")
+ };
+
+ wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer *item1 = new wxBoxSizer( wxHORIZONTAL );
+
+ wxGridSizer *item2 = new wxGridSizer( 4, 0, 0 );
+
+ wxButton *item3 = new wxButton( this, ID_START, wxT("Connect to server"), wxDefaultPosition, wxDefaultSize, 0 );
+ item2->Add( item3, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxChoice *item5 = new wxChoice( this, ID_HOSTNAME, wxDefaultPosition, wxSize(100,-1), 2, strs5, 0 );
+ item2->Add( item5, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ wxChoice *item4 = new wxChoice( this, ID_SERVERNAME, wxDefaultPosition, wxSize(100,-1), 2, strs4, 0 );
+ item2->Add( item4, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxChoice *item6 = new wxChoice( this, ID_TOPIC, wxDefaultPosition, wxSize(100,-1), 2, strs6, 0 );
+ item2->Add( item6, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ wxButton *item7 = new wxButton( this, ID_DISCONNECT, wxT("Disconnect "), wxDefaultPosition, wxDefaultSize, 0 );
+ item2->Add( item7, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ wxButton *item8 = new wxButton( this, ID_STARTADVISE, wxT("StartAdvise"), wxDefaultPosition, wxDefaultSize, 0 );
+ item2->Add( item8, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxButton *item9 = new wxButton( this, ID_STOPADVISE, wxT("StopAdvise"), wxDefaultPosition, wxDefaultSize, 0 );
+ item2->Add( item9, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ wxButton *item10 = new wxButton( this, ID_EXECUTE, wxT("Execute"), wxDefaultPosition, wxDefaultSize, 0 );
+ item2->Add( item10, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ wxButton *item11 = new wxButton( this, ID_POKE, wxT("Poke"), wxDefaultPosition, wxDefaultSize, 0 );
+ item2->Add( item11, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ wxButton *item12 = new wxButton( this, ID_REQUEST, wxT("Request"), wxDefaultPosition, wxDefaultSize, 0 );
+ item2->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ item1->Add( item2, 1, wxALIGN_CENTER|wxALL, 5 );
+
+ item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxStaticBox *item14 = new wxStaticBox( this, -1, wxT("Client log") );
+ wxStaticBoxSizer *item13 = new wxStaticBoxSizer( item14, wxVERTICAL );
+
+ wxTextCtrl *item15 = new wxTextCtrl( this, ID_LOG, wxT(""), wxDefaultPosition, wxSize(500,140), wxTE_MULTILINE );
+ item13->Add( item15, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ item0->Add( item13, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ this->SetSizer( item0 );
+ item0->SetSizeHints( this );
+
+ // status
+ m_client = NULL;
+ GetServername()->SetSelection(0);
+ GetHostname()->SetSelection(0);
+ GetTopic()->SetSelection(0);
+ wxLogTextCtrl *logWindow = new wxLogTextCtrl(GetLog());
+ delete wxLog::SetActiveTarget(logWindow);
+ wxLogMessage(_T("Click on Connect to connect to the server"));
+ Enable();
+}
+
+void MyFrame::Enable()
+{
+ GetStart()->Enable(m_client == NULL);
+ GetServername()->Enable(m_client == NULL);
+ GetHostname()->Enable(m_client == NULL);
+ GetTopic()->Enable(m_client == NULL);
+ GetDisconnect()->Enable(m_client && m_client->IsConnected() != NULL);
+ GetStartAdvise()->Enable(m_client && m_client->IsConnected() != NULL);
+ GetStopAdvise()->Enable(m_client && m_client->IsConnected() != NULL);
+ GetExecute()->Enable(m_client && m_client->IsConnected() != NULL);
+ GetPoke()->Enable(m_client && m_client->IsConnected() != NULL);
+ GetRequest()->Enable(m_client && m_client->IsConnected() != NULL);
+}
+
+void MyFrame::OnClose(wxCloseEvent& event)
+{
+ if (m_client)
+ {
+ delete m_client;
+ m_client = NULL;
+ }
+ event.Skip();
+}
+
+void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
+{
+ Close();
+}
+
+void MyFrame::OnStart(wxCommandEvent& WXUNUSED(event))
+{
+ // Connect to the client
+ wxString servername = GetServername()->GetStringSelection();
+ wxString hostname = GetHostname()->GetStringSelection();
+ wxString topic = GetTopic()->GetStringSelection();
+
+ m_client = new MyClient;
+ bool retval = m_client->Connect(hostname, servername, topic);
+
+ wxLogMessage(_T("Client host=\"%s\" port=\"%s\" topic=\"%s\" %s"),
+ hostname.c_str(), servername.c_str(), topic.c_str(),
+ retval ? _T("connected") : _T("failed to connect"));
+
+ if (!retval)
+ {
+ delete m_client;
+ m_client = NULL;
+ }
+ Enable();
+}
+
+void MyFrame::OnServername( wxCommandEvent& WXUNUSED(event) )
+{
+ if (GetServername()->GetStringSelection() == _T("..."))
+ {
+ wxString s = wxGetTextFromUser(_T("Specify the name of the server"),
+ _T("Server Name"), _(""), this);
+ if (!s.IsEmpty() && s != IPC_SERVICE)
+ {
+ GetServername()->Insert(s, 0);
+ GetServername()->SetSelection(0);
+ }
+ }
+}
+
+void MyFrame::OnHostname( wxCommandEvent& WXUNUSED(event) )
+{
+ if (GetHostname()->GetStringSelection() == _T("..."))
+ {
+ wxString s = wxGetTextFromUser(_T("Specify the name of the host (ignored under DDE)"),
+ _T("Host Name"), _(""), this);
+ if (!s.IsEmpty() && s != IPC_HOST)
+ {
+ GetHostname()->Insert(s, 0);
+ GetHostname()->SetSelection(0);
+ }
+ }
+}
+
+void MyFrame::OnTopic( wxCommandEvent& WXUNUSED(event) )
+{
+ if (GetTopic()->GetStringSelection() == _T("..."))
+ {
+ wxString s = wxGetTextFromUser(_T("Specify the name of the topic"),
+ _T("Topic Name"), _(""), this);
+ if (!s.IsEmpty() && s != IPC_TOPIC)
+ {
+ GetTopic()->Insert(s, 0);
+ GetTopic()->SetSelection(0);
+ }
+ }
+}
+
+void MyFrame::OnDisconnect(wxCommandEvent& WXUNUSED(event))
+{
+ Disconnect();
+}
+
+void MyFrame::Disconnect()
+{
+ delete m_client;
+ m_client = NULL;
+ Enable();
+}
+
+void MyFrame::OnStartAdvise(wxCommandEvent& WXUNUSED(event))
+{
+ m_client->GetConnection()->StartAdvise(_T("something"));
+}
+
+void MyFrame::OnStopAdvise(wxCommandEvent& WXUNUSED(event))
+{
+ m_client->GetConnection()->StopAdvise(_T("something"));
}
void MyFrame::OnExecute(wxCommandEvent& WXUNUSED(event))
{
- if (the_connection)
- if (!the_connection->Execute(_T("Hello from the client!")))
- wxMessageBox(_T("Execute failed"), _T("Client Demo Error"));
+ if (m_client->IsConnected())
+ {
+ wxString s = _T("Date");
+
+ m_client->GetConnection()->Execute((wxChar *)s.c_str());
+ m_client->GetConnection()->Execute((wxChar *)s.c_str(), (s.Length() + 1) * sizeof(wxChar));
+#if wxUSE_DDE_FOR_IPC
+ wxLogMessage(_T("DDE Execute can only be used to send text strings, not arbitrary data.\nThe type argument will be ignored, text truncated, converted to Unicode and null terminated."));
+#endif
+ char bytes[3];
+ bytes[0] = '1'; bytes[1] = '2'; bytes[2] = '3';
+ m_client->GetConnection()->Execute((wxChar *)bytes, 3, wxIPC_PRIVATE);
+ }
}
void MyFrame::OnPoke(wxCommandEvent& WXUNUSED(event))
{
- if (the_connection)
- if (!the_connection->Poke(_T("An item"), _T("Some data to poke at the server!")))
- wxMessageBox(_T("Poke failed"), _T("Client Demo Error"));
+ if (m_client->IsConnected())
+ {
+ wxString s = wxDateTime::Now().Format();
+ m_client->GetConnection()->Poke(_T("Date"), (wxChar *)s.c_str());
+ s = wxDateTime::Now().FormatTime() + _T(" ") + wxDateTime::Now().FormatDate();
+ m_client->GetConnection()->Poke(_T("Date"), (wxChar *)s.c_str(), (s.Length() + 1) * sizeof(wxChar));
+ char bytes[3];
+ bytes[0] = '1'; bytes[1] = '2'; bytes[2] = '3';
+ m_client->GetConnection()->Poke(_T("bytes[3]"), (wxChar *)bytes, 3, wxIPC_PRIVATE);
+ }
}
void MyFrame::OnRequest(wxCommandEvent& WXUNUSED(event))
{
- if (the_connection)
+ if (m_client->IsConnected())
{
- wxChar *data = the_connection->Request(_T("An item"));
- if (data)
- wxMessageBox(data, _T("Client: Request"), wxOK);
- else
- wxMessageBox(_T("Request failed"), _T("Client Demo Error"));
+ int size;
+ m_client->GetConnection()->Request(_T("Date"));
+ m_client->GetConnection()->Request(_T("Date+len"), &size);
+ m_client->GetConnection()->Request(_T("bytes[3]"), &size, wxIPC_PRIVATE);
}
}
-void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
+// ----------------------------------------------------------------------------
+// MyClient
+// ----------------------------------------------------------------------------
+MyClient::MyClient() : wxClient()
{
- Close();
+ m_connection = NULL;
+}
+
+bool MyClient::Connect(const wxString& sHost, const wxString& sService, const wxString& sTopic)
+{
+ // suppress the log messages from MakeConnection()
+ wxLogNull nolog;
+
+ m_connection = (MyConnection *)MakeConnection(sHost, sService, sTopic);
+ return m_connection != NULL;
}
wxConnectionBase *MyClient::OnMakeConnection()
return new MyConnection;
}
-bool MyConnection::OnAdvise(const wxString& WXUNUSED(topic), const wxString& WXUNUSED(item), wxChar *data, int WXUNUSED(size), wxIPCFormat WXUNUSED(format))
+void MyClient::Disconnect()
+{
+ if (m_connection)
+ {
+ m_connection->Disconnect();
+ delete m_connection;
+ m_connection = NULL;
+ wxGetApp().GetFrame()->Enable();
+ wxLogMessage(_T("Client disconnected from server"));
+ }
+}
+
+MyClient::~MyClient()
+{
+ Disconnect();
+}
+
+// ----------------------------------------------------------------------------
+// MyConnection
+// ----------------------------------------------------------------------------
+
+void MyConnection::Log(const wxString& command, const wxString& topic,
+ const wxString& item, wxChar *data, int size, wxIPCFormat format)
{
- if (the_list)
+ wxString s;
+ if (topic.IsEmpty() && item.IsEmpty())
+ s.Printf(_T("%s("), command);
+ else if (topic.IsEmpty())
+ s.Printf(_T("%s(item=\"%s\","), command, item);
+ else if (item.IsEmpty())
+ s.Printf(_T("%s(topic=\"%s\","), command, topic);
+ else
+ s.Printf(_T("%s(topic=\"%s\",item=\"%s\","), command, topic, item);
+
+ if (format == wxIPC_TEXT || format == wxIPC_UNICODETEXT)
+ wxLogMessage(_T("%s\"%s\",%d)"), s, data, size);
+ else if (format == wxIPC_PRIVATE)
{
- int n = the_list->FindString(data);
- if (n > wxNOT_FOUND)
- the_list->SetSelection(n);
+ if (size == 3)
+ {
+ char *bytes = (char *)data;
+ wxLogMessage(_T("%s'%c%c%c',%d)"), s, bytes[0], bytes[1], bytes[2], size);
+ }
+ else
+ wxLogMessage(_T("%s...,%d)"), s, size);
}
+ else if (format == wxIPC_INVALID)
+ wxLogMessage(_T("%s[invalid data],%d)"), s, size);
+}
+
+bool MyConnection::OnAdvise(const wxString& topic, const wxString& item, wxChar *data,
+ int size, wxIPCFormat format)
+{
+ Log(_T("OnAdvise"), topic, item, data, size, format);
return true;
}
bool MyConnection::OnDisconnect()
{
- // when connection is terminated, quit whole program
- wxWindow *win = wxTheApp->GetTopWindow();
- if ( win )
- win->Destroy();
+ wxLogMessage(_T("OnDisconnect()"));
+ wxGetApp().GetFrame()->Disconnect();
+ return true;
+}
+
+bool MyConnection::Execute(const wxChar *data, int size, wxIPCFormat format)
+{
+ Log(_T("Execute"), _T(""), _T(""), (wxChar *)data, size, format);
+ bool retval = wxConnection::Execute(data, size, format);
+ if (!retval)
+ wxLogMessage(_T("Execute failed!"));
+ return retval;
+}
- // delete self
- the_connection = NULL;
- return wxConnection::OnDisconnect();
+wxChar *MyConnection::Request(const wxString& item, int *size, wxIPCFormat format)
+{
+ wxChar *data = wxConnection::Request(item, size, format);
+ Log(_T("Request"), _T(""), item, data, size ? *size : -1, format);
+ return data;
+}
+
+bool MyConnection::Poke(const wxString& item, wxChar *data, int size, wxIPCFormat format)
+{
+ Log(_T("Poke"), _T(""), item, data, size, format);
+ return wxConnection::Poke(item, data, size, format);
}
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
+#define ID_START 10000
+#define ID_DISCONNECT 10001
+#define ID_STARTADVISE 10002
+#define ID_LOG 10003
+#define ID_SERVERNAME 10004
+#define ID_STOPADVISE 10005
+#define ID_POKE 10006
+#define ID_REQUEST 10007
+#define ID_EXECUTE 10008
+#define ID_TOPIC 10009
+#define ID_HOSTNAME 10010
+
// Define a new application
+class MyClient;
+class MyConnection;
+class MyFrame;
+
class MyApp: public wxApp
{
public:
virtual bool OnInit();
virtual int OnExit();
+ MyFrame *GetFrame() { return m_frame; };
+
+protected:
+ MyFrame *m_frame;
};
// Define a new frame
MyFrame(wxFrame *frame, const wxString& title);
void OnExit(wxCommandEvent& event);
+ void OnClose(wxCloseEvent& event);
+ void Enable();
+ void Disconnect();
+
+protected:
+ wxButton* GetStart() { return (wxButton*) FindWindow( ID_START ); }
+ wxChoice* GetServername() { return (wxChoice*) FindWindow( ID_SERVERNAME ); }
+ wxChoice* GetHostname() { return (wxChoice*) FindWindow( ID_HOSTNAME ); }
+ wxChoice* GetTopic() { return (wxChoice*) FindWindow( ID_TOPIC ); }
+ wxButton* GetDisconnect() { return (wxButton*) FindWindow( ID_DISCONNECT ); }
+ wxButton* GetStartAdvise() { return (wxButton*) FindWindow( ID_STARTADVISE ); }
+ wxButton* GetStopAdvise() { return (wxButton*) FindWindow( ID_STOPADVISE ); }
+ wxButton* GetRequest() { return (wxButton*) FindWindow( ID_REQUEST ); }
+ wxButton* GetPoke() { return (wxButton*) FindWindow( ID_POKE ); }
+ wxButton* GetExecute() { return (wxButton*) FindWindow( ID_EXECUTE ); }
+ wxTextCtrl* GetLog() { return (wxTextCtrl*) FindWindow( ID_LOG ); }
+
+ MyClient *m_client;
+
+ void OnStart( wxCommandEvent &event );
+ void OnServername( wxCommandEvent &event );
+ void OnHostname( wxCommandEvent &event );
+ void OnTopic( wxCommandEvent &event );
+ void OnDisconnect( wxCommandEvent &event );
+ void OnStartAdvise( wxCommandEvent &event );
+ void OnStopAdvise( wxCommandEvent &event );
void OnExecute(wxCommandEvent& event);
void OnPoke(wxCommandEvent& event);
void OnRequest(wxCommandEvent& event);
-private:
- wxPanel *panel;
-
+protected:
DECLARE_EVENT_TABLE()
};
class MyConnection: public wxConnection
{
public:
- bool OnAdvise(const wxString& topic, const wxString& item, wxChar *data, int size, wxIPCFormat format);
- bool OnDisconnect();
+ virtual bool Execute(const wxChar *data, int size = -1, wxIPCFormat format = wxIPC_TEXT);
+ virtual wxChar *Request(const wxString& item, int *size = NULL, wxIPCFormat format = wxIPC_TEXT);
+ virtual bool Poke(const wxString& item, wxChar *data, int size = -1, wxIPCFormat format = wxIPC_TEXT);
+ virtual bool OnAdvise(const wxString& topic, const wxString& item, wxChar *data, int size, wxIPCFormat format);
+ virtual bool OnDisconnect();
+protected:
+ void MyConnection::Log(const wxString& command, const wxString& topic,
+ const wxString& item, wxChar *data, int size, wxIPCFormat format);
};
class MyClient: public wxClient
{
public:
+ MyClient();
+ ~MyClient();
+ bool Connect(const wxString& sHost, const wxString& sService, const wxString& sTopic);
+ void Disconnect();
wxConnectionBase *OnMakeConnection();
+ bool IsConnected() { return m_connection != NULL; };
+ MyConnection *GetConnection() { return m_connection; };
+
+protected:
+ MyConnection *m_connection;
};
-#define CLIENT_QUIT wxID_EXIT
-#define CLIENT_EXECUTE 2
-#define CLIENT_REQUEST 3
-#define CLIENT_POKE 4
-#define CLIENT_LISTBOX 200
// Name: server.cpp
// Purpose: IPC sample: server
// Author: Julian Smart
-// Modified by:
+// Modified by: Jurgen Doornik
// Created: 25/01/99
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Settings common to both executables: determines whether
// we're using TCP/IP or real DDE.
-#include "ddesetup.h"
+#include "ipcsetup.h"
#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) || defined(__WXMAC__)
#include "mondrian.xpm"
#endif
#include "server.h"
+#include "wx/textdlg.h"
+#include "wx/datetime.h"
// ----------------------------------------------------------------------------
// wxWin macros
IMPLEMENT_APP(MyApp)
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
- EVT_MENU (SERVER_EXIT, MyFrame::OnExit)
- EVT_LISTBOX(SERVER_LISTBOX, MyFrame::OnListBoxClick)
+ EVT_MENU (wxID_EXIT, MyFrame::OnExit)
+ EVT_CLOSE( MyFrame::OnClose )
+ EVT_BUTTON( ID_START, MyFrame::OnStart )
+ EVT_CHOICE( ID_SERVERNAME, MyFrame::OnServerName )
+ EVT_BUTTON( ID_DISCONNECT, MyFrame::OnDisconnect )
+ EVT_BUTTON( ID_ADVISE, MyFrame::OnAdvise )
END_EVENT_TABLE()
-BEGIN_EVENT_TABLE(IPCDialogBox, wxDialog)
- EVT_BUTTON(SERVER_QUIT_BUTTON, IPCDialogBox::OnQuit)
-END_EVENT_TABLE()
-
-// ----------------------------------------------------------------------------
-// global variables
-// ----------------------------------------------------------------------------
-
-MyConnection *the_connection = NULL;
// ============================================================================
// implementation
bool MyApp::OnInit()
{
// Create the main frame window
- (new MyFrame(NULL, _T("Server")))->Show(true);
-
- // service name (DDE classes) or port number (TCP/IP based classes)
- wxString service = IPC_SERVICE;
-
- if (argc > 1)
- service = argv[1];
-
- // Create a new server
- m_server = new MyServer;
- m_server->Create(service);
+ m_frame = new MyFrame(NULL, _T("Server"));
+ m_frame->Show(true);
return true;
}
int MyApp::OnExit()
{
- delete m_server;
-
return 0;
}
// Define my frame constructor
MyFrame::MyFrame(wxFrame *frame, const wxString& title)
- : wxFrame(frame, wxID_ANY, title, wxDefaultPosition, wxSize(350, 250))
+ : wxFrame(frame, wxID_ANY, title, wxDefaultPosition, wxSize(400, 300))
{
#if wxUSE_STATUSBAR
CreateStatusBar();
// Make a menubar
wxMenu *file_menu = new wxMenu;
- file_menu->Append(SERVER_EXIT, _T("&Quit\tCtrl-Q"));
+ file_menu->Append(wxID_EXIT, _T("&Quit\tCtrl-Q"));
wxMenuBar *menu_bar = new wxMenuBar;
// Associate the menu bar with the frame
SetMenuBar(menu_bar);
- // Make a listbox
- wxListBox *list = new wxListBox(this, SERVER_LISTBOX);
- list->Append(_T("Apple"));
- list->Append(_T("Pear"));
- list->Append(_T("Orange"));
- list->Append(_T("Banana"));
- list->Append(_T("Fruit"));
+ // set a dialog background
+ SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
+
+ // add the controls to the frame
+ wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer *item1 = new wxBoxSizer( wxHORIZONTAL );
+
+ wxFlexGridSizer *item2 = new wxFlexGridSizer( 2, 0, 0 );
+ item2->AddGrowableCol( 1 );
+
+ wxButton *item3 = new wxButton( this, ID_START, wxT("Start Server"), wxDefaultPosition, wxDefaultSize, 0 );
+ item2->Add( item3, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxString strs4[] =
+ {
+ IPC_SERVICE, _T("...")
+ };
+ wxChoice *item4 = new wxChoice( this, ID_SERVERNAME, wxDefaultPosition, wxSize(100,-1), 2, strs4, 0 );
+ item2->Add( item4, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxButton *item5 = new wxButton( this, ID_DISCONNECT, wxT("Disconnect Client"), wxDefaultPosition, wxDefaultSize, 0 );
+ item2->Add( item5, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ wxButton *item6 = new wxButton( this, ID_ADVISE, wxT("Advise"), wxDefaultPosition, wxDefaultSize, 0 );
+ item2->Add( item6, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
+
+ item1->Add( item2, 1, wxALIGN_CENTER|wxALL, 5 );
+
+ item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxStaticBox *item8 = new wxStaticBox( this, -1, wxT("Server log") );
+ wxStaticBoxSizer *item7 = new wxStaticBoxSizer( item8, wxVERTICAL );
+
+ wxTextCtrl *item9 = new wxTextCtrl( this, ID_LOG, wxT(""), wxDefaultPosition, wxSize(500,140), wxTE_MULTILINE );
+ item7->Add( item9, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ item0->Add( item7, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ SetSizer( item0 );
+ item0->SetSizeHints( this );
+
+ // status
+ m_server = NULL;
+ GetServername()->SetSelection(0);
+ wxLogTextCtrl *logWindow = new wxLogTextCtrl(GetLog());
+ delete wxLog::SetActiveTarget(logWindow);
+ wxLogMessage(_T("Click on Start to start the server"));
+ Enable();
}
-// Set the client process's listbox to this item
-void MyFrame::OnListBoxClick(wxCommandEvent& WXUNUSED(event))
+void MyFrame::Enable()
{
- wxListBox* listBox = (wxListBox*) FindWindow(SERVER_LISTBOX);
- if (listBox)
- {
- wxString value = listBox->GetStringSelection();
+ GetStart()->Enable(m_server == NULL);
+ GetServername()->Enable(m_server == NULL);
+ GetAdvise()->Enable(m_server && m_server->CanAdvise());
+ GetDisconnect()->Enable(m_server && m_server->IsConnected() != NULL);
+}
- /* Because the_connection only holds one connection, in this sample only
- one connection can receive advise messages */
- if (the_connection)
- {
- the_connection->Advise(IPC_ADVISE_NAME, (wxChar*)value.c_str());
- }
+void MyFrame::OnClose(wxCloseEvent& event)
+{
+ if (m_server)
+ {
+ delete m_server;
+ m_server = NULL;
}
+ event.Skip();
}
void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
Close(true);
}
-// ----------------------------------------------------------------------------
-// IPCDialogBox
-// ----------------------------------------------------------------------------
+void MyFrame::OnStart(wxCommandEvent& WXUNUSED(event))
+{
+ // Create a new server
+ m_server = new MyServer;
+ wxString servername = GetServername()->GetStringSelection();
+ if (m_server->Create(servername))
+ {
+ wxLogMessage(_T("Server %s started"), servername.c_str());
+ #if wxUSE_DDE_FOR_IPC
+ wxLogMessage(_T("Server uses DDE"));
+ #else // !wxUSE_DDE_FOR_IPC
+ wxLogMessage(_T("Server uses TCP"));
+ #endif // wxUSE_DDE_FOR_IPC/!wxUSE_DDE_FOR_IPC
+ }
+ else
+ {
+ wxLogMessage(_T("Server %s failed to start"), servername.c_str());
+ delete m_server;
+ m_server = NULL;
+ }
+ Enable();
+}
-IPCDialogBox::IPCDialogBox(wxWindow *parent, const wxString& title,
- const wxPoint& pos, const wxSize& size,
- MyConnection *connection)
- : wxDialog(parent, wxID_ANY, title, pos, size)
+void MyFrame::OnServerName( wxCommandEvent& WXUNUSED(event) )
{
- m_connection = connection;
- (void)new wxButton(this, SERVER_QUIT_BUTTON, _T("Quit this connection"),
- wxPoint(5, 5));
- Fit();
+ if (GetServername()->GetStringSelection() == _T("..."))
+ {
+ wxString s = wxGetTextFromUser(_T("Specify the name of the server"),
+ _T("Server Name"), _(""), this);
+ if (!s.IsEmpty() && s != IPC_SERVICE)
+ {
+ GetServername()->Insert(s, 0);
+ GetServername()->SetSelection(0);
+ }
+ }
}
-IPCDialogBox::~IPCDialogBox( )
+void MyFrame::Disconnect()
{
- // wxWidgets exit code destroys dialog before destroying the connection in
- // OnExit, so make sure connection won't try to delete the dialog later.
- if (m_connection)
- m_connection->dialog = NULL;
+ m_server->Disconnect();
+ Enable();
}
-void IPCDialogBox::OnQuit(wxCommandEvent& WXUNUSED(event))
+void MyFrame::OnDisconnect(wxCommandEvent& WXUNUSED(event))
{
- m_connection->Disconnect();
- delete m_connection;
+ Disconnect();
+}
+
+void MyFrame::OnAdvise(wxCommandEvent& WXUNUSED(event))
+{
+ m_server->Advise();
}
// ----------------------------------------------------------------------------
// MyServer
// ----------------------------------------------------------------------------
+MyServer::MyServer() : wxServer()
+{
+ m_connection = NULL;
+}
+
+MyServer::~MyServer()
+{
+ Disconnect();
+}
+
wxConnectionBase *MyServer::OnAcceptConnection(const wxString& topic)
{
- if ( topic == IPC_TOPIC )
- return new MyConnection();
+ wxLogMessage(_T("OnAcceptConnection(\"%s\")"), topic);
+ if ( topic == IPC_TOPIC )
+ {
+ m_connection = new MyConnection();
+ wxGetApp().GetFrame()->Enable();
+ wxLogMessage(_T("Connection accepted"));
+ return m_connection;
+ }
// unknown topic
return NULL;
}
+void MyServer::Disconnect()
+{
+ if (m_connection)
+ {
+ m_connection->Disconnect();
+ delete m_connection;
+ m_connection = NULL;
+ wxGetApp().GetFrame()->Enable();
+ wxLogMessage(_T("Disconnected client"));
+ }
+}
+
+void MyServer::Advise()
+{
+ if (CanAdvise())
+ {
+ wxString s = wxDateTime::Now().Format();
+ m_connection->Advise(m_connection->m_sAdvise, (wxChar *)s.c_str());
+ s = wxDateTime::Now().FormatTime() + _T(" ") + wxDateTime::Now().FormatDate();
+ m_connection->Advise(m_connection->m_sAdvise, (wxChar *)s.c_str(), (s.Length() + 1) * sizeof(wxChar));
+
+#if wxUSE_DDE_FOR_IPC
+ wxLogMessage(_T("DDE Advise type argument cannot be wxIPC_PRIVATE. The client will receive it as wxIPC_TEXT, and receive the correct no of bytes, but not print a correct log entry."));
+#endif
+ char bytes[3];
+ bytes[0] = '1'; bytes[1] = '2'; bytes[2] = '3';
+ m_connection->Advise(m_connection->m_sAdvise, (wxChar *)bytes, 3, wxIPC_PRIVATE);
+ // this works, but the log treats it as a string now
+// m_connection->Advise(m_connection->m_sAdvise, (wxChar *)bytes, 3, wxIPC_TEXT );
+ }
+}
+
// ----------------------------------------------------------------------------
// MyConnection
// ----------------------------------------------------------------------------
MyConnection::MyConnection()
: wxConnection()
{
- dialog = new IPCDialogBox(wxTheApp->GetTopWindow(), _T("Connection"),
- wxDefaultPosition, wxDefaultSize, this);
- dialog->Show(true);
- the_connection = this;
}
MyConnection::~MyConnection()
{
- if (the_connection)
+}
+
+bool MyConnection::OnExecute(const wxString& topic,
+ wxChar *data, int size, wxIPCFormat format)
+{
+ Log(_T("OnExecute"), topic, _T(""), data, size, format);
+ return true;
+}
+
+bool MyConnection::OnPoke(const wxString& topic,
+ const wxString& item, wxChar *data, int size, wxIPCFormat format)
+{
+ Log(_T("OnPoke"), topic, item, data, size, format);
+ return wxConnection::OnPoke(topic, item, data, size, format);
+}
+
+wxChar *MyConnection::OnRequest(const wxString& topic,
+ const wxString& item, int * size, wxIPCFormat format)
+{
+ wxChar *data;
+ if (item == _T("Date"))
{
- if (dialog)
- {
- dialog->m_connection = NULL;
- dialog->Destroy();
- }
- the_connection = NULL;
+ m_sRequestDate = wxDateTime::Now().Format();
+ data = (wxChar *)m_sRequestDate.c_str();
+ *size = -1;
+ }
+ else if (item == _T("Date+len"))
+ {
+ m_sRequestDate = wxDateTime::Now().FormatTime() + _T(" ") + wxDateTime::Now().FormatDate();
+ data = (wxChar *)m_sRequestDate.c_str();
+ *size = (m_sRequestDate.Length() + 1) * sizeof(wxChar);
+ }
+ else if (item == _T("bytes[3]"))
+ {
+ data = (wxChar *)m_achRequestBytes;
+ m_achRequestBytes[0] = '1'; m_achRequestBytes[1] = '2'; m_achRequestBytes[2] = '3';
+ *size = 3;
+ }
+ else
+ {
+ data = NULL;
+ *size = 0;
}
+ Log(_T("OnRequest"), topic, item, data, *size, format);
+ return data;
}
-bool MyConnection::OnExecute(const wxString& WXUNUSED(topic),
- wxChar *data,
- int WXUNUSED(size),
- wxIPCFormat WXUNUSED(format))
+bool MyConnection::OnStartAdvise(const wxString& topic,
+ const wxString& item)
{
- wxLogStatus(wxT("Execute command: %s"), data);
+ wxLogMessage(_T("OnStartAdvise(\"%s\",\"%s\")"), topic, item);
+ wxLogMessage(_T("Returning true"));
+ m_sAdvise = item;
+ wxGetApp().GetFrame()->Enable();
return true;
}
-bool MyConnection::OnPoke(const wxString& WXUNUSED(topic),
- const wxString& item,
- wxChar *data,
- int WXUNUSED(size),
- wxIPCFormat WXUNUSED(format))
+bool MyConnection::OnStopAdvise(const wxString& topic,
+ const wxString& item)
{
- wxLogStatus(wxT("Poke command: %s = %s"), item.c_str(), data);
+ wxLogMessage(_T("OnStopAdvise(\"%s\",\"%s\")"), topic, item);
+ wxLogMessage(_T("Returning true"));
+ m_sAdvise.Empty();
+ wxGetApp().GetFrame()->Enable();
return true;
}
-wxChar *MyConnection::OnRequest(const wxString& WXUNUSED(topic),
- const wxString& WXUNUSED(item),
- int * WXUNUSED(size),
- wxIPCFormat WXUNUSED(format))
+void MyConnection::Log(const wxString& command, const wxString& topic,
+ const wxString& item, wxChar *data, int size, wxIPCFormat format)
+{
+ wxString s;
+ if (topic.IsEmpty() && item.IsEmpty())
+ s.Printf(_T("%s("), command);
+ else if (topic.IsEmpty())
+ s.Printf(_T("%s(\"%s\","), command, item);
+ else if (item.IsEmpty())
+ s.Printf(_T("%s(\"%s\","), command, topic);
+ else
+ s.Printf(_T("%s(\"%s\",\"%s\","), command, topic, item);
+
+ if (format == wxIPC_TEXT || format == wxIPC_UNICODETEXT)
+ wxLogMessage(_T("%s\"%s\",%d)"), s, data, size);
+ else if (format == wxIPC_PRIVATE)
+ {
+ if (size == 3)
+ {
+ char *bytes = (char *)data;
+ wxLogMessage(_T("%s'%c%c%c',%d)"), s, bytes[0], bytes[1], bytes[2], size);
+ }
+ else
+ wxLogMessage(_T("%s...,%d)"), s, size);
+ }
+ else if (format == wxIPC_INVALID)
+ wxLogMessage(_T("%s[invalid data],%d)"), s, size);
+}
+
+bool MyConnection::Advise(const wxString& item, wxChar *data, int size, wxIPCFormat format)
{
- return _T("Here, have your data, client!");
+ Log(_T("Advise"), _T(""), item, data, size, format);
+ return wxConnection::Advise(item, data, size, format);
}
-bool MyConnection::OnStartAdvise(const wxString& WXUNUSED(topic),
- const wxString& WXUNUSED(item))
+bool MyConnection::OnDisconnect()
{
+ wxLogMessage(_T("OnDisconnect()"));
+ wxGetApp().GetFrame()->Disconnect();
return true;
}
-
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
+#define ID_START 10000
+#define ID_DISCONNECT 10001
+#define ID_ADVISE 10002
+#define ID_LOG 10003
+#define ID_SERVERNAME 10004
+
// Define a new application
class MyServer;
+class MyConnection;
+class MyFrame;
+
class MyApp : public wxApp
{
public:
virtual bool OnInit();
virtual int OnExit();
+ MyFrame *GetFrame() { return m_frame; };
-private:
- MyServer *m_server;
+protected:
+ MyFrame *m_frame;
};
DECLARE_APP(MyApp)
public:
MyFrame(wxFrame *frame, const wxString& title);
- void OnListBoxClick(wxCommandEvent& event);
void OnExit(wxCommandEvent& event);
+ void OnClose(wxCloseEvent& event);
+
+ void Enable();
+ void Disconnect();
+
+protected:
+ wxButton* GetStart() { return (wxButton*) FindWindow( ID_START ); }
+ wxChoice* GetServername() { return (wxChoice*) FindWindow( ID_SERVERNAME ); }
+ wxButton* GetDisconnect() { return (wxButton*) FindWindow( ID_DISCONNECT ); }
+ wxButton* GetAdvise() { return (wxButton*) FindWindow( ID_ADVISE ); }
+ wxTextCtrl* GetLog() { return (wxTextCtrl*) FindWindow( ID_LOG ); }
-private:
- wxPanel *panel;
+
+ MyServer *m_server;
+
+ void OnStart( wxCommandEvent &event );
+ void OnServerName( wxCommandEvent &event );
+ void OnDisconnect( wxCommandEvent &event );
+ void OnAdvise( wxCommandEvent &event );
DECLARE_EVENT_TABLE()
};
-class IPCDialogBox;
class MyConnection : public wxConnection
{
public:
MyConnection();
~MyConnection();
- bool OnExecute(const wxString& topic, wxChar *data, int size, wxIPCFormat format);
- wxChar *OnRequest(const wxString& topic, const wxString& item, int *size, wxIPCFormat format);
- bool OnPoke(const wxString& topic, const wxString& item, wxChar *data, int size, wxIPCFormat format);
- bool OnStartAdvise(const wxString& topic, const wxString& item);
-
- IPCDialogBox *dialog;
+ virtual bool OnExecute(const wxString& topic, wxChar *data, int size, wxIPCFormat format);
+ virtual wxChar *OnRequest(const wxString& topic, const wxString& item, int *size, wxIPCFormat format);
+ virtual bool OnPoke(const wxString& topic, const wxString& item, wxChar *data, int size, wxIPCFormat format);
+ virtual bool OnStartAdvise(const wxString& topic, const wxString& item);
+ virtual bool OnStopAdvise(const wxString& topic, const wxString& item);
+ virtual bool Advise(const wxString& item, wxChar *data, int size = -1, wxIPCFormat format = wxIPC_TEXT);
+ virtual bool OnDisconnect();
+protected:
+ void Log(const wxString& command, const wxString& topic, const wxString& item, wxChar *data, int size, wxIPCFormat format);
+public:
+ wxString m_sAdvise;
+protected:
+ wxString m_sRequestDate;
+ char m_achRequestBytes[3];
};
class MyServer: public wxServer
{
public:
+ MyServer();
+ ~MyServer();
+ void Disconnect();
+ bool IsConnected() { return m_connection != NULL; };
+ MyConnection *GetConnection() { return m_connection; };
+ void Advise();
+ bool CanAdvise() { return m_connection != NULL && !m_connection->m_sAdvise.IsEmpty(); };
wxConnectionBase *OnAcceptConnection(const wxString& topic);
-};
-
-class IPCDialogBox: public wxDialog
-{
-public:
- IPCDialogBox(wxWindow *parent,
- const wxString& title,
- const wxPoint& pos,
- const wxSize& size,
- MyConnection *the_connection);
- ~IPCDialogBox( );
- void OnQuit(wxCommandEvent& event);
-
- MyConnection *m_connection;
-
- DECLARE_EVENT_TABLE()
+protected:
+ MyConnection *m_connection;
};
-#define SERVER_EXIT wxID_EXIT
-#define SERVER_LISTBOX 500
-#define SERVER_QUIT_BUTTON 501
IMPLEMENT_CLASS(wxClientBase, wxObject)
IMPLEMENT_CLASS(wxConnectionBase, wxObject)
-wxConnectionBase::wxConnectionBase(wxChar *buffer, int size)
+wxConnectionBase::wxConnectionBase(wxChar *buffer, int bytes)
: m_connected(true),
m_buffer(buffer),
- m_buffersize(size),
+ m_buffersize(bytes),
m_deletebufferwhendone(false)
{
if ( buffer == (wxChar *)NULL )
{ // we're in charge of buffer, increase it
if ( m_buffer )
delete m_buffer;
- m_buffer = new wxChar[bytes];
+ // the argument specifies **byte size**, but m_buffer is of type
+ // wxChar. Under unicode: sizeof(wxChar) > 1, so the buffer size is
+ // bytes / sizeof(wxChar) rounded upwards.
+ m_buffer = new wxChar[(bytes + sizeof(wxChar) - 1) / sizeof(wxChar)];
m_buffersize = bytes;
return m_buffer;
} // user-supplied buffer, fail
m_codeco->Write8(format);
if (size < 0)
- size = wxStrlen(data) + 1; // includes final NUL
+ size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL
m_codeco->Write32(size);
m_sockstrm->Write(data, size);
m_codeco->Write8(format);
if (size < 0)
- size = wxStrlen(data) + 1; // includes final NUL
+ size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL
m_codeco->Write32(size);
m_sockstrm->Write(data, size);
m_codeco->Write8(format);
if (size < 0)
- size = wxStrlen(data) + 1; // includes final NUL
+ size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL
m_codeco->Write32(size);
m_sockstrm->Write(data, size);
codeco->Write8(IPC_REQUEST_REPLY);
if (user_size == -1)
- user_size = wxStrlen(user_data) + 1; // includes final NUL
+ user_size = (wxStrlen(user_data) + 1) * sizeof(wxChar); // includes final NUL
codeco->Write32(user_size);
sockstrm->Write(user_data, user_size);
#include "wx/dde.h"
#include "wx/intl.h"
#include "wx/hashmap.h"
-#include "wx/math.h"
#include "wx/msw/private.h"
return ok;
}
-bool wxDDEConnection::Execute(const wxChar *data, int size, wxIPCFormat format)
+bool wxDDEConnection::Execute(const wxChar *data, int size, wxIPCFormat WXUNUSED(format))
{
DWORD result;
if (size < 0)
{
- size = wxStrlen(data) + 1;
+ size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL
}
bool ok = DdeClientTransaction((LPBYTE)data,
- size * sizeof(wxChar),
+ size,
GetHConv(),
NULL,
- format,
+// If the transaction specified by the wType parameter does not pass data or is XTYP_EXECUTE,
+// wFmt should be zero.
+ 0,
XTYP_EXECUTE,
DDE_TIMEOUT,
&result) != 0;
}
DWORD len = DdeGetData(returned_data, NULL, 0, 0);
- len = (DWORD)ceil( double(len)/sizeof(wxChar) );
wxChar *data = GetBufferAtLeast( len );
wxASSERT_MSG(data != NULL,
(void) DdeFreeDataHandle(returned_data);
if (size)
- *size = len;
+ *size = (int)len;
return data;
}
DWORD result;
if (size < 0)
{
- size = wxStrlen(data) + 1;
+ size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL
}
HSZ item_atom = DDEGetAtom(item);
bool ok = DdeClientTransaction((LPBYTE)data,
- size * sizeof(wxChar),
+ size,
GetHConv(),
item_atom, format,
XTYP_POKE,
{
if (size < 0)
{
- size = wxStrlen(data) + 1;
+ size = (wxStrlen(data) + 1) * sizeof(wxChar); // includes final NUL
}
HSZ item_atom = DDEGetAtom(item);
HSZ topic_atom = DDEGetAtom(m_topicName);
m_sendingData = data; // mrf: potential for scope problems here?
m_dataSize = size;
- m_dataType = format;
+ // wxIPC_PRIVATE does not succeed, so use text instead
+ m_dataType = format == wxIPC_PRIVATE ? wxIPC_TEXT : format;
bool ok = DdePostAdvise(DDEIdInst, topic_atom, item_atom) != 0;
if ( !ok )
if (connection)
{
DWORD len = DdeGetData(hData, NULL, 0, 0);
- len = (DWORD)ceil( double(len)/sizeof(wxChar) );
wxChar *data = connection->GetBufferAtLeast( len );
wxASSERT_MSG(data != NULL,
DdeFreeDataHandle(hData);
+// XTYP_EXECUTE cannot be used for arbitrary data, but only for text
if ( connection->OnExecute(connection->m_topicName,
data,
(int)len,
- (wxIPCFormat) wFmt) )
+ wxIPC_TEXT ) )
{
return (DDERETURN)(DWORD)DDE_FACK;
}
if (data)
{
if (user_size < 0)
- user_size = wxStrlen((wxChar*)data) + 1;
+ user_size = (wxStrlen((wxChar*)data) + 1) * sizeof(wxChar); // includes final NUL
HDDEDATA handle = DdeCreateDataHandle(DDEIdInst,
(LPBYTE)data,
- user_size*sizeof(wxChar),
+ user_size,
0,
hsz2,
wFmt,
wxString item_name = DDEStringFromAtom(hsz2);
DWORD len = DdeGetData(hData, NULL, 0, 0);
- len = (DWORD)ceil( double(len) / sizeof(wxChar) );
wxChar *data = connection->GetBufferAtLeast( len );
wxASSERT_MSG(data != NULL,
- _T("Buffer too small in _DDECallback (XTYP_EXECUTE)") );
+ _T("Buffer too small in _DDECallback (XTYP_POKE)") );
DdeGetData(hData, (LPBYTE)data, len, 0);
(
DDEIdInst,
(LPBYTE)connection->m_sendingData,
- connection->m_dataSize*sizeof(wxChar),
+ connection->m_dataSize,
0,
hsz2,
connection->m_dataType,
wxString item_name = DDEStringFromAtom(hsz2);
DWORD len = DdeGetData(hData, NULL, 0, 0);
- len = (DWORD)ceil( double(len) / sizeof(wxChar) );
wxChar *data = connection->GetBufferAtLeast( len );
wxASSERT_MSG(data != NULL,