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