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.4 2007/11/26 13:56:47 iwai_yuma 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: // Establish connection
83 {
84 BYTE clearBuf[MULTI_BUFFER_SIZE * 2];
85
86 // Send 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 // Send 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: // Receive data
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 // To perform communication that employs protocol, call CHioIf->Read with HIO2IF_EVENT_CALLBACK
224 //
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 thread 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 thread 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 // errno_t err;
307
308 _time64(&lTime);
309 // err = _localtime64_s( &LocalTime, &lTime );
310 pLocalTime = _localtime64(&lTime);
311
312 pPacket->mon = pLocalTime->tm_mon + 1;
313 pPacket->mday = pLocalTime->tm_mday;
314 pPacket->hour = pLocalTime->tm_hour;
315 pPacket->min = pLocalTime->tm_min;
316 pPacket->sec = pLocalTime->tm_sec;
317 pPacket->msec = 0;
318 // strcpy_s( pPacket->string, sizeof( pPacket->string ), "PC TIME" );
319 strcpy( pPacket->string, "PC TIME" );
320 }
321
322 ///////////////////////////////////////////////////////////////////////////////
323 //
324 // CMultiApp
325 //
326
BEGIN_MESSAGE_MAP(CMultiApp,CWinApp)327 BEGIN_MESSAGE_MAP(CMultiApp, CWinApp)
328 ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
329 // Standard file based document commands
330 ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
331 ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
332 END_MESSAGE_MAP()
333
334
335 // CMultiApp construction
336
337 CMultiApp::CMultiApp()
338 {
339 // TODO: Add construction code here,
340 // Place all significant initialization in InitInstance
341 }
342
343
344 // The one and only CMultiApp object
345
346 CMultiApp theApp;
347
348 // CMultiApp initialization
349
InitInstance()350 BOOL CMultiApp::InitInstance()
351 {
352 // InitCommonControls() is required on Windows XP if an application
353 // manifest specifies use of ComCtl32.dll version 6 or later to enable
354 // visual styles. Otherwise, any window creation will fail.
355 InitCommonControls();
356
357 CWinApp::InitInstance();
358
359 // Initialize OLE libraries
360 if (!AfxOleInit())
361 {
362 AfxMessageBox(IDP_OLE_INIT_FAILED);
363 return FALSE;
364 }
365 AfxEnableControlContainer();
366 // Standard initialization
367 // If you are not using these features and wish to reduce the size
368 // of your final executable, you should remove from the following
369 // the specific initialization routines you do not need
370 // Change the registry key under which our settings are stored
371 // TODO: You should modify this string to be something appropriate
372 // such as the name of your company or organization
373 SetRegistryKey(_T("Local AppWizard-Generated Applications"));
374 LoadStdProfileSettings(4); // Load standard INI file options (including MRU)
375
376 ////////// for multiApp //////////
377 m_pHioIf = Hio2CreateInterface();
378 if ( !HioIfInit() )
379 {
380 MessageBox(NULL, m_pHioIf->GetMessage(), "ERROR", (MB_OK | MB_ICONWARNING));
381 m_cInfoList.Clear();
382 return FALSE;
383 }
384
385 // Register the application's document templates. Document templates
386 // serve as the connection between documents, frame windows and views
387 CMultiDocTemplate* pDocTemplate;
388 pDocTemplate = new CMultiDocTemplate(IDR_multiTYPE,
389 RUNTIME_CLASS(CMultiDoc),
390 RUNTIME_CLASS(CChildFrame), // Custom MDI child frame
391 RUNTIME_CLASS(CMultiView));
392 if (!pDocTemplate)
393 return FALSE;
394 AddDocTemplate(pDocTemplate);
395 // Create main MDI Frame window
396 CMainFrame* pMainFrame = new CMainFrame;
397 if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME))
398 return FALSE;
399 m_pMainWnd = pMainFrame;
400 // Call DragAcceptFiles only if there's a suffix
401 // In an MDI app, this should occur immediately after setting m_pMainWnd
402 // Parse command line for standard shell commands, DDE, file open
403 CCommandLineInfo cmdInfo;
404 ParseCommandLine(cmdInfo);
405 // Dispatch commands specified on the command line. Will return FALSE if
406 // app was launched with /RegServer, /Register, /Unregserver or /Unregister.
407 #if 0
408 if (!ProcessShellCommand(cmdInfo))
409 return FALSE;
410 #endif
411 // The main window has been initialized, so show and update it
412 pMainFrame->ShowWindow(m_nCmdShow);
413 pMainFrame->UpdateWindow();
414
415 ////////// for multiApp //////////
416 // Create a window for each EXI channel
417 CreateInfo();
418
419 return TRUE;
420 }
421
422 // CMultiApp message handlers
423
424
ExitInstance()425 int CMultiApp::ExitInstance()
426 {
427 ////////// for multiApp //////////
428 HioIfExit();
429 Hio2ReleaseInterface(m_pHioIf);
430
431 return CWinApp::ExitInstance();
432 }
433
434 // CAboutDlg dialog used for App About
435
436 class CAboutDlg : public CDialog
437 {
438 public:
439 CAboutDlg();
440
441 // Dialog Data
442 enum { IDD = IDD_ABOUTBOX };
443
444 protected:
445 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
446
447 // Implementation
448 protected:
449 DECLARE_MESSAGE_MAP()
450 };
451
CAboutDlg()452 CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
453 {
454 }
455
DoDataExchange(CDataExchange * pDX)456 void CAboutDlg::DoDataExchange(CDataExchange* pDX)
457 {
458 CDialog::DoDataExchange(pDX);
459 }
460
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)461 BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
462 END_MESSAGE_MAP()
463
464 // App command to run the dialog
465 void CMultiApp::OnAppAbout()
466 {
467 CAboutDlg aboutDlg;
468 aboutDlg.DoModal();
469 }
470
471
472