/*----------------------------------------------------------------------------*\ | | | dialog.c - Dialog functions for Timer Device Driver Test Application | | | | | | History: | | Created Glenn Steffler (w-GlennS) 29-Jan-1990 | | | \*----------------------------------------------------------)-----------------*/ /*----------------------------------------------------------------------------*\ | | | i n c l u d e f i l e s | | | \*----------------------------------------------------------------------------*/ #include #include #include #include #include #include "ta.h" #define abs(x) ( (x) < 0 ? -(x) : (x) ) /*----------------------------------------------------------------------------*\ | | | g l o b a l v a r i a b l e s | | | \*----------------------------------------------------------------------------*/ extern LPTIMECALLBACK lpTimeCallback; // call back function entry point extern BOOL bHandlerHit; extern WORD wHandlerError; extern HWND hwndApp; static char *szPerOne[] = { "One","Per" }; HWND hdlgModeless = NULL; HWND hdlgDelay = NULL; int nEvents = 0; EVENTLIST EventList[MAXEVENTS]; /*----------------------------------------------------------------------------*\ | ErrMsg - Opens a Message box with a error message in it. The user can | | select the OK button to continue | \*----------------------------------------------------------------------------*/ void PASCAL ErrMsg(char *sz) { MessageBox(NULL,sz,NULL,MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2|MB_SYSTEMMODAL); } /*----------------------------------------------------------------------------*\ | fnFileDlg (hDlg, uiMessage, wParam, lParam) | | | | Description: | | | | This function handles the messages for the delay dialog box. When | | the ADD, or REMOVE options are chosen, a timer event is either added | | or removed from the system respectively. | | | | Arguments: | | hDlg window handle of dialog window | | uiMessage message number | | wParam message-dependent | | lParam message-dependent | | | | Returns: | | TRUE if message has been processed, else FALSE | | | \*----------------------------------------------------------------------------*/ BOOL FAR PASCAL fnFileDlg( HWND hDlg, unsigned uiMessage, UINT wParam, LONG lParam ) { switch (uiMessage) { case WM_COMMAND: switch (wParam) { case IDOK: EndDialog(hDlg,TRUE); break; case IDCANCEL: EndDialog(hDlg,FALSE); break; } break; case WM_INITDIALOG: // SetDlgItemText(hDlg,IDOK,szText); return TRUE; } return FALSE; } /*----------------------------------------------------------------------------*\ | fnDelayDlg (hDlg, uiMessage, wParam, lParam) | | | | Description: | | | | This function handles the messages for the delay dialog box. When | | the ADD, or REMOVE options are chosen, a timer event is either added | | or removed from the system respectively. | | | | Arguments: | | hDlg window handle of dialog window | | uiMessage message number | | wParam message-dependent | | lParam message-dependent | | | | Returns: | | TRUE if message has been processed, else FALSE | | | \*----------------------------------------------------------------------------*/ BOOL FAR PASCAL fnDelayDlg( HWND hDlg, unsigned uiMessage, UINT wParam, LONG lParam ) { static int piTabs[5] = { 0, 5*4, 10*4, 15*4, 20*4 }; HWND hWnd; int nID,i,i1; char szTemp[100]; EVENTLIST *pEventList; TIMEREVENT *pEvent; WORD error; switch (uiMessage) { case MM_TIMEEVENT: if( EventList[LOWORD(lParam)].bPeriodic ) { bHandlerHit = TRUE; EventList[LOWORD(lParam)].dwCount++; EventList[LOWORD(lParam)].bHit = TRUE; } else { i = (int)EventList[LOWORD(lParam)].teEvent.wDelay; error = (int)EventList[LOWORD(lParam)].dtime - i; if (error < 0) wsprintf(szTemp,"%dms OneShot was %dms early",-i,error); else if (error > 0) wsprintf(szTemp,"%dms OneShot was %dms late",i,error); else wsprintf(szTemp,"%dms OneShot was on time",i); MessageBox(NULL,szTemp,NULL,MB_OK|MB_ICONEXCLAMATION|MB_TASKMODAL); hWnd = GetDlgItem(hDlg,LB_DELAY); /* events in listbox */ i1 = (int)SendMessage(hWnd,LB_GETCOUNT,0,0l); for( i=1; i < i1; i++ ) { SendMessage(hWnd,LB_GETTEXT,i,(LONG)(LPSTR)szTemp); sscanf( szTemp+strlen(szTemp)-4, "%x", &nID ); if( nID == wParam ) { // compare ID's - kill if same nEvents--; bHandlerHit = TRUE; EventList[LOWORD(lParam)].bActive = FALSE; SendMessage(hWnd,LB_DELETESTRING,i,0l); break; } } } return TRUE; case WM_COMMAND: DelayDlgCmd( hDlg, wParam, lParam ); break; case WM_CLOSE: DestroyWindow( hDlg ); hdlgModeless = NULL; hdlgDelay = NULL; return TRUE; case WM_INITDIALOG: hdlgDelay = hDlg; hWnd = GetDlgItem(hDlg,LB_DELAY); SendMessage(hWnd,LB_SETTABSTOPS, sizeof(piTabs)/sizeof(int),(LONG)(LPSTR)piTabs); SendMessage(hWnd,LB_RESETCONTENT,0,0l); SendMessage(hWnd,LB_ADDSTRING,0,(LONG)(LPSTR)"[none]"); for( pEventList=EventList,i=0; i < MAXEVENTS ; i++,pEventList++) { if( pEventList->bActive ) { pEvent = &( pEventList->teEvent ); wsprintf(szTemp,"%d\t%d\t%d\t %s : %4x", pEventList->wStart, pEvent->wDelay, pEvent->wResolution, (LPSTR)szPerOne[pEventList->bPeriodic], pEventList->nID); SendMessage(hWnd,LB_ADDSTRING,0,(LONG)(LPSTR)szTemp); } } SendMessage(hWnd,LB_SETCURSEL,0,0l); return TRUE; } return FALSE; } /*----------------------------------------------------------------------------*\ | DelayDlgCmd( hDlg, wParam, lParam ) | | | | Description: | | | | Process the WM_COMMAND messages for the fnDelayDlg DIALOG. | | | | Arguments: | | hDlg window handle of dialog window | | wParam message-dependent | | lParam message-dependent | | | | Returns: | | abso-poso-litilly-nothin | | | \*----------------------------------------------------------------------------*/ void PASCAL DelayDlgCmd( HWND hDlg, UINT wParam, LONG lParam ) { HWND hWnd; int nStartEdit,nDelayEdit,nResolEdit,nID,i; BOOL b1,b2,b3,bPeriodic; char szTemp[100],szTemp2[100]; TIMEREVENT *pEvent; switch (wParam) { case ID_REMOVE: hWnd = GetDlgItem(hDlg,LB_DELAY); if( (i = (int)SendMessage(hWnd,LB_GETCURSEL,0,0l)) > 0 ) { SendMessage(hWnd,LB_GETTEXT,i,(LONG)(LPSTR)szTemp); sscanf( szTemp+strlen(szTemp)-4, "%x", &nID ); if( nID != 0 ) { SendMessage(hWnd,LB_DELETESTRING,i,0l); for( i=0; i < MAXEVENTS; i++ ) { if( EventList[i].nID == nID ) { if( EventList[i].bActive ) { EventList[i].bActive = FALSE; timeKillEvent(nID); nEvents--; break; } else { ErrMsg( "Isn't registered in Queue!" ); break; } } } SendMessage(hWnd,LB_SETCURSEL,0,0l); PostMessage(hDlg,WM_COMMAND,LB_DELAY, MAKELONG(hWnd,LBN_SELCHANGE)); break; } } MessageBeep( NULL ); break; case IDOK: case ID_ADD: hWnd = GetDlgItem(hDlg,LB_DELAY); nStartEdit = GetDlgItemInt( hDlg, ID_STARTEDIT, &b1, FALSE ); nDelayEdit = GetDlgItemInt( hDlg, ID_DELAYEDIT, &b2, FALSE ); nResolEdit = GetDlgItemInt( hDlg, ID_RESOLEDIT, &b3, FALSE ); bPeriodic = (int)SendDlgItemMessage(hDlg,ID_PERIODIC,BM_GETCHECK,0,0l); if( nID = (b1 && b2 && b3) ) { for( i=0; i < MAXEVENTS; i++ ) { if( !EventList[i].bActive ) break; } if( i >= MAXEVENTS ) { nID = 0; break; } pEvent = &( EventList[i].teEvent ); pEvent->wDelay = nDelayEdit; pEvent->wResolution = nResolEdit; pEvent->dwUser = i; pEvent->wFlags = ((bPeriodic)?(TIME_PERIODIC):(TIME_ONESHOT)); pEvent->lpFunction = lpTimeCallback; EventList[i].bActive = TRUE; EventList[i].bPeriodic = bPeriodic; EventList[i].bHit = FALSE; EventList[i].dwCount = 0l; EventList[i].dwError = 0l; EventList[i].wStart = nStartEdit; EventList[i].dtimeMin = 0x7FFFFFFF; EventList[i].dtimeMax = 0; EventList[i].dtime = 0; EventList[i].time = timeGetTime(); if( (nID = timeSetEvent(pEvent->wDelay, pEvent->wResolution, pEvent->lpFunction, pEvent->dwUser, pEvent->wFlags)) == NULL ) { EventList[i].bActive = FALSE; break; } // SetTimer call must return non-NULL ID to signify a valid event nEvents++; EventList[i].nID = nID; wsprintf(szTemp,"%d\t%d\t%d\t %s : %4x", nStartEdit,nDelayEdit,nResolEdit,(LPSTR)szPerOne[bPeriodic],nID); SendMessage(hWnd,LB_ADDSTRING,0,(LONG)(LPSTR)szTemp); SendMessage(hWnd,LB_SETCURSEL,0,0l); PostMessage(hDlg,WM_COMMAND,LB_DELAY,MAKELONG(hWnd,LBN_SELCHANGE)); } if( wParam == IDOK ) { PostMessage( hDlg, WM_CLOSE, 0, 0l ); break; } if( !nID ) { MessageBeep( NULL ); } break; case LB_DELAY: switch( HIWORD(lParam) ) { case LBN_SELCHANGE: i = (int)SendMessage(LOWORD(lParam),LB_GETCURSEL,0,0l); if( i == 0 ) { SetDlgItemText(hDlg,ID_STARTEDIT,""); SetDlgItemText(hDlg,ID_DELAYEDIT,""); SetDlgItemText(hDlg,ID_RESOLEDIT,""); SendDlgItemMessage(hDlg,ID_PERIODIC,BM_SETCHECK,FALSE,0l); } else if( i != LB_ERR ) { SendMessage(LOWORD(lParam),LB_GETTEXT,i,(LONG)(LPSTR)szTemp); sscanf( szTemp, "%d %d %d %s : %x", &nStartEdit,&nDelayEdit,&nResolEdit,szTemp2,&nID); bPeriodic = (lstrcmp( szTemp2, szPerOne[1] ) == 0); SetDlgItemInt(hDlg,ID_STARTEDIT,nStartEdit,FALSE); SetDlgItemInt(hDlg,ID_DELAYEDIT,nDelayEdit,FALSE); SetDlgItemInt(hDlg,ID_RESOLEDIT,nResolEdit,FALSE); SendDlgItemMessage(hDlg,ID_PERIODIC,BM_SETCHECK,bPeriodic,0l); } else break; break; } break; case IDCANCEL: PostMessage( hDlg, WM_CLOSE, 0, 0l ); break; } return; } /*----------------------------------------------------------------------------*\ | KillAllEvents(void ) | | | | Description: | | Kills all outstanding events when windows exits | | | | Arguments: | | | | Returns: | | Absolutely nothing | | | \*----------------------------------------------------------------------------*/ void PASCAL KillAllEvents( void ) { int i; for( i=0; i < MAXEVENTS; i++ ) { if( EventList[i].bActive ) { timeKillEvent( (UINT)EventList[i].nID ); } } } /*----------------------------------------------------------------------------*\ | TimeCallback( wID, dwUser ) | | | | Description: | | The routine which processes the timer interrupt call backs. | | Simply adds one to the long int corresponding to lParam in the | | table of call back function counts. This essentionally means the | | number of times this routine is called for the certain interrupts | | is recorded. | | | | Arguments: | | wID ID returned from timeSetTimerEvent call | | dwUser value passed in event structure to said function. | | | | Returns: | | Absolutely nothing | | | \*----------------------------------------------------------------------------*/ void FAR PASCAL TimeCallback( UINT wID, UINT msg, DWORD dwUser, DWORD dwTime, DWORD dw2) { #define i (LOWORD(dwUser)) DWORD time; time = timeGetTime(); EventList[i].dtime = time - EventList[i].time; EventList[i].dtimeMin = min(EventList[i].dtime,EventList[i].dtimeMin); EventList[i].dtimeMax = max(EventList[i].dtime,EventList[i].dtimeMax); EventList[i].time = time; if( !EventList[i].bActive ) { wHandlerError++; } else if( EventList[i].bPeriodic ) { bHandlerHit = TRUE; EventList[i].dwCount++; if (abs((int)EventList[i].dtime-(int)EventList[i].teEvent.wDelay) > (int)EventList[i].teEvent.wResolution) EventList[i].dwError++; EventList[i].bHit = TRUE; } else if( hdlgDelay != NULL ) { PostMessage(hdlgDelay,MM_TIMEEVENT,wID,dwUser); } else { nEvents--; bHandlerHit = TRUE; EventList[i].bActive = FALSE; } #undef i }