]> git.saurik.com Git - wxWidgets.git/blob - samples/ipc/client.cpp
Make storing non-trivial data in wxThreadSpecificInfo possible.
[wxWidgets.git] / samples / ipc / client.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: client.cpp
3 // Purpose: DDE sample: client
4 // Author: Julian Smart
5 // Modified by: Jurgen Doornik
6 // Created: 25/01/99
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #ifndef WX_PRECOMP
27 #include "wx/wx.h"
28 #endif
29
30 // Settings common to both executables: determines whether
31 // we're using TCP/IP or real DDE.
32 #include "ipcsetup.h"
33
34 #include "wx/datetime.h"
35 #include "client.h"
36
37 #ifndef wxHAS_IMAGES_IN_RESOURCES
38 #include "../sample.xpm"
39 #endif
40
41 // ----------------------------------------------------------------------------
42 // wxWin macros
43 // ----------------------------------------------------------------------------
44
45 IMPLEMENT_APP(MyApp)
46
47 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
48 EVT_MENU(wxID_EXIT, MyFrame::OnExit)
49 EVT_CLOSE( MyFrame::OnClose )
50 EVT_BUTTON( ID_START, MyFrame::OnStart )
51 EVT_CHOICE( ID_SERVERNAME, MyFrame::OnServername )
52 EVT_CHOICE( ID_HOSTNAME, MyFrame::OnHostname )
53 EVT_CHOICE( ID_TOPIC, MyFrame::OnTopic )
54 EVT_BUTTON( ID_DISCONNECT, MyFrame::OnDisconnect )
55 EVT_BUTTON( ID_STARTADVISE, MyFrame::OnStartAdvise )
56 EVT_BUTTON( ID_STOPADVISE, MyFrame::OnStopAdvise )
57 EVT_BUTTON( ID_POKE, MyFrame::OnPoke )
58 EVT_BUTTON( ID_EXECUTE, MyFrame::OnExecute )
59 EVT_BUTTON( ID_REQUEST, MyFrame::OnRequest )
60 END_EVENT_TABLE()
61
62 // ----------------------------------------------------------------------------
63 // globals
64 // ----------------------------------------------------------------------------
65
66 // ============================================================================
67 // implementation
68 // ============================================================================
69
70 // ----------------------------------------------------------------------------
71 // MyApp
72 // ----------------------------------------------------------------------------
73
74 // The `main program' equivalent, creating the windows and returning the
75 // main frame
76 bool MyApp::OnInit()
77 {
78 if ( !wxApp::OnInit() )
79 return false;
80
81 // Create the main frame window
82 m_frame = new MyFrame(NULL, wxT("Client"));
83 m_frame->Show(true);
84
85 return true;
86 }
87
88 int MyApp::OnExit()
89 {
90
91 return 0;
92 }
93
94 // Define my frame constructor
95 MyFrame::MyFrame(wxFrame *frame, const wxString& title)
96 : wxFrame(frame, wxID_ANY, title, wxDefaultPosition, wxSize(400, 300))
97 {
98 // Give it an icon
99 SetIcon(wxICON(sample));
100
101 // Make a menubar
102 wxMenu *file_menu = new wxMenu;
103
104 file_menu->Append(wxID_EXIT, wxT("&Quit\tCtrl-Q"));
105
106 wxMenuBar *menu_bar = new wxMenuBar;
107
108 menu_bar->Append(file_menu, wxT("&File"));
109
110 // Associate the menu bar with the frame
111 SetMenuBar(menu_bar);
112
113 // set a dialog background
114 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));
115
116 // add the controls to the frame
117 wxString strs4[] =
118 {
119 IPC_SERVICE, wxT("...")
120 };
121 wxString strs5[] =
122 {
123 IPC_HOST, wxT("...")
124 };
125 wxString strs6[] =
126 {
127 IPC_TOPIC, wxT("...")
128 };
129
130 wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
131
132 wxBoxSizer *item1 = new wxBoxSizer( wxHORIZONTAL );
133
134 wxGridSizer *item2 = new wxGridSizer( 4, 0, 0 );
135
136 wxButton *item3 = new wxButton( this, ID_START, wxT("Connect to server"), wxDefaultPosition, wxDefaultSize, 0 );
137 item2->Add( item3, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
138
139 wxChoice *item5 = new wxChoice( this, ID_HOSTNAME, wxDefaultPosition, wxSize(100,-1), 2, strs5, 0 );
140 item2->Add( item5, 0, wxALIGN_CENTER|wxALL, 5 );
141
142 wxChoice *item4 = new wxChoice( this, ID_SERVERNAME, wxDefaultPosition, wxSize(100,-1), 2, strs4, 0 );
143 item2->Add( item4, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
144
145 wxChoice *item6 = new wxChoice( this, ID_TOPIC, wxDefaultPosition, wxSize(100,-1), 2, strs6, 0 );
146 item2->Add( item6, 0, wxALIGN_CENTER|wxALL, 5 );
147
148 wxButton *item7 = new wxButton( this, ID_DISCONNECT, wxT("Disconnect "), wxDefaultPosition, wxDefaultSize, 0 );
149 item2->Add( item7, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
150
151 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
152
153 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
154
155 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
156
157 wxButton *item8 = new wxButton( this, ID_STARTADVISE, wxT("StartAdvise"), wxDefaultPosition, wxDefaultSize, 0 );
158 item2->Add( item8, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
159
160 wxButton *item9 = new wxButton( this, ID_STOPADVISE, wxT("StopAdvise"), wxDefaultPosition, wxDefaultSize, 0 );
161 item2->Add( item9, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
162
163 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
164
165 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
166
167 wxButton *item10 = new wxButton( this, ID_EXECUTE, wxT("Execute"), wxDefaultPosition, wxDefaultSize, 0 );
168 item2->Add( item10, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
169
170 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
171
172 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
173
174 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
175
176 wxButton *item11 = new wxButton( this, ID_POKE, wxT("Poke"), wxDefaultPosition, wxDefaultSize, 0 );
177 item2->Add( item11, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
178
179 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
180
181 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
182
183 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
184
185 wxButton *item12 = new wxButton( this, ID_REQUEST, wxT("Request"), wxDefaultPosition, wxDefaultSize, 0 );
186 item2->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
187
188 item2->Add( 20, 20, 0, wxALIGN_CENTER|wxALL, 5 );
189
190 item1->Add( item2, 1, wxALIGN_CENTER|wxALL, 5 );
191
192 item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
193
194 wxStaticBox *item14 = new wxStaticBox( this, -1, wxT("Client log") );
195 wxStaticBoxSizer *item13 = new wxStaticBoxSizer( item14, wxVERTICAL );
196
197 wxTextCtrl *item15 = new wxTextCtrl( this, ID_LOG, wxEmptyString, wxDefaultPosition, wxSize(500,140), wxTE_MULTILINE );
198 item13->Add( item15, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
199
200 item0->Add( item13, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
201
202 this->SetSizer( item0 );
203 item0->SetSizeHints( this );
204
205 // status
206 m_client = NULL;
207 GetServername()->SetSelection(0);
208 GetHostname()->SetSelection(0);
209 GetTopic()->SetSelection(0);
210 wxLogTextCtrl *logWindow = new wxLogTextCtrl(GetLog());
211 delete wxLog::SetActiveTarget(logWindow);
212 wxLogMessage(wxT("Click on Connect to connect to the server"));
213 EnableControls();
214 }
215
216 void MyFrame::EnableControls()
217 {
218 GetStart()->Enable(m_client == NULL);
219 GetServername()->Enable(m_client == NULL);
220 GetHostname()->Enable(m_client == NULL);
221 GetTopic()->Enable(m_client == NULL);
222
223 const bool isConnected = (m_client != NULL && m_client->IsConnected());
224 GetDisconnect()->Enable(m_client != NULL && isConnected);
225 GetStartAdvise()->Enable(m_client != NULL && isConnected);
226 GetStopAdvise()->Enable(m_client != NULL && isConnected);
227 GetExecute()->Enable(m_client != NULL && isConnected);
228 GetPoke()->Enable(m_client != NULL && isConnected);
229 GetRequest()->Enable(m_client != NULL && isConnected);
230 }
231
232 void MyFrame::OnClose(wxCloseEvent& event)
233 {
234 wxDELETE(m_client);
235
236 event.Skip();
237 }
238
239 void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
240 {
241 Close();
242 }
243
244 void MyFrame::OnStart(wxCommandEvent& WXUNUSED(event))
245 {
246 // Connect to the client
247 wxString servername = GetServername()->GetStringSelection();
248 wxString hostname = GetHostname()->GetStringSelection();
249 wxString topic = GetTopic()->GetStringSelection();
250
251 m_client = new MyClient;
252 bool retval = m_client->Connect(hostname, servername, topic);
253
254 wxLogMessage(wxT("Client host=\"%s\" port=\"%s\" topic=\"%s\" %s"),
255 hostname.c_str(), servername.c_str(), topic.c_str(),
256 retval ? wxT("connected") : wxT("failed to connect"));
257
258 if (!retval)
259 {
260 wxDELETE(m_client);
261 }
262 EnableControls();
263 }
264
265 void MyFrame::OnServername( wxCommandEvent& WXUNUSED(event) )
266 {
267 if (GetServername()->GetStringSelection() == wxT("..."))
268 {
269 wxString s = wxGetTextFromUser(wxT("Specify the name of the server"),
270 wxT("Server Name"), wxEmptyString, this);
271 if (!s.IsEmpty() && s != IPC_SERVICE)
272 {
273 GetServername()->Insert(s, 0);
274 GetServername()->SetSelection(0);
275 }
276 }
277 }
278
279 void MyFrame::OnHostname( wxCommandEvent& WXUNUSED(event) )
280 {
281 if (GetHostname()->GetStringSelection() == wxT("..."))
282 {
283 wxString s = wxGetTextFromUser(wxT("Specify the name of the host (ignored under DDE)"),
284 wxT("Host Name"), wxEmptyString, this);
285 if (!s.IsEmpty() && s != IPC_HOST)
286 {
287 GetHostname()->Insert(s, 0);
288 GetHostname()->SetSelection(0);
289 }
290 }
291 }
292
293 void MyFrame::OnTopic( wxCommandEvent& WXUNUSED(event) )
294 {
295 if (GetTopic()->GetStringSelection() == wxT("..."))
296 {
297 wxString s = wxGetTextFromUser(wxT("Specify the name of the topic"),
298 wxT("Topic Name"), wxEmptyString, this);
299 if (!s.IsEmpty() && s != IPC_TOPIC)
300 {
301 GetTopic()->Insert(s, 0);
302 GetTopic()->SetSelection(0);
303 }
304 }
305 }
306
307 void MyFrame::OnDisconnect(wxCommandEvent& WXUNUSED(event))
308 {
309 Disconnect();
310 }
311
312 void MyFrame::Disconnect()
313 {
314 wxDELETE(m_client);
315 EnableControls();
316 }
317
318 void MyFrame::OnStartAdvise(wxCommandEvent& WXUNUSED(event))
319 {
320 m_client->GetConnection()->StartAdvise(wxT("something"));
321 }
322
323 void MyFrame::OnStopAdvise(wxCommandEvent& WXUNUSED(event))
324 {
325 m_client->GetConnection()->StopAdvise(wxT("something"));
326 }
327
328 void MyFrame::OnExecute(wxCommandEvent& WXUNUSED(event))
329 {
330 if (m_client->IsConnected())
331 {
332 wxString s = wxT("Date");
333
334 m_client->GetConnection()->Execute(s);
335 m_client->GetConnection()->Execute((const char *)s.c_str(), s.length() + 1);
336 char bytes[3];
337 bytes[0] = '1';
338 bytes[1] = '2';
339 bytes[2] = '3';
340 m_client->GetConnection()->Execute(bytes, WXSIZEOF(bytes));
341 }
342 }
343
344 void MyFrame::OnPoke(wxCommandEvent& WXUNUSED(event))
345 {
346 if (m_client->IsConnected())
347 {
348 wxString s = wxDateTime::Now().Format();
349 m_client->GetConnection()->Poke(wxT("Date"), s);
350 s = wxDateTime::Now().FormatTime() + wxT(" ") + wxDateTime::Now().FormatDate();
351 m_client->GetConnection()->Poke(wxT("Date"), (const char *)s.c_str(), s.length() + 1);
352 char bytes[3];
353 bytes[0] = '1'; bytes[1] = '2'; bytes[2] = '3';
354 m_client->GetConnection()->Poke(wxT("bytes[3]"), bytes, 3, wxIPC_PRIVATE);
355 }
356 }
357
358 void MyFrame::OnRequest(wxCommandEvent& WXUNUSED(event))
359 {
360 if (m_client->IsConnected())
361 {
362 size_t size;
363 m_client->GetConnection()->Request(wxT("Date"));
364 m_client->GetConnection()->Request(wxT("Date+len"), &size);
365 m_client->GetConnection()->Request(wxT("bytes[3]"), &size, wxIPC_PRIVATE);
366 }
367 }
368
369 // ----------------------------------------------------------------------------
370 // MyClient
371 // ----------------------------------------------------------------------------
372 MyClient::MyClient() : wxClient()
373 {
374 m_connection = NULL;
375 }
376
377 bool MyClient::Connect(const wxString& sHost, const wxString& sService, const wxString& sTopic)
378 {
379 // suppress the log messages from MakeConnection()
380 wxLogNull nolog;
381
382 m_connection = (MyConnection *)MakeConnection(sHost, sService, sTopic);
383 return m_connection != NULL;
384 }
385
386 wxConnectionBase *MyClient::OnMakeConnection()
387 {
388 return new MyConnection;
389 }
390
391 void MyClient::Disconnect()
392 {
393 if (m_connection)
394 {
395 m_connection->Disconnect();
396 wxDELETE(m_connection);
397 wxGetApp().GetFrame()->EnableControls();
398 wxLogMessage(wxT("Client disconnected from server"));
399 }
400 }
401
402 MyClient::~MyClient()
403 {
404 Disconnect();
405 }
406
407 // ----------------------------------------------------------------------------
408 // MyConnection
409 // ----------------------------------------------------------------------------
410
411 bool MyConnection::OnAdvise(const wxString& topic, const wxString& item, const void *data,
412 size_t size, wxIPCFormat format)
413 {
414 Log(wxT("OnAdvise"), topic, item, data, size, format);
415 return true;
416 }
417
418 bool MyConnection::OnDisconnect()
419 {
420 wxLogMessage(wxT("OnDisconnect()"));
421 wxGetApp().GetFrame()->Disconnect();
422 return true;
423 }
424
425 bool MyConnection::DoExecute(const void *data, size_t size, wxIPCFormat format)
426 {
427 Log(wxT("Execute"), wxEmptyString, wxEmptyString, data, size, format);
428 bool retval = wxConnection::DoExecute(data, size, format);
429 if (!retval)
430 {
431 wxLogMessage(wxT("Execute failed!"));
432 }
433 return retval;
434 }
435
436 const void *MyConnection::Request(const wxString& item, size_t *size, wxIPCFormat format)
437 {
438 const void *data = wxConnection::Request(item, size, format);
439 Log(wxT("Request"), wxEmptyString, item, data, size ? *size : wxNO_LEN, format);
440 return data;
441 }
442
443 bool MyConnection::DoPoke(const wxString& item, const void *data, size_t size, wxIPCFormat format)
444 {
445 Log(wxT("Poke"), wxEmptyString, item, data, size, format);
446 return wxConnection::DoPoke(item, data, size, format);
447 }