]> git.saurik.com Git - wxWidgets.git/blame - samples/ipc/server.cpp
The alignment controls are now left-aligned if the floating controls are not shown.
[wxWidgets.git] / samples / ipc / server.cpp
CommitLineData
7921cf2b
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: server.cpp
4b89c618 3// Purpose: IPC sample: server
7921cf2b 4// Author: Julian Smart
9d860992 5// Modified by: Jurgen Doornik
7921cf2b 6// Created: 25/01/99
7921cf2b
JS
7// Copyright: (c) Julian Smart
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
4b89c618
VZ
11// ============================================================================
12// declarations
13// ============================================================================
14
15// ----------------------------------------------------------------------------
16// headers
17// ----------------------------------------------------------------------------
18
7921cf2b
JS
19// For compilers that support precompilation, includes "wx.h".
20#include "wx/wxprec.h"
21
22#ifdef __BORLANDC__
4b89c618 23 #pragma hdrstop
7921cf2b
JS
24#endif
25
26#ifndef WX_PRECOMP
4b89c618 27 #include "wx/wx.h"
7921cf2b
JS
28#endif
29
30// Settings common to both executables: determines whether
31// we're using TCP/IP or real DDE.
9d860992 32#include "ipcsetup.h"
7921cf2b 33
e7092398 34#ifndef wxHAS_IMAGES_IN_RESOURCES
589c1174 35 #include "../sample.xpm"
7921cf2b
JS
36#endif
37
38#include "server.h"
9d860992
JS
39#include "wx/textdlg.h"
40#include "wx/datetime.h"
7921cf2b 41
4b89c618
VZ
42// ----------------------------------------------------------------------------
43// wxWin macros
44// ----------------------------------------------------------------------------
7921cf2b
JS
45
46IMPLEMENT_APP(MyApp)
47
4b89c618 48BEGIN_EVENT_TABLE(MyFrame, wxFrame)
9d860992 49 EVT_CLOSE( MyFrame::OnClose )
589c1174
VZ
50
51 EVT_BUTTON( ID_START, MyFrame::OnStart )
52 EVT_CHOICE( ID_SERVERNAME, MyFrame::OnServerName )
9d860992
JS
53 EVT_BUTTON( ID_DISCONNECT, MyFrame::OnDisconnect )
54 EVT_BUTTON( ID_ADVISE, MyFrame::OnAdvise )
4b89c618
VZ
55END_EVENT_TABLE()
56
4b89c618
VZ
57
58// ============================================================================
59// implementation
60// ============================================================================
61
62// ----------------------------------------------------------------------------
63// MyApp
64// ----------------------------------------------------------------------------
7921cf2b
JS
65
66bool MyApp::OnInit()
67{
45e6e6f8
VZ
68 if ( !wxApp::OnInit() )
69 return false;
70
4b89c618 71 // Create the main frame window
589c1174 72 m_frame = new MyFrame(NULL, "Server");
9d860992 73 m_frame->Show(true);
7921cf2b 74
b62ca03d 75 return true;
4b89c618 76}
7921cf2b 77
4b89c618
VZ
78// ----------------------------------------------------------------------------
79// MyFrame
80// ----------------------------------------------------------------------------
7921cf2b 81
4b89c618
VZ
82// Define my frame constructor
83MyFrame::MyFrame(wxFrame *frame, const wxString& title)
9d860992 84 : wxFrame(frame, wxID_ANY, title, wxDefaultPosition, wxSize(400, 300))
4b89c618 85{
8520f137 86#if wxUSE_STATUSBAR
4b89c618 87 CreateStatusBar();
8520f137 88#endif // wxUSE_STATUSBAR
7921cf2b 89
589c1174 90 SetIcon(wxICON(sample));
7921cf2b 91
589c1174 92 m_server = NULL;
9d860992 93
589c1174 94 wxPanel * const panel = new wxPanel(this);
9d860992 95
589c1174 96 wxBoxSizer * const sizerMain = new wxBoxSizer( wxVERTICAL );
9d860992 97
589c1174
VZ
98 wxFlexGridSizer * const sizerCmds = new wxFlexGridSizer( 2, 0, 0 );
99 sizerCmds->AddGrowableCol( 1 );
9d860992 100
589c1174 101 wxButton *btn;
9d860992 102
589c1174
VZ
103 btn = new wxButton(panel, ID_START, "&Start Server");
104 sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
9d860992 105
589c1174
VZ
106 const wxString choices[] = { IPC_SERVICE, "..." };
107 wxChoice * const choice = new wxChoice
108 (
109 panel,
110 ID_SERVERNAME,
111 wxDefaultPosition, wxSize(100, -1),
112 WXSIZEOF(choices), choices
113 );
114 sizerCmds->Add(choice, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
9d860992 115
589c1174
VZ
116 btn = new wxButton(panel, ID_DISCONNECT, "&Disconnect Client");
117 sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
118 sizerCmds->AddSpacer(20);
9d860992 119
589c1174
VZ
120 btn = new wxButton( panel, ID_ADVISE, "&Advise");
121 sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
122 sizerCmds->AddSpacer(20);
9d860992 123
589c1174 124 sizerMain->Add(sizerCmds, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
9d860992 125
589c1174
VZ
126 wxStaticBoxSizer * const
127 sizerLog = new wxStaticBoxSizer(wxVERTICAL, panel, "Server &log");
9d860992 128
589c1174
VZ
129 wxTextCtrl * const textLog = new wxTextCtrl
130 (
131 panel,
132 wxID_ANY,
133 "",
134 wxDefaultPosition, wxSize(500, 140),
135 wxTE_MULTILINE
136 );
137 sizerLog->Add(textLog, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
9d860992 138
589c1174 139 sizerMain->Add(sizerLog, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
9d860992 140
589c1174
VZ
141 panel->SetSizer(sizerMain);
142 sizerMain->SetSizeHints(panel);
143 SetClientSize(panel->GetSize());
9d860992 144
9d860992 145 GetServername()->SetSelection(0);
589c1174 146 wxLogTextCtrl *logWindow = new wxLogTextCtrl(textLog);
9d860992 147 delete wxLog::SetActiveTarget(logWindow);
589c1174
VZ
148 wxLogMessage("Click on Start to start the server");
149 UpdateUI();
7921cf2b
JS
150}
151
589c1174 152void MyFrame::UpdateUI()
7921cf2b 153{
9d860992
JS
154 GetStart()->Enable(m_server == NULL);
155 GetServername()->Enable(m_server == NULL);
156 GetAdvise()->Enable(m_server && m_server->CanAdvise());
b21348b4 157 GetDisconnect()->Enable(m_server && m_server->IsConnected());
9d860992 158}
f010ad48 159
9d860992
JS
160void MyFrame::OnClose(wxCloseEvent& event)
161{
5276b0a5 162 wxDELETE(m_server);
9d860992 163 event.Skip();
7921cf2b
JS
164}
165
9d860992
JS
166void MyFrame::OnStart(wxCommandEvent& WXUNUSED(event))
167{
168 // Create a new server
169 m_server = new MyServer;
170 wxString servername = GetServername()->GetStringSelection();
171 if (m_server->Create(servername))
172 {
589c1174 173 wxLogMessage("Server %s started", servername);
9d860992 174 #if wxUSE_DDE_FOR_IPC
589c1174 175 wxLogMessage("Server uses DDE");
9d860992 176 #else // !wxUSE_DDE_FOR_IPC
589c1174 177 wxLogMessage("Server uses TCP");
9d860992
JS
178 #endif // wxUSE_DDE_FOR_IPC/!wxUSE_DDE_FOR_IPC
179 }
180 else
181 {
589c1174 182 wxLogMessage("Server %s failed to start", servername);
5276b0a5 183 wxDELETE(m_server);
9d860992 184 }
589c1174 185 UpdateUI();
9d860992 186}
7921cf2b 187
9d860992 188void MyFrame::OnServerName( wxCommandEvent& WXUNUSED(event) )
7921cf2b 189{
589c1174 190 if ( GetServername()->GetStringSelection() == "..." )
9d860992 191 {
589c1174
VZ
192 wxString s = wxGetTextFromUser
193 (
194 "Specify the name of the server",
195 "Server Name",
196 "",
197 this
198 );
199
200 if ( !s.empty() && s != IPC_SERVICE )
9d860992
JS
201 {
202 GetServername()->Insert(s, 0);
203 GetServername()->SetSelection(0);
204 }
205 }
7921cf2b
JS
206}
207
9d860992 208void MyFrame::Disconnect()
f010ad48 209{
9d860992 210 m_server->Disconnect();
589c1174 211 UpdateUI();
f010ad48
JS
212}
213
9d860992 214void MyFrame::OnDisconnect(wxCommandEvent& WXUNUSED(event))
7921cf2b 215{
589c1174 216 Disconnect();
9d860992
JS
217}
218
219void MyFrame::OnAdvise(wxCommandEvent& WXUNUSED(event))
220{
221 m_server->Advise();
7921cf2b
JS
222}
223
4b89c618
VZ
224// ----------------------------------------------------------------------------
225// MyServer
226// ----------------------------------------------------------------------------
227
9d860992
JS
228MyServer::MyServer() : wxServer()
229{
230 m_connection = NULL;
231}
232
233MyServer::~MyServer()
234{
235 Disconnect();
236}
237
7921cf2b
JS
238wxConnectionBase *MyServer::OnAcceptConnection(const wxString& topic)
239{
589c1174 240 wxLogMessage("OnAcceptConnection(\"%s\")", topic);
d5172a58 241
9d860992
JS
242 if ( topic == IPC_TOPIC )
243 {
244 m_connection = new MyConnection();
589c1174
VZ
245 wxGetApp().GetFrame()->UpdateUI();
246 wxLogMessage("Connection accepted");
9d860992
JS
247 return m_connection;
248 }
589c1174
VZ
249 //else: unknown topic
250
251 wxLogMessage("Unknown topic, connection refused");
d5172a58 252 return NULL;
7921cf2b
JS
253}
254
9d860992
JS
255void MyServer::Disconnect()
256{
589c1174 257 if ( m_connection )
9d860992 258 {
5276b0a5 259 wxDELETE(m_connection);
589c1174
VZ
260 wxGetApp().GetFrame()->UpdateUI();
261 wxLogMessage("Disconnected client");
9d860992
JS
262 }
263}
264
265void MyServer::Advise()
266{
589c1174 267 if ( CanAdvise() )
9d860992 268 {
589c1174
VZ
269 const wxDateTime now = wxDateTime::Now();
270
271 m_connection->Advise(m_connection->m_advise, now.Format());
272
273 const wxString s = now.FormatTime() + " " + now.FormatDate();
274 m_connection->Advise(m_connection->m_advise, s.mb_str(), wxNO_LEN);
9d860992
JS
275
276#if wxUSE_DDE_FOR_IPC
589c1174
VZ
277 wxLogMessage("DDE Advise type argument cannot be wxIPC_PRIVATE. "
278 "The client will receive it as wxIPC_TEXT, "
279 " and receive the correct no of bytes, "
280 "but not print a correct log entry.");
9d860992 281#endif
589c1174
VZ
282 char bytes[3] = { '1', '2', '3' };
283 m_connection->Advise(m_connection->m_advise, bytes, 3, wxIPC_PRIVATE);
9d860992
JS
284 }
285}
286
4b89c618
VZ
287// ----------------------------------------------------------------------------
288// MyConnection
289// ----------------------------------------------------------------------------
290
589c1174
VZ
291bool
292MyConnection::OnExecute(const wxString& topic,
293 const void *data,
294 size_t size,
295 wxIPCFormat format)
9d860992 296{
589c1174 297 Log("OnExecute", topic, "", data, size, format);
9d860992
JS
298 return true;
299}
300
589c1174
VZ
301bool
302MyConnection::OnPoke(const wxString& topic,
303 const wxString& item,
304 const void *data,
305 size_t size,
306 wxIPCFormat format)
9d860992 307{
589c1174 308 Log("OnPoke", topic, item, data, size, format);
9d860992
JS
309 return wxConnection::OnPoke(topic, item, data, size, format);
310}
311
589c1174
VZ
312const void *
313MyConnection::OnRequest(const wxString& topic,
314 const wxString& item,
315 size_t *size,
316 wxIPCFormat format)
9d860992 317{
589c1174
VZ
318 *size = 0;
319
e536b750
VZ
320 wxString s,
321 afterDate;
589c1174 322 if ( item.StartsWith("Date", &afterDate) )
9d860992 323 {
589c1174
VZ
324 const wxDateTime now = wxDateTime::Now();
325
326 if ( afterDate.empty() )
327 {
e536b750 328 s = now.Format();
589c1174
VZ
329 *size = wxNO_LEN;
330 }
331 else if ( afterDate == "+len" )
332 {
e536b750
VZ
333 s = now.FormatTime() + " " + now.FormatDate();
334 *size = strlen(s.mb_str()) + 1;
589c1174
VZ
335 }
336 }
337 else if ( item == "bytes[3]" )
9d860992 338 {
e536b750 339 s = "123";
9d860992
JS
340 *size = 3;
341 }
589c1174
VZ
342
343 if ( !*size )
9d860992 344 {
589c1174
VZ
345 wxLogMessage("Unknown request for \"%s\"", item);
346 return NULL;
4b89c618 347 }
589c1174 348
e536b750
VZ
349 // store the data pointer to which we return in a member variable to ensure
350 // that the pointer remains valid even after we return
351 m_requestData = s.mb_str();
352 const void * const data = m_requestData;
589c1174 353 Log("OnRequest", topic, item, data, *size, format);
9d860992 354 return data;
7921cf2b
JS
355}
356
589c1174 357bool MyConnection::OnStartAdvise(const wxString& topic, const wxString& item)
7921cf2b 358{
589c1174
VZ
359 wxLogMessage("OnStartAdvise(\"%s\", \"%s\")", topic, item);
360 wxLogMessage("Returning true");
361 m_advise = item;
362 wxGetApp().GetFrame()->UpdateUI();
b62ca03d 363 return true;
7921cf2b
JS
364}
365
589c1174 366bool MyConnection::OnStopAdvise(const wxString& topic, const wxString& item)
7921cf2b 367{
589c1174
VZ
368 wxLogMessage("OnStopAdvise(\"%s\",\"%s\")", topic, item);
369 wxLogMessage("Returning true");
370 m_advise.clear();
371 wxGetApp().GetFrame()->UpdateUI();
b62ca03d 372 return true;
7921cf2b
JS
373}
374
589c1174
VZ
375bool
376MyConnection::DoAdvise(const wxString& item,
377 const void *data,
378 size_t size,
379 wxIPCFormat format)
7921cf2b 380{
589c1174 381 Log("Advise", "", item, data, size, format);
50c549b9 382 return wxConnection::DoAdvise(item, data, size, format);
7921cf2b
JS
383}
384
9d860992 385bool MyConnection::OnDisconnect()
7921cf2b 386{
589c1174 387 wxLogMessage("OnDisconnect()");
9d860992 388 wxGetApp().GetFrame()->Disconnect();
b62ca03d 389 return true;
7921cf2b 390}