/*---------------------------------------------------------------------------* Project: HIO2 demos - multi File: multi.cpp (C)2005 HUDSON SOFT $Header: /home/cvsroot/SDK/build/demos/hio2demo/vc++/multi/multi.cpp,v 1.3 2006/03/15 06:31:26 mitu Exp $ $NoKeywords: $ *---------------------------------------------------------------------------*/ // multi.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "multi.h" #include "MainFrm.h" #include "ChildFrm.h" #include "multiDoc.h" #include "multiView.h" #include ".\multi.h" #ifdef _DEBUG #define new DEBUG_NEW #endif ///////// for multiApp ///////// // the comparison function specified in m_cInfoList.IndexOf() BOOL MultiCompID(CMultiApp::LPAPPINFO pItem, LPVOID pData) { return (pItem->m_nHioIfID == (HIO2IF_ID)pData) ? TRUE : FALSE; } /////////////////////////////////////////////////////////////////////////////// // // local function and thread function definition // // Get active view static CMultiView* GetActiveView(HIO2IF_ID nID) { POSITION pos; CDocTemplate* pDocTemplate; CMultiDoc* pDoc; // Document Template pos = GetApp()->GetFirstDocTemplatePosition(); if ( pos == NULL ) return NULL; pDocTemplate = GetApp()->GetNextDocTemplate(pos); // Document pos = pDocTemplate->GetFirstDocPosition(); if ( pos == NULL ) return NULL; while ( pos != NULL ) { pDoc = static_cast(pDocTemplate->GetNextDoc(pos)); if ( pDoc->m_nHioIfID == nID ) { POSITION viewpos = pDoc->GetFirstViewPosition(); if ( viewpos != NULL ) return static_cast(pDoc->GetNextView(viewpos)); } } return NULL; } // CHioIf::HIO2IF_EVENT_CALLBACK static void HioIfEventCallback(HIO2IF_ID id, HIO2IF_EVENT event) { CMultiView* pView; CMultiApp* pApp = GetApp(); int nIndex = GetApp()->m_cInfoList.IndexOf((LPVOID)id, MultiCompID); CMultiApp::LPAPPINFO pInfo = pApp->m_cInfoList.GetItem(nIndex); switch ( event ) { case HIO2IF_EVENT_CONNECT: // connection established { BYTE clearBuf[MULTI_BUFFER_SIZE * 2]; // message to View if ( (pView=GetActiveView(id)) != NULL ) pView->PostMessage(WM_USER, CMultiView::EVENT_CONNECT, 0); // clear the region ZeroMemory(clearBuf, sizeof(clearBuf)); pApp->m_pHioIf->WriteFree(id, MULTI_PC2NNGC_ADDR, clearBuf, sizeof(clearBuf), FALSE); break; } case HIO2IF_EVENT_DISCONNECT: // connection released pApp->m_pHioIf->Close(id); // message to View if ( (pView=GetActiveView(id)) != NULL ) pView->PostMessage(WM_USER, CMultiView::EVENT_DISCONNECT, 0); break; case HIO2IF_EVENT_RECEIVED: // Data reception { HIO2IF_RESULT result = pApp->m_pHioIf->Read( id, MULTI_NNGC2PC_ADDR, (LPVOID)&(pInfo->m_stPacket), MULTI_BUFFER_SIZE, pInfo->m_bSync); if ( HIO2IF_SUCCESS(result) && !pInfo->m_bSync ) { if ( (pView=GetActiveView(id)) != NULL ) pView->PostMessage(WM_USER, CMultiView::EVENCT_RECEIVED, 0); } break; } case HIO2IF_EVENT_READ_ASYNC_DONE: if ( (pView=GetActiveView(id)) != NULL ) pView->PostMessage(WM_USER, CMultiView::EVENCT_RECEIVED, 0); break; case HIO2IF_EVENT_WRITE_ASYNC_DONE: if ( (pView=GetActiveView(id)) != NULL ) pView->PostMessage(WM_USER, CMultiView::EVENT_WRITE_DONE, 0); break; case HIO2IF_EVENT_SEND_POSSIBLE: // send possible default: break; } } // ReadFree thread static DWORD WINAPI PollingThread( LPVOID pHandle ) { CMultiApp* pApp = static_cast(pHandle); pApp->m_bThreadBreak = FALSE; while ( !pApp->m_bThreadBreak ) { for (int i=0; im_cInfoList.GetCount(); i++ ) { CMultiView* pView; DWORD dwStatus = 0; CMultiApp::LPAPPINFO pInfo = pApp->m_cInfoList.GetItem(i); // get communication status pApp->m_pHioIf->ReadStatus(pInfo->m_nHioIfID, dwStatus); // update displayed PC time, communication status if ( (pView=GetActiveView(pInfo->m_nHioIfID)) != NULL ) pView->PostMessage(WM_USER, CMultiView::EVENT_UPDATE_PC_TIME, dwStatus); #ifndef PROTOCOL_USED // don't process when connection is broken if ( !pApp->m_pHioIf->IsConnected(pInfo->m_nHioIfID) ) continue; HIO2IF_RESULT result = pApp->m_pHioIf->ReadFree( pInfo->m_nHioIfID, MULTI_NNGC2PC_ADDR, (LPVOID)&(pInfo->m_stPacket), MULTI_BUFFER_SIZE, pInfo->m_bSync); pView = GetActiveView(pInfo->m_nHioIfID); if ( HIO2IF_SUCCESS(result) && (pView != NULL) ) pView->PostMessage(WM_USER, CMultiView::EVENCT_RECEIVED, 0); #endif } // Read for roughly each 1V Sleep(1000 / 60); } return 0; } /////////////////////////////////////////////////////////////////////////////// // // CMultiApp - Host I/O API interface // //----------------------------------------------------------------------------- BOOL CMultiApp::HioIfInit() { // initialization if ( HIO2IF_FAILED(m_pHioIf->Init()) ) return FALSE; // open the detected number of EXI channels for (int i=0; iGetDeviceCount(); i++) { HIO2IF_ID id; HIO2DevicePath pPath = m_pHioIf->GetDevicePath(i); if ( HIO2IF_FAILED(m_pHioIf->Open(pPath, HioIfEventCallback, id)) ) return FALSE; LPAPPINFO pInfo = new APPINFO; #ifndef HW0 pInfo->m_pDevice = new TCHAR [lstrlen(pPath) + 1]; lstrcpy((LPSTR)pInfo->m_pDevice, pPath); #else // HW0 pInfo->m_pDevice = pPath; #endif // HW0 pInfo->m_nHioIfID = id; m_cInfoList.AddTail(pInfo); } // update displayed PC time, create thread to run ReadFree() from CHioIf DWORD dwTmp; m_bThreadBreak = TRUE; m_hThread = ::CreateThread(NULL, 0, PollingThread, (LPVOID)this, 0, &dwTmp); // wait until thread launches // set m_bThreadBreak to FALSE within the PollingThread function) while ( m_bThreadBreak ) ; // when protocol communication is taking place, call HIO2IF_EVENT_CALLBACK to go from HioIf // to Read return TRUE; } //----------------------------------------------------------------------------- void CMultiApp::CreateInfo() { POSITION pos = GetFirstDocTemplatePosition(); ASSERT(pos != NULL); CMultiDocTemplate* pDocTemplate = static_cast(GetNextDocTemplate(pos)); for (int i=0; i(pDocTemplate->OpenDocumentFile(NULL, TRUE)); pDoc->m_nHioIfID = pInfo->m_nHioIfID; pDoc->UpdateTitle(); } } //----------------------------------------------------------------------------- BOOL CMultiApp::HioIfExit() { // terminate three if PollingThread is valid StopPollingThread(); m_pHioIf->EnterCriticalSection(); m_pHioIf->Exit(); // HIO termination m_pHioIf->LeaveCriticalSection(); m_cInfoList.Clear(); return TRUE; } //----------------------------------------------------------------------------- void CMultiApp::StopPollingThread() { // terminate three if PollingThread is valid if ( m_hThread != INVALID_HANDLE_VALUE ) { // halt the EXI thread m_bThreadBreak = TRUE; WaitForSingleObject(m_hThread,1000*30); CloseHandle(m_hThread); m_hThread = INVALID_HANDLE_VALUE; } } void CMultiApp::Connect(HIO2IF_ID id) { m_pHioIf->EnterCriticalSection(); int nIndex = m_cInfoList.IndexOf((LPVOID)id, MultiCompID); LPAPPINFO pInfo = m_cInfoList.GetItem(nIndex); if ( HIO2IF_FAILED(m_pHioIf->Open(pInfo->m_pDevice, HioIfEventCallback, id)) ) { MessageBox(NULL, "reopen failed", "ERROR", MB_OK); } m_pHioIf->LeaveCriticalSection(); } void CMultiApp::Disconnect(HIO2IF_ID id) { m_pHioIf->EnterCriticalSection(); m_pHioIf->Close(id); m_pHioIf->LeaveCriticalSection(); CMultiView* pView = GetActiveView(id); if ( pView != NULL ) pView->PostMessage(WM_USER, CMultiView::EVENT_DISCONNECT, 0); } void CMultiApp::CreatePcTime(MULTI_PACKET* pPacket) { struct tm *pLocalTime; __time64_t lTime; _time64(&lTime); pLocalTime = _localtime64(&lTime); pPacket->mon = pLocalTime->tm_mon; pPacket->mday = pLocalTime->tm_mday; pPacket->hour = pLocalTime->tm_hour; pPacket->min = pLocalTime->tm_min; pPacket->sec = pLocalTime->tm_sec; pPacket->msec = 0; strcpy(pPacket->string, "PC TIME"); } /////////////////////////////////////////////////////////////////////////////// // // CMultiApp // BEGIN_MESSAGE_MAP(CMultiApp, CWinApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) // Standard file based document commands ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) END_MESSAGE_MAP() // CMultiApp construction CMultiApp::CMultiApp() { // TODO : add construction code here, // Place all significant initialization in InitInstance } // The one and only CMultiApp object CMultiApp theApp; // CMultiApp initialization BOOL CMultiApp::InitInstance() { // InitCommonControls() is required on Windows XP if an application // manifest specifies use of ComCtl32.dll version 6 or later to enable // visual styles. Otherwise, any window creation will fail. InitCommonControls(); CWinApp::InitInstance(); // Initialize OLE libraries if (!AfxOleInit()) { AfxMessageBox(IDP_OLE_INIT_FAILED); return FALSE; } AfxEnableControlContainer(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need // Change the registry key under which our settings are stored // TODO : You should modify this string to be something appropriate // such as the name of your company or organization SetRegistryKey(_T("Local AppWizard-Generated Applications")); LoadStdProfileSettings(4); // Load standard INI file options (including MRU) ////////// for multiApp ////////// m_pHioIf = Hio2CreateInterface(); if ( !HioIfInit() ) { MessageBox(NULL, m_pHioIf->GetMessage(), "ERROR", (MB_OK | MB_ICONWARNING)); m_cInfoList.Clear(); return FALSE; } // Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views CMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate(IDR_multiTYPE, RUNTIME_CLASS(CMultiDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CMultiView)); if (!pDocTemplate) return FALSE; AddDocTemplate(pDocTemplate); // create main MDI Frame window CMainFrame* pMainFrame = new CMainFrame; if (!pMainFrame || !pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; // call DragAcceptFiles only if there's a suffix // In an MDI app, this should occur immediately after setting m_pMainWnd // Parse command line for standard shell commands, DDE, file open CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line. Will return FALSE if // app was launched with /RegServer, /Register, /Unregserver or /Unregister. #if 0 if (!ProcessShellCommand(cmdInfo)) return FALSE; #endif // The main window has been initialized, so show and update it pMainFrame->ShowWindow(m_nCmdShow); pMainFrame->UpdateWindow(); ////////// for multiApp ////////// // create a window for each EXI channel CreateInfo(); return TRUE; } // CMultiApp message handlers int CMultiApp::ExitInstance() { ////////// for multiApp ////////// HioIfExit(); Hio2ReleaseInterface(m_pHioIf); return CWinApp::ExitInstance(); } // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // App command to run the dialog void CMultiApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); }