X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8520f1374ceec64abae3802984c4f8654d8836ba..5dfc7e56e5da728f57b139f47c7dd234c6754dbe:/samples/ipc/server.cpp diff --git a/samples/ipc/server.cpp b/samples/ipc/server.cpp index 0ea33ed6bf..9680d222f8 100644 --- a/samples/ipc/server.cpp +++ b/samples/ipc/server.cpp @@ -2,7 +2,7 @@ // 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 @@ -30,13 +30,15 @@ // 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 @@ -45,19 +47,14 @@ 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 @@ -70,25 +67,14 @@ MyConnection *the_connection = NULL; 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; } @@ -98,7 +84,7 @@ int MyApp::OnExit() // 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(); @@ -110,7 +96,7 @@ MyFrame::MyFrame(wxFrame *frame, const wxString& title) // 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; @@ -119,30 +105,77 @@ MyFrame::MyFrame(wxFrame *frame, const wxString& title) // Associate the menu bar with the frame SetMenuBar(menu_bar); - // Make a listbox - wxListBox *list = new wxListBox(this, SERVER_LISTBOX, wxPoint(5, 5)); - 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()); +} - /* 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)) @@ -150,48 +183,120 @@ 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.c_str()); + 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 // ---------------------------------------------------------------------------- @@ -199,55 +304,115 @@ wxConnectionBase *MyServer::OnAcceptConnection(const wxString& topic) MyConnection::MyConnection() : wxConnection() { - dialog = new IPCDialogBox(wxTheApp->GetTopWindow(), _T("Connection"), - wxPoint(100, 100), wxSize(500, 500), 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.c_str(), item.c_str()); + 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.c_str(), item.c_str()); + 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.c_str()); + else if (topic.IsEmpty()) + s.Printf(_T("%s(\"%s\","), command.c_str(), item.c_str()); + else if (item.IsEmpty()) + s.Printf(_T("%s(\"%s\","), command.c_str(), topic.c_str()); + else + s.Printf(_T("%s(\"%s\",\"%s\","), command.c_str(), topic.c_str(), item.c_str()); + + if (format == wxIPC_TEXT || format == wxIPC_UNICODETEXT) + wxLogMessage(_T("%s\"%s\",%d)"), s.c_str(), data, size); + else if (format == wxIPC_PRIVATE) + { + if (size == 3) + { + char *bytes = (char *)data; + wxLogMessage(_T("%s'%c%c%c',%d)"), s.c_str(), bytes[0], bytes[1], bytes[2], size); + } + else + wxLogMessage(_T("%s...,%d)"), s.c_str(), size); + } + else if (format == wxIPC_INVALID) + wxLogMessage(_T("%s[invalid data],%d)"), s.c_str(), 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; } -