// ODDE.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "ODDE.h" #include "ODDEDlg.h" #include // for sin, cos #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CODDEApp BEGIN_MESSAGE_MAP(CODDEApp, CWinApp) //{{AFX_MSG_MAP(CODDEApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CODDEApp construction CODDEApp::CODDEApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance m_nTimerID = 0; m_nTimerRate = 1000;// 1 sec; m_bUseFloatDataType = FALSE; // use double m_bKeepColumnType = FALSE; // always turn to numeric columns } ///////////////////////////////////////////////////////////////////////////// // The one and only CODDEApp object CODDEApp theApp; const int DEMO_DDE_TIMER_ID = 666; const int NUM_PTS_PER_ONE_TIME_TRANSFER = 2000; const int NUM_PTS_PER_REAL_TIME_TRANSFER = 10; const char szcWksRealTime[] = "RealTime"; const char szcWksOneTime[] = "OneTime"; ///////////////////////////////////////////////////////////////////////////// // CODDEApp initialization BOOL CODDEApp::InitInstance() { // 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. #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif CODDEDlg dlg; m_pMainWnd = &dlg; int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; } /////////////////////////////////////////////////////// // DDEDEMO specific functions /////////////////////////////////////////////////////// // return TRUE if message is processed, return FALSE for default handling BOOL CODDEApp :: DoWindowProc(CWnd *pWnd, UINT message, WPARAM wParam, LPARAM lParam) { if(WM_DDE_ACK == message) { TRACE("DDE message WM_DDE_ACK\n"); m_OriginServer.On_WM_DDE_ACK(pWnd->m_hWnd, wParam, lParam); return TRUE; } else if(WM_DDE_TERMINATE == message) { TRACE("DDE message WM_DDE_TERMINATE\n"); m_OriginServer.On_WM_DDE_TERMINATE(pWnd->m_hWnd); return TRUE; } return FALSE; } BOOL CODDEApp :: SendData(int nRows, LPCTSTR lpcszWksName, WORD wOrginDDEFormat) // we will have several dataset prepared before hand { int nColumns = 4;// always send 4 columns in this example static INT count = 0; static DWORD init_time = 0; // initialize the time only once if(init_time == 0) init_time = GetCurrentTime(); // data area size, depends on rows and columns DWORD length = nColumns * nRows * (m_bUseFloatDataType? sizeof(float) : sizeof(double)); /* double is the best data type * for Origin. * Currently Origin only accept * float and double. */ HANDLE hmem = GlobalAlloc(GHND | GMEM_DDESHARE, (LONG)sizeof(DDEPOKE) + (DWORD)sizeof(DataWorkSheet) + length + 2); DDEPOKE FAR * lpPokeData; lpPokeData = (DDEPOKE FAR *)GlobalLock(hmem); lpPokeData->fRelease = TRUE; lpPokeData->cfFormat = (short)m_OriginServer.GetOriginDDEClipboardFormat(); DataWorkSheet FAR * lpWorksheet; // move pointer to location in lpPokeData's memory at Value lpWorksheet = (DataWorkSheet FAR *)lpPokeData->Value; if(m_bUseFloatDataType) lpWorksheet->wFormat = DDE_DATA_FLOAT | wOrginDDEFormat; else lpWorksheet->wFormat = DDE_DATA_DOUBLE | wOrginDDEFormat; if(m_bKeepColumnType) lpWorksheet->wFormat |= DDE_DATA_KEEP_TYPE; lpWorksheet->nColumns = nColumns; lpWorksheet->nRows = nRows; lpWorksheet->nColumnBegin = 0; /* the nRowBegin is ignored for appending */ /* we are now ready to get some * data */ double *lpData; lpData = (double *) lpWorksheet->data; float *lpfData; lpfData = (float *) lpWorksheet->data; /* the sample data consist of 4 columns * col(1)= count * col(2)= sin * col(3)= cos * col(4)= time */ #define DATA_ARRAY(m,n) lpData[(n) + (m) * nRows] #define FDATA_ARRAY(m,n) lpfData[(n) + (m) * nRows] /* data are stored column by column so that * data in each column are continuous */ int jj; double findex, col2, col3, time; for(jj=0; jj < nRows; jj++) { col2 = sin((double)count/300.0) * ( 1.0 + (0.1*rand())/RAND_MAX); col3 = cos((double)count/300.0) * ( 1.0 + (0.1*rand())/RAND_MAX); time = (GetCurrentTime()-init_time)/1000.0; findex = count++; if( m_bUseFloatDataType ) { FDATA_ARRAY(0,jj) = findex; FDATA_ARRAY(1,jj) = col2; FDATA_ARRAY(2,jj) = col3; FDATA_ARRAY(3,jj) = time; } else { DATA_ARRAY(0,jj) = findex; DATA_ARRAY(1,jj) = col2; DATA_ARRAY(2,jj) = col3; DATA_ARRAY(3,jj) = time; } } /* now we are all done with the * dde data block */ GlobalUnlock(hmem); if(!m_OriginServer.SendData(hmem, lpcszWksName, wOrginDDEFormat)) { GlobalFree(hmem); return FALSE; } // eles the memory in hmem will be released by the server app return TRUE; } BOOL CODDEApp :: DoOneTimeDataTransfer() { if(!IsServerRunning()) return FALSE; return SendData(NUM_PTS_PER_ONE_TIME_TRANSFER, szcWksOneTime, 0); // send nextdataset into column 4 } void CODDEApp :: StartRealTimeTransfer(CWnd *pWnd) { ASSERT(m_nTimerID == 0); m_nTimerID = pWnd->SetTimer(DEMO_DDE_TIMER_ID, m_nTimerRate, NULL); } void CODDEApp :: StopRealTimeTransfer(CWnd *pWnd) { ASSERT(m_nTimerID); pWnd->KillTimer(m_nTimerID); m_nTimerID = 0; } void CODDEApp :: ProcessRealTimeTransfer(int nEventID, CWnd *pWnd) { if(nEventID != m_nTimerID) return; ASSERT(m_nTimerID); if(!IsServerRunning()) return ; SendData(NUM_PTS_PER_REAL_TIME_TRANSFER, szcWksRealTime, DDE_DATA_APPEND); } BOOL CODDEApp :: DoOpenServer(CWnd *pWnd) { if(!m_OriginServer.ConnectServer(pWnd->m_hWnd, m_strCmdLine)) return FALSE; return TRUE; } //IV 04/07/99 t3291 FINISH_MOVE_DDEDEMO_32BIT BOOL CODDEApp::OnCommandString(LPCTSTR lptsrCommand) { return m_OriginServer.SendCommandString(lptsrCommand); } //end FINISH_MOVE_DDEDEMO_32BIT