1 /*---------------------------------------------------------------------------*
2 Project: HIO2 demos - multi
3 File: multi.cpp
4
5 (C)2005 HUDSON SOFT
6
7 $Header: /home/cvsroot/SDK/build/demos/hio2demo/vc++/multi/multi.cpp,v 1.3 2006/03/15 06:31:26 mitu Exp $
8
9 $NoKeywords: $
10 *---------------------------------------------------------------------------*/
11
12 // multi.cpp : Defines the class behaviors for the application.
13 //
14
15 #include "stdafx.h"
16 #include "multi.h"
17 #include "MainFrm.h"
18
19 #include "ChildFrm.h"
20 #include "multiDoc.h"
21 #include "multiView.h"
22 #include ".\multi.h"
23
24 #ifdef _DEBUG
25 #define new DEBUG_NEW
26 #endif
27
28 ///////// for multiApp /////////
29
30 // the comparison function specified in m_cInfoList.IndexOf()
MultiCompID(CMultiApp::LPAPPINFO pItem,LPVOID pData)31 BOOL MultiCompID(CMultiApp::LPAPPINFO pItem, LPVOID pData)
32 {
33 return (pItem->m_nHioIfID == (HIO2IF_ID)pData) ? TRUE : FALSE;
34 }
35
36 ///////////////////////////////////////////////////////////////////////////////
37 //
38 // local function and thread function definition
39 //
40
41 // Get active view
42 static
GetActiveView(HIO2IF_ID nID)43 CMultiView* GetActiveView(HIO2IF_ID nID)
44 {
45 POSITION pos;
46 CDocTemplate* pDocTemplate;
47 CMultiDoc* pDoc;
48
49 // Document Template
50 pos = GetApp()->GetFirstDocTemplatePosition();
51 if ( pos == NULL ) return NULL;
52 pDocTemplate = GetApp()->GetNextDocTemplate(pos);
53
54 // Document
55 pos = pDocTemplate->GetFirstDocPosition();
56 if ( pos == NULL ) return NULL;
57 while ( pos != NULL )
58 {
59 pDoc = static_cast<CMultiDoc *>(pDocTemplate->GetNextDoc(pos));
60 if ( pDoc->m_nHioIfID == nID )
61 {
62 POSITION viewpos = pDoc->GetFirstViewPosition();
63 if ( viewpos != NULL )
64 return static_cast<CMultiView *>(pDoc->GetNextView(viewpos));
65 }
66 }
67 return NULL;
68 }
69
70 // CHioIf::HIO2IF_EVENT_CALLBACK
71 static
HioIfEventCallback(HIO2IF_ID id,HIO2IF_EVENT event)72 void HioIfEventCallback(HIO2IF_ID id, HIO2IF_EVENT event)
73 {
74 CMultiView* pView;
75 CMultiApp* pApp = GetApp();
76 int nIndex =
77 GetApp()->m_cInfoList.IndexOf((LPVOID)id, MultiCompID);
78 CMultiApp::LPAPPINFO pInfo = pApp->m_cInfoList.GetItem(nIndex);
79
80 switch ( event )
81 {
82 case HIO2IF_EVENT_CONNECT: // connection established
83 {
84 BYTE clearBuf[MULTI_BUFFER_SIZE * 2];
85
86 // message to View
87 if ( (pView=GetActiveView(id)) != NULL )
88 pView->PostMessage(WM_USER, CMultiView::EVENT_CONNECT, 0);
89
90 // clear the region
91 ZeroMemory(clearBuf, sizeof(clearBuf));
92 pApp->m_pHioIf->WriteFree(id, MULTI_PC2NNGC_ADDR, clearBuf, sizeof(clearBuf), FALSE);
93 break;
94 }
95 case HIO2IF_EVENT_DISCONNECT: // connection released
96 pApp->m_pHioIf->Close(id);
97
98 // message to View
99 if ( (pView=GetActiveView(id)) != NULL )
100 pView->PostMessage(WM_USER, CMultiView::EVENT_DISCONNECT, 0);
101 break;
102 case HIO2IF_EVENT_RECEIVED: // Data reception
103 {
104 HIO2IF_RESULT result = pApp->m_pHioIf->Read(
105 id,
106 MULTI_NNGC2PC_ADDR,
107 (LPVOID)&(pInfo->m_stPacket),
108 MULTI_BUFFER_SIZE,
109 pInfo->m_bSync);
110
111 if ( HIO2IF_SUCCESS(result) && !pInfo->m_bSync )
112 {
113 if ( (pView=GetActiveView(id)) != NULL )
114 pView->PostMessage(WM_USER, CMultiView::EVENCT_RECEIVED, 0);
115 }
116 break;
117 }
118
119 case HIO2IF_EVENT_READ_ASYNC_DONE:
120 if ( (pView=GetActiveView(id)) != NULL )
121 pView->PostMessage(WM_USER, CMultiView::EVENCT_RECEIVED, 0);
122 break;
123
124 case HIO2IF_EVENT_WRITE_ASYNC_DONE:
125 if ( (pView=GetActiveView(id)) != NULL )
126 pView->PostMessage(WM_USER, CMultiView::EVENT_WRITE_DONE, 0);
127 break;
128
129 case HIO2IF_EVENT_SEND_POSSIBLE: // send possible
130 default:
131 break;
132 }
133 }
134
135 // ReadFree thread
136 static
PollingThread(LPVOID pHandle)137 DWORD WINAPI PollingThread( LPVOID pHandle )
138 {
139 CMultiApp* pApp = static_cast<CMultiApp *>(pHandle);
140
141 pApp->m_bThreadBreak = FALSE;
142 while ( !pApp->m_bThreadBreak )
143 {
144 for (int i=0; i<pApp->m_cInfoList.GetCount(); i++ )
145 {
146 CMultiView* pView;
147 DWORD dwStatus = 0;
148
149 CMultiApp::LPAPPINFO pInfo = pApp->m_cInfoList.GetItem(i);
150
151 // get communication status
152 pApp->m_pHioIf->ReadStatus(pInfo->m_nHioIfID, dwStatus);
153
154 // update displayed PC time, communication status
155 if ( (pView=GetActiveView(pInfo->m_nHioIfID)) != NULL )
156 pView->PostMessage(WM_USER, CMultiView::EVENT_UPDATE_PC_TIME, dwStatus);
157
158 #ifndef PROTOCOL_USED
159 // don't process when connection is broken
160 if ( !pApp->m_pHioIf->IsConnected(pInfo->m_nHioIfID) ) continue;
161
162 HIO2IF_RESULT result = pApp->m_pHioIf->ReadFree(
163 pInfo->m_nHioIfID,
164 MULTI_NNGC2PC_ADDR,
165 (LPVOID)&(pInfo->m_stPacket),
166 MULTI_BUFFER_SIZE,
167 pInfo->m_bSync);
168
169 pView = GetActiveView(pInfo->m_nHioIfID);
170 if ( HIO2IF_SUCCESS(result) && (pView != NULL) )
171 pView->PostMessage(WM_USER, CMultiView::EVENCT_RECEIVED, 0);
172 #endif
173 }
174
175 // Read for roughly each 1V
176 Sleep(1000 / 60);
177 }
178
179 return 0;
180 }
181
182
183 ///////////////////////////////////////////////////////////////////////////////
184 //
185 // CMultiApp - Host I/O API interface
186 //
187
188 //-----------------------------------------------------------------------------
HioIfInit()189 BOOL CMultiApp::HioIfInit()
190 {
191 // initialization
192 if ( HIO2IF_FAILED(m_pHioIf->Init()) ) return FALSE;
193
194 // open the detected number of EXI channels
195 for (int i=0; i<m_pHioIf->GetDeviceCount(); i++)
196 {
197 HIO2IF_ID id;
198 HIO2DevicePath pPath = m_pHioIf->GetDevicePath(i);
199 if ( HIO2IF_FAILED(m_pHioIf->Open(pPath, HioIfEventCallback, id)) )
200 return FALSE;
201
202 LPAPPINFO pInfo = new APPINFO;
203 #ifndef HW0
204 pInfo->m_pDevice = new TCHAR [lstrlen(pPath) + 1];
205 lstrcpy((LPSTR)pInfo->m_pDevice, pPath);
206 #else // HW0
207 pInfo->m_pDevice = pPath;
208 #endif // HW0
209 pInfo->m_nHioIfID = id;
210 m_cInfoList.AddTail(pInfo);
211 }
212
213 // update displayed PC time, create thread to run ReadFree() from CHioIf
214 DWORD dwTmp;
215
216 m_bThreadBreak = TRUE;
217 m_hThread = ::CreateThread(NULL, 0, PollingThread, (LPVOID)this, 0, &dwTmp);
218
219 // wait until thread launches
220 // set m_bThreadBreak to FALSE within the PollingThread function)
221 while ( m_bThreadBreak ) ;
222
223 // when protocol communication is taking place, call HIO2IF_EVENT_CALLBACK to go from HioIf
224 // to Read
225
226 return TRUE;
227 }
228
229 //-----------------------------------------------------------------------------
CreateInfo()230 void CMultiApp::CreateInfo()
231 {
232 POSITION pos = GetFirstDocTemplatePosition();
233 ASSERT(pos != NULL);
234 CMultiDocTemplate* pDocTemplate =
235 static_cast<CMultiDocTemplate *>(GetNextDocTemplate(pos));
236
237 for (int i=0; i<m_cInfoList.GetCount(); i++)
238 {
239 LPAPPINFO pInfo = m_cInfoList.GetItem(i);
240 CMultiDoc* pDoc =
241 static_cast<CMultiDoc *>(pDocTemplate->OpenDocumentFile(NULL, TRUE));
242 pDoc->m_nHioIfID = pInfo->m_nHioIfID;
243 pDoc->UpdateTitle();
244 }
245 }
246
247 //-----------------------------------------------------------------------------
HioIfExit()248 BOOL CMultiApp::HioIfExit()
249 {
250 // terminate three if PollingThread is valid
251 StopPollingThread();
252
253 m_pHioIf->EnterCriticalSection();
254 m_pHioIf->Exit(); // HIO termination
255 m_pHioIf->LeaveCriticalSection();
256
257 m_cInfoList.Clear();
258
259 return TRUE;
260 }
261
262 //-----------------------------------------------------------------------------
StopPollingThread()263 void CMultiApp::StopPollingThread()
264 {
265 // terminate three if PollingThread is valid
266 if ( m_hThread != INVALID_HANDLE_VALUE )
267 {
268 // halt the EXI thread
269 m_bThreadBreak = TRUE;
270 WaitForSingleObject(m_hThread,1000*30);
271 CloseHandle(m_hThread);
272 m_hThread = INVALID_HANDLE_VALUE;
273 }
274 }
275
Connect(HIO2IF_ID id)276 void CMultiApp::Connect(HIO2IF_ID id)
277 {
278 m_pHioIf->EnterCriticalSection();
279
280 int nIndex = m_cInfoList.IndexOf((LPVOID)id, MultiCompID);
281 LPAPPINFO pInfo = m_cInfoList.GetItem(nIndex);
282
283 if ( HIO2IF_FAILED(m_pHioIf->Open(pInfo->m_pDevice, HioIfEventCallback, id)) )
284 {
285 MessageBox(NULL, "reopen failed", "ERROR", MB_OK);
286 }
287
288 m_pHioIf->LeaveCriticalSection();
289 }
290
Disconnect(HIO2IF_ID id)291 void CMultiApp::Disconnect(HIO2IF_ID id)
292 {
293 m_pHioIf->EnterCriticalSection();
294 m_pHioIf->Close(id);
295 m_pHioIf->LeaveCriticalSection();
296
297 CMultiView* pView = GetActiveView(id);
298 if ( pView != NULL )
299 pView->PostMessage(WM_USER, CMultiView::EVENT_DISCONNECT, 0);
300 }
301
CreatePcTime(MULTI_PACKET * pPacket)302 void CMultiApp::CreatePcTime(MULTI_PACKET* pPacket)
303 {
304 struct tm *pLocalTime;
305 __time64_t lTime;
306
307 _time64(&lTime);
308 pLocalTime = _localtime64(&lTime);
309
310 pPacket->mon = pLocalTime->tm_mon;
311 pPacket->mday = pLocalTime->tm_mday;
312 pPacket->hour = pLocalTime->tm_hour;
313 pPacket->min = pLocalTime->tm_min;
314 pPacket->sec = pLocalTime->tm_sec;
315 pPacket->msec = 0;
316 strcpy(pPacket->string, "PC TIME");
317 }
318
319 ///////////////////////////////////////////////////////////////////////////////
320 //
321 // CMultiApp
322 //
323
BEGIN_MESSAGE_MAP(CMultiApp,CWinApp)324 BEGIN_MESSAGE_MAP(CMultiApp, CWinApp)
325 ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
326 // Standard file based document commands
327 ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
328 ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
329 END_MESSAGE_MAP()
330
331
332 // CMultiApp construction
333
334 CMultiApp::CMultiApp()
335 {
336 // TODO : add construction code here,
337 // Place all significant initialization in InitInstance
338 }
339
340
341 // The one and only CMultiApp object
342
343 CMultiApp theApp;
344
345 // CMultiApp initialization
346
InitInstance()347 BOOL CMultiApp::InitInstance()
348 {
349 // InitCommonControls() is required on Windows XP if an application
350 // manifest specifies use of ComCtl32.dll version 6 or later to enable
351 // visual styles. Otherwise, any window creation will fail.
352 InitCommonControls();
353
354 CWinApp::InitInstance();
355
356 // Initialize OLE libraries
357 if (!AfxOleInit())
358 {
359 AfxMessageBox(IDP_OLE_INIT_FAILED);
360 return FALSE;
361 }
362 AfxEnableControlContainer();
363 // Standard initialization
364 // If you are not using these features and wish to reduce the size
365 // of your final executable, you should remove from the following
366 // the specific initialization routines you do not need
367 // Change the registry key under which our settings are stored
368 // TODO : You should modify this string to be something appropriate
369 // such as the name of your company or organization
370 SetRegistryKey(_T("Local AppWizard-Generated Applications"));
371 LoadStdProfileSettings(4); // Load standard INI file options (including MRU)
372
373 ////////// for multiApp //////////
374 m_pHioIf = Hio2CreateInterface();
375 if ( !HioIfInit() )
376 {
377 MessageBox(NULL, m_pHioIf->GetMessage(), "ERROR", (MB_OK | MB_ICONWARNING));
378 m_cInfoList.Clear();
379 return FALSE;
380 }
381
382 // Register the application's document templates. Document templates
383 // serve as the connection between documents, frame windows and views
384 CMultiDocTemplate* pDocTemplate;
385 pDocTemplate = new CMultiDocTemplate(IDR_multiTYPE,
386 RUNTIME_CLASS(CMultiDoc),
387 RUNTIME_CLASS(CChildFrame), // custom MDI child frame
388 RUNTIME_CLASS(CMultiView));
389 if (!pDocTemplate)
390 return FALSE;
391 AddDocTemplate(pDocTemplate);
392 // create main MDI Frame window
393 CMainFrame* pMainFrame = new CMainFrame;
394 if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
395 return FALSE;
396 m_pMainWnd = pMainFrame;
397 // call DragAcceptFiles only if there's a suffix
398 // In an MDI app, this should occur immediately after setting m_pMainWnd
399 // Parse command line for standard shell commands, DDE, file open
400 CCommandLineInfo cmdInfo;
401 ParseCommandLine(cmdInfo);
402 // Dispatch commands specified on the command line. Will return FALSE if
403 // app was launched with /RegServer, /Register, /Unregserver or /Unregister.
404 #if 0
405 if (!ProcessShellCommand(cmdInfo))
406 return FALSE;
407 #endif
408 // The main window has been initialized, so show and update it
409 pMainFrame->ShowWindow(m_nCmdShow);
410 pMainFrame->UpdateWindow();
411
412 ////////// for multiApp //////////
413 // create a window for each EXI channel
414 CreateInfo();
415
416 return TRUE;
417 }
418
419 // CMultiApp message handlers
420
421
ExitInstance()422 int CMultiApp::ExitInstance()
423 {
424 ////////// for multiApp //////////
425 HioIfExit();
426 Hio2ReleaseInterface(m_pHioIf);
427
428 return CWinApp::ExitInstance();
429 }
430
431 // CAboutDlg dialog used for App About
432
433 class CAboutDlg : public CDialog
434 {
435 public:
436 CAboutDlg();
437
438 // Dialog Data
439 enum { IDD = IDD_ABOUTBOX };
440
441 protected:
442 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
443
444 // Implementation
445 protected:
446 DECLARE_MESSAGE_MAP()
447 };
448
CAboutDlg()449 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
450 {
451 }
452
DoDataExchange(CDataExchange * pDX)453 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
454 {
455 CDialog::DoDataExchange(pDX);
456 }
457
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)458 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
459 END_MESSAGE_MAP()
460
461 // App command to run the dialog
462 void CMultiApp::OnAppAbout()
463 {
464 CAboutDlg aboutDlg;
465 aboutDlg.DoModal();
466 }
467
468
469