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