home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / pcmagazi / 1992 / 18 / wtime.c < prev    next >
C/C++ Source or Header  |  1992-10-26  |  44KB  |  1,221 lines

  1. #include "WTIME.H"
  2. #include<ctype.h>
  3. #include<dos.h>
  4. #include<errno.h>
  5. #include<time.h>
  6. #ifdef __TURBOC__
  7.     #define _dostime_t dostime_t
  8.     #define _dosdate_t dosdate_t
  9. #endif
  10. int PASCAL WinMain(HANDLE hInstance,HANDLE hPrevInstance,
  11. LPSTR lpszCmdLine,int nCmdShow){
  12.     MSG msg;
  13.     int nRc;
  14.     lstrcpy(szAppName,"WTime");
  15.     lstrcpy(szHelpFile,"WTime.hlp");
  16.     iInHelp=0;
  17.     hInst=hInstance;
  18.     iTargetTime=TIMER_TARGET_INACTIVE;
  19.     wEachSecondCmdToPost=wTimedTargetCmdToPost=
  20.     TIMER_NEVER_POST;
  21.     if(lpszCmdLine){
  22.         LPSTR tmpptr=lpszCmdLine;
  23.         while(*tmpptr){
  24.             if(*tmpptr=='a'||*tmpptr=='A'){
  25.                 /*CNICE-*/
  26.                 if(
  27.                 (tmpptr[1]=='u'||tmpptr[1]=='U')&&
  28.                 (tmpptr[2]=='t'||tmpptr[2]=='T')&&
  29.                 (tmpptr[3]=='o'||tmpptr[3]=='O')&&
  30.                 (tmpptr[4]=='m'||tmpptr[4]=='M')&&
  31.                 (tmpptr[5]=='a'||tmpptr[5]=='A')&&
  32.                 (tmpptr[6]=='t'||tmpptr[6]=='T')&&
  33.                 (tmpptr[7]=='i'||tmpptr[7]=='I')&&
  34.                 (tmpptr[8]=='c'||tmpptr[8]=='C')
  35.                 ){
  36.                     /*CNICE+*/
  37.                     iAutomatic=1;
  38.                 }
  39.                 break;
  40.             }
  41.             else tmpptr++;
  42.         }
  43.     }
  44.     if(!hPrevInstance){
  45.         if((nRc=nCwRegisterClasses())==-1){
  46.             if(iAutomatic){
  47.                 LoadString(hInst,IDS_ERR_REGISTER_CLASS,
  48.                 szString,sizeof(szString));
  49.                 MessageBox(NULL, szString, NULL,
  50.                 MB_ICONEXCLAMATION);
  51.             }
  52.             return 1;
  53.         }
  54.         else;
  55.     }
  56.     else{
  57.         if(!iAutomatic){
  58.             LoadString(hInst, IDS_ERR_MULT_INSTANCES,
  59.             szString,sizeof(szString));
  60.             MessageBox(NULL,szString,NULL,
  61.             MB_ICONEXCLAMATION);
  62.         }
  63.         return 1;
  64.     }
  65.     hWndMain = CreateWindow(
  66.                 szAppName,
  67.                 szAppName,
  68.                 WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|
  69.                 WS_MAXIMIZEBOX|WS_THICKFRAME|
  70.                 WS_CLIPCHILDREN|WS_OVERLAPPED,
  71.                 CW_USEDEFAULT,0,
  72.                 CW_USEDEFAULT,0,
  73.                 NULL,
  74.                 NULL,
  75.                 hInst,
  76.                 NULL);
  77.     if(hWndMain == NULL){
  78.         if(!iAutomatic){
  79.             LoadString(hInst,IDS_ERR_CREATE_WINDOW,
  80.             szString,sizeof(szString));
  81.             MessageBox(NULL,szString,NULL,
  82.             MB_ICONEXCLAMATION);
  83.         }
  84.         CwUnRegisterClasses();
  85.         return 1;
  86.     }
  87.     else{
  88.         int charWidth,charHeight,startX,startY;
  89.         TEXTMETRIC tm;
  90.         HDC devcon=GetDC(hWndMain);/* get device context */
  91.         GetTextMetrics(devcon,&tm);/* get text size info */
  92.         iRowHeight=tm.tmHeight; /* for multirow display */
  93.         charWidth=tm.tmAveCharWidth*60;
  94.         charHeight=tm.tmHeight*15;
  95.         ReleaseDC(hWndMain,devcon);/* release dev ctx */
  96.                                 /* center the screen */
  97.         startX=(GetSystemMetrics(SM_CXSCREEN)-charWidth)/2;
  98.         startY=(GetSystemMetrics(SM_CYSCREEN)-charHeight)
  99.         /2;
  100.                                 /* change window size */
  101.         SetWindowPos(hWndMain,NULL,startX,startY,charWidth,
  102.         charHeight,SWP_NOZORDER);
  103.     }
  104.     szDisplayString[0]=0;       /* no string for window */
  105.     szDisplayString2[0]=0;      /* no string for window */
  106.     ShowWindow(hWndMain,nCmdShow);
  107.     while(GetMessage(&msg,NULL,0,0)){
  108.         TranslateMessage(&msg);
  109.         DispatchMessage(&msg);
  110.     }
  111.  
  112.     CwUnRegisterClasses();
  113.     return msg.wParam;
  114. }
  115. LONG FAR PASCAL WndProc(HWND hWnd,WORD Message,
  116.                         WORD wParam,LONG lParam){
  117.     HMENU hMenu=0;
  118.     HBITMAP hBitmap=0;
  119.     HDC hDC;
  120.     PAINTSTRUCT ps;
  121.     int nRc=0;
  122.     switch(Message){
  123.     case WM_COMMAND:
  124.         if(iInHelp){
  125.             int help_topic=0;
  126.             iAutomatic=0;
  127.             iInHelp=0;
  128.             if(wParam==IDM_F_EXIT)help_topic=
  129.             HLP_WTIME_MEXIT;
  130.             else if(wParam==IDM_M_CALL)help_topic=
  131.             HLP_WTIME_MCALL;
  132.             else if(wParam==IDM_M_HANGUP)help_topic=
  133.             HLP_WTIME_MHANGUP;
  134.             else if(wParam==IDM_M_SETUP)help_topic=
  135.             HLP_WTIME_MSETUP;
  136.             else if(wParam==IDM_H_PROCEDURES)help_topic=
  137.             HLP_WTIME_MPROCS;
  138.             else if(wParam==IDM_H_USINGHELP)help_topic=
  139.             HLP_WTIME_MUSING;
  140.             else if(wParam==IDM_H_ABOUTWTIME)help_topic=
  141.             HLP_WTIME_MABOUT;
  142.             else MessageBox(hWnd,
  143.             "Could not find help topic","Program Error",
  144.             MB_ICONSTOP);
  145.             if(help_topic){
  146.                 if(!WinHelp(hWnd,szHelpFile,HELP_CONTEXT,
  147.                 help_topic)){
  148.                     MessageBox(NULL,"Could not start "
  149.                     "Windows Help\nor WTIME.HLP not found",
  150.                     "Windows Error",MB_ICONSTOP);
  151.                 }
  152.             }
  153.             break;
  154.         }
  155.         switch(wParam){
  156.         case IDM_F_EXIT:
  157.             PostMessage(hWnd,WM_CLOSE,0,0L);
  158.             break;
  159.         case IDM_M_SETUP:
  160.             iAutomatic=0;
  161.             {
  162.                 FARPROC lpfnCONFIGMsgProc,lpfnMsgFilter;
  163.                 /* first, hook messages for help */
  164.                 lpfnMsgFilter=
  165.                 MakeProcInstance((FARPROC)SetupDlgMsgHook,
  166.                 hInst);
  167.                 oldfilter=SetWindowsHook(WH_MSGFILTER,
  168.                 lpfnMsgFilter);
  169.                 /* now do the dialog box */
  170.                 lpfnCONFIGMsgProc=
  171.                 MakeProcInstance((FARPROC)CONFIGMsgProc,
  172.                 hInst);
  173.                 nRc=DialogBox(hInst,MAKEINTRESOURCE(100),
  174.                 hWnd, lpfnCONFIGMsgProc);
  175.                 FreeProcInstance(lpfnCONFIGMsgProc);
  176.                 /* unhook the message queue */
  177.                 UnhookWindowsHook(WH_MSGFILTER,
  178.                 lpfnMsgFilter);
  179.                 FreeProcInstance(lpfnMsgFilter);
  180.             }
  181.             iReadyToGo=iGetConfigurationInformation();
  182.             SetCallOption();
  183.             szDisplayString[0]=0;
  184.             UpdateStatusLine();
  185.             break;
  186.         case IDM_H_PROCEDURES:
  187.             iAutomatic=0;
  188.             if(!WinHelp(hWnd,szHelpFile,HELP_CONTEXT,
  189.             HLP_WTIME_MPROCS)){
  190.                 MessageBox(NULL,
  191.                 "Could not start Windows Help\n"
  192.                 "or WTIME.HLP missing",
  193.                 "Windows Error",MB_ICONSTOP);
  194.             }
  195.             break;
  196.         case IDM_H_USINGHELP:
  197.             iAutomatic=0;
  198.             if(!WinHelp(hWnd,szHelpFile,
  199.             HELP_HELPONHELP,0)){
  200.                 MessageBox(NULL,
  201.                 "Could not start Windows Help\n"
  202.                 "or WTIME.HLP not present",
  203.                 "Windows Error",MB_ICONSTOP);
  204.             }
  205.             break;
  206.         case IDM_H_ABOUTWTIME:
  207.             iAutomatic=0;
  208.             {
  209.                 FARPROC lpfnABOUTMsgProc;
  210.                 lpfnABOUTMsgProc=
  211.                 MakeProcInstance((FARPROC)ABOUTMsgProc,
  212.                 hInst);
  213.                 nRc=DialogBox(hInst,MAKEINTRESOURCE(600),
  214.                 hWnd,lpfnABOUTMsgProc);
  215.                 FreeProcInstance(lpfnABOUTMsgProc);
  216.             }
  217.             break;
  218.         case IDM_M_HANGUP:
  219.             if(!iCleaningUp){
  220.                 iAutomatic=0;
  221.                 EnableMenuItem(hMainMenu,IDM_M_HANGUP,
  222.                 MF_GRAYED|MF_BYCOMMAND);
  223.                 FailCall("User chose Modem|Hang Up");
  224.             }
  225.             break;
  226.         case IDM_M_CALL:
  227.             if(iInCall||iCleaningUp){MessageBeep(0);break;}
  228.             iThisRunFailed=1;
  229.             iInCall=1;
  230.             iCleaningUp=0;
  231.             iMustHangUp=0;
  232.             szFailString[0]=0;
  233.             szCommError[0]=0;
  234.             iTimerCount=TIMER_TOTAL_CALLTIME;
  235.             iTargetTime=TIMER_TARGET_INACTIVE;
  236.             EnableMenuItem(hMainMenu,IDM_M_CALL,
  237.             MF_GRAYED|MF_BYCOMMAND);
  238.             EnableMenuItem(hMainMenu,IDM_M_SETUP,
  239.             MF_GRAYED|MF_BYCOMMAND);
  240.             EnableMenuItem(hMainMenu,IDM_M_HANGUP,
  241.             MF_ENABLED|MF_BYCOMMAND);
  242.             if(!iHaveTimer){            /* start timer */
  243.                 if(SetTimer(hWnd,1,1000,NULL))iHaveTimer=1;
  244.                 else {
  245.                     FailCall("No timers available");
  246.                     break;
  247.                 }
  248.             }
  249.             {                           /* get COM port */
  250.                 LPSTR string;
  251.                 if(string=init_comm_port()){
  252.                     FailCall(string);
  253.                     break;
  254.                 }
  255.             }
  256.             UpdateStatusLineText("Initializing modem");
  257.             WaitSecondsCommand(TIMER_FIRST_ESCAPE,
  258.             IDM_CMD_FIRST_ESCAPE);
  259.             break;
  260.         case IDM_CMD_FIRST_ESCAPE:
  261.             UpdateStatusLineText("Sending "
  262.             "escape sequence");
  263.             if(WriteComm(dcb.Id,"+++",3)!=3){
  264.                 FailCall("Could not get "
  265.                 "modem's attention");
  266.                 break;
  267.             }
  268.             WaitSecondsCommand(TIMER_AT_CMD,
  269.             IDM_CMD_AT_CMD);
  270.             break;
  271.         case IDM_CMD_AT_CMD:
  272.             if(!iInCall)break;
  273.             UpdateStatusLineText("Resetting modem");
  274.             if(WriteComm(dcb.Id,"ATZ\n\r",5)!=5){
  275.                 FailCall("Could not initialize modem");
  276.                 break;
  277.             }
  278.             WaitSecondsCommand(TIMER_FIRST_RESET,
  279.             IDM_CMD_DIALTIME);
  280.             break;
  281.         case IDM_CMD_DIALTIME:
  282.             if(!iInCall)break;
  283.             UpdateStatusLineText("Dialing modem");
  284.             iMustHangUp=1;
  285.             wsprintf(szString,"%s\n\r",
  286.             (LPSTR)szModemDialString);
  287.             if(WriteComm(dcb.Id,szString,lstrlen(szString))
  288.             !=(int)lstrlen(szString)){
  289.                 FailCall("Could not dial");
  290.                 break;
  291.             }
  292.             WaitSecondsCommand(TIMER_DIAL,
  293.             IDM_CMD_WAITDATA);
  294.             break;
  295.         case IDM_CMD_WAITDATA:
  296.             if(!iInCall)break;
  297.             {
  298.                 static int gotspecials=0;
  299.                 static char newbuf[101],*p;
  300.                 int read_chars,got_firstspecial,need_chars;
  301.                 NISTDATA *nist;
  302.                 LPSTR failstring=NULL;
  303.                 /* on first call, chg to call ea. second */
  304.                 if(wTimedTargetCmdToPost==
  305.                 IDM_CMD_WAITDATA){
  306.                     wEachSecondCmdToPost=IDM_CMD_WAITDATA;
  307.                     iTargetTime=TIMER_TARGET_INACTIVE;
  308.                     wTimedTargetCmdToPost=TIMER_NEVER_POST;
  309.                     gotspecials=0;
  310.                     p=newbuf;
  311.                     UpdateStatusLineText("Looking for "
  312.                     "data");
  313.                 }
  314.                 /*
  315.                 **  now gather the data
  316.                 **  first, read 90 chars at a time
  317.                 **  we won't do anything until we find
  318.                 **  '*' or '#' three separate times
  319.                 **  then we'll show a string
  320.                 */
  321.                 GetDisplayCommError(dcb.Id,&comstat);
  322.                 read_chars=ReadComm(dcb.Id,
  323.                 p,100-(p-newbuf));
  324.                 if(read_chars<0)read_chars*=-1;
  325.                 if(gotspecials<3){
  326.                     while(read_chars--){
  327.                         if(*p=='#'||*p=='*')gotspecials++;
  328.                         p++;
  329.                     }
  330.                     p=newbuf;
  331.                     break;
  332.                 }
  333.                 /* ok we want to proceed, clean start */
  334.                 FlushComm(dcb.Id,1);    /* rx queue */
  335.                 p=newbuf;
  336.                 got_firstspecial=0;
  337.                 for(;;){
  338.                     p=newbuf;
  339.                     GetDisplayCommError(dcb.Id,&comstat);
  340.                     read_chars=ReadComm(dcb.Id,
  341.                     newbuf,100-sizeof(NISTDATA));
  342.                     if(read_chars<0)read_chars*=-1;
  343.                     while(read_chars--){
  344.                         if(*p=='*'||*p=='#'){
  345.                             got_firstspecial=1;
  346.                             nist=(NISTDATA *)p;
  347.                             break;
  348.                         }
  349.                     }
  350.                     if(got_firstspecial||!iInCall)break;
  351.                 }
  352.                 if(!iInCall)break;
  353.                 if(!got_firstspecial){  /* resync */
  354.                     p=newbuf;
  355.                     gotspecials=0;
  356.                     need_chars=sizeof(NISTDATA)-read_chars;
  357.                     break;
  358.                 }
  359.                 /*
  360.                 **  Now nist and p point to same char --
  361.                 **  that char is a special char
  362.                 **  there is room for the whole NISTDATA
  363.                 **  structure there. We need need_chars
  364.                 **  chars still to fill struct -- now we'll
  365.                 **  loop until we have our actual data
  366.                 **  and we'll convert it then, then we'll
  367.                 **  break out to wait for next special
  368.                 **  char
  369.                 */
  370.                 while(iInCall){
  371.                     GetDisplayCommError(dcb.Id,&comstat);
  372.                     read_chars=ReadComm(dcb.Id,p,
  373.                     need_chars);
  374.                     if(read_chars<0)read_chars*=-1;
  375.                     p+=read_chars;
  376.                     if(p>=nist->junk3)break;
  377.                 }
  378.                 /*
  379.                 **  if all valid data post ASAP
  380.                 */
  381.                 if(!iInCall)break;
  382.                 {
  383.                     struct tm tims,*tm_ptr;
  384.                     time_t Time;
  385.                     struct _dosdate_t dosdate;
  386.                     struct _dostime_t dostime;
  387.                     if(!isdigit((int)nist->year[0])||
  388.                     !isdigit((int)nist->year[1])||
  389.                     !isdigit((int)nist->month[0])||
  390.                     !isdigit((int)nist->month[1])||
  391.                     !isdigit((int)nist->day[0])||
  392.                     !isdigit((int)nist->day[1])||
  393.                     !isdigit((int)nist->hour[0])||
  394.                     !isdigit((int)nist->hour[1])||
  395.                     !isdigit((int)nist->minute[0])||
  396.                     !isdigit((int)nist->minute[1])||
  397.                     !isdigit((int)nist->second[0])||
  398.                     !isdigit((int)nist->second[1])){
  399.                         /* got invalid data so retry */
  400.                         gotspecials=0;
  401.                         p=newbuf;
  402.                         break;
  403.                     }
  404.                     tims.tm_year=
  405.                     (((int)nist->year[0]-'0')*10)+
  406.                     ((int)nist->year[1]-'0');
  407.                     if(tims.tm_year<90)tims.tm_year+=100;
  408.                     tims.tm_mon=
  409.                     (((int)nist->month[0]-'0')*10)+
  410.                     ((int)nist->month[1]-'0')-1;
  411.                     tims.tm_mday=
  412.                     (((int)nist->day[0]-'0')*10)+
  413.                     ((int)nist->day[1]-'0');
  414.                     tims.tm_hour=
  415.                     (((int)nist->hour[0]-'0')*10)+
  416.                     ((int)nist->hour[1]-'0');
  417.                     tims.tm_min=
  418.                     (((int)nist->minute[0]-'0')*10)+
  419.                     ((int)nist->minute[1]-'0');
  420.                     tims.tm_sec=
  421.                     (((int)nist->second[0]-'0')*10)+
  422.                     ((int)nist->second[1]-'0');
  423.                     tims.tm_isdst=-1;
  424.                     daylight=0;
  425.                     timezone=0L;
  426.                     if((Time=mktime(&tims))==-1L){
  427.                         failstring="Time conversion error";
  428.                         break;
  429.                     }
  430.                     timezone=-60L*(long)iTimeOffset;
  431.                     daylight=iUseDaylightSavings?~0:0;
  432.                     if(!(tm_ptr=localtime(&Time))){
  433.                         failstring="Local time error";
  434.                         break;
  435.                     }
  436.                     dosdate.day=
  437.                     (unsigned char)tm_ptr->tm_mday;
  438.                     dosdate.month=
  439.                     (unsigned char)(1+tm_ptr->tm_mon);
  440.                     dosdate.year=
  441.                     (unsigned int)1900+tm_ptr->tm_year;
  442.                     dostime.hour=
  443.                     (unsigned char)tm_ptr->tm_hour;
  444.                     dostime.minute=
  445.                     (unsigned char)tm_ptr->tm_min;
  446.                     dostime.second=
  447.                     (unsigned char)tm_ptr->tm_sec;
  448.                     if(_dos_settime(&dostime)){
  449.                         failstring="Couldn't set DOS time";
  450.                         break;
  451.                     }
  452.                     if(_dos_setdate(&dosdate)){
  453.                         failstring="Couldn't set DOS date";
  454.                         break;
  455.                     }
  456.                     UpdateStatusLineText("Time set");
  457.                 }
  458.                 /*
  459.                 **  clean up
  460.                 **  use failstring to drive failure
  461.                 */
  462.                 wEachSecondCmdToPost=TIMER_NEVER_POST;
  463.                 iTargetTime=TIMER_TARGET_INACTIVE;
  464.                 wTimedTargetCmdToPost=TIMER_NEVER_POST;
  465.                 if(failstring)FailCall(failstring);
  466.                 else{
  467.                     iInCall=0;
  468.                     iThisRunFailed=0;
  469.                     PostMessage(hWnd,WM_COMMAND,
  470.                     IDM_CMD_CALLDONE,0L);
  471.                 }
  472.             }
  473.             break;
  474.         case IDM_CMD_CALLDONE:
  475.             iCleaningUp=1;
  476.             iTargetTime=TIMER_TARGET_INACTIVE;
  477.             wEachSecondCmdToPost=wTimedTargetCmdToPost=
  478.             TIMER_NEVER_POST;
  479.             if(iGotComPort&&iMustHangUp){
  480.                 UpdateStatusLineText(iThisRunFailed?
  481.                 "Abort: waiting to send escape sequence":
  482.                 "Success: waiting to send escape "
  483.                 "sequence");
  484.                 iTimerCount=1000;
  485.                 WaitSecondsCommand(TIMER_PREBREAK,
  486.                 IDM_CMD_PREBREAK);
  487.                 break;
  488.             }
  489.             else goto break_is_done;
  490.         case IDM_CMD_PREBREAK:
  491.             GetDisplayCommError(dcb.Id,&comstat);
  492.             WriteComm(dcb.Id,"+++",3);
  493.             UpdateStatusLineText(iThisRunFailed?
  494.             "Abort: sending escape sequence":
  495.             "Success: sending escape sequence");
  496.             WaitSecondsCommand(TIMER_POSTBREAK,
  497.             IDM_CMD_POSTBREAK);
  498.             break;
  499.         case IDM_CMD_POSTBREAK:
  500.             UpdateStatusLineText(iThisRunFailed?
  501.             "Abort: sending hang-up sequence":
  502.             "Success: sending hang-up sequence");
  503.             WriteComm(dcb.Id,"ATH0\n\r",6);
  504.             /* fall through... */
  505.         case IDM_CMD_CALLQUIT:
  506. break_is_done:
  507.             iCleaningUp=0;
  508.             iTimerCount=0;
  509.             iTargetTime=TIMER_TARGET_INACTIVE;
  510.             wEachSecondCmdToPost=wTimedTargetCmdToPost=TIMER_NEVER_POST;
  511.             close_comm_port();
  512.             EnableMenuItem(hMainMenu,IDM_M_CALL,
  513.             MF_ENABLED|MF_BYCOMMAND);
  514.             EnableMenuItem(hMainMenu,IDM_M_SETUP,
  515.             MF_ENABLED|MF_BYCOMMAND);
  516.             EnableMenuItem(hMainMenu,IDM_M_HANGUP,
  517.             MF_GRAYED|MF_BYCOMMAND);
  518.             if(iAutomatic)PostMessage(hWnd,WM_CLOSE,0,0L);
  519.             if(!iAutomatic){
  520.                 if(!iThisRunFailed){
  521.                     MessageBox(hWnd,"Time and date\n"
  522.                     "successfully set","Call Complete",
  523.                     MB_ICONINFORMATION);
  524.                 }
  525.                 else{
  526.                     if(szFailString[0])MessageBox(hWnd,
  527.                     szFailString,"Time Set Aborted",
  528.                     MB_ICONSTOP);
  529.                     else MessageBox(hWnd,"Time and date\n"
  530.                     "not set","Call Complete",MB_ICONSTOP);
  531.                 }
  532.             }
  533.             szCommError[0]=0;
  534.             szDisplayString[0]=0;
  535.             UpdateStatusLine();
  536.             break;
  537.         default: return DefWindowProc(hWnd,Message,
  538.         wParam,lParam);
  539.         }
  540.         break;                      /* End of WM_COMMAND */
  541.     case WM_TIMER:
  542.         if(iTimerCount>0){
  543.             if(TIMER_NEVER_POST!=wEachSecondCmdToPost){
  544.             /* each second */
  545.                 PostMessage(hWnd,WM_COMMAND,
  546.                 wEachSecondCmdToPost,0L);
  547.             }
  548.             iTimerCount--;
  549.             if(iTimerCount==iTargetTime){
  550.                 /* timed execution... */
  551.                 if(wTimedTargetCmdToPost!=
  552.                 TIMER_NEVER_POST){
  553.                     PostMessage(hWnd,WM_COMMAND,
  554.                     wTimedTargetCmdToPost,0L);
  555.                 }
  556.                 iTargetTime=TIMER_TARGET_INACTIVE;
  557.             }
  558.             UpdateStatusLine();
  559.             if(!iTimerCount)FailCall("Call timed out");
  560.         }
  561.         break;
  562.     case WM_KEYDOWN:
  563.         if((wParam==VK_F1)){
  564.             PostMessage(hWnd,WM_COMMAND,IDM_H_PROCEDURES,
  565.             0);
  566.         }
  567.         else return DefWindowProc(hWnd,Message,
  568.         wParam,lParam);
  569.         break;
  570.     case WM_ENTERIDLE:
  571.         if((wParam==MSGF_MENU)&&
  572.         (GetKeyState(VK_F1)&0x8000)){
  573.             iInHelp=1;
  574.             PostMessage(hWnd,WM_KEYDOWN,VK_RETURN,0L);
  575.         }
  576.         break;
  577.     case WM_CREATE:
  578.         hMainMenu=((CREATESTRUCT *)lParam)->hMenu;
  579.         iReadyToGo=iGetConfigurationInformation();
  580.         if(iAutomatic){
  581.             if(iReadyToGo)PostMessage(hWnd,WM_COMMAND,
  582.             IDM_M_CALL,0L);
  583.             else PostMessage(hWnd,WM_CLOSE,0,0L);
  584.         }
  585.         else SetCallOption();
  586.         EnableMenuItem(hMainMenu,IDM_M_HANGUP,
  587.         MF_GRAYED|MF_BYCOMMAND);
  588.         break;
  589.     case WM_MOVE:
  590.         break;
  591.     case WM_SIZE:
  592.         break;
  593.     case WM_PAINT:
  594.         memset(&ps, 0x00, sizeof(PAINTSTRUCT));
  595.         hDC = BeginPaint(hWnd, &ps);
  596.         SetBkMode(hDC, OPAQUE);
  597.         SetTextColor(hDC,GetSysColor(COLOR_WINDOWTEXT));
  598.         SetBkColor(hDC,GetSysColor(COLOR_WINDOW));
  599.         if(szDisplayString[0]){
  600.             if(iTimerCount&&!iCleaningUp){
  601.                 wsprintf(szDisplayString2,"%s: %d "
  602.                 "second%s left",
  603.                 (LPSTR)szDisplayString,iTimerCount,
  604.                 iTimerCount==1?(LPSTR)"":(LPSTR)"s");
  605.             }
  606.             else lstrcpy(szDisplayString2,szDisplayString);
  607.         }
  608.         else{
  609.             if(iTimerCount&&!iCleaningUp){
  610.                 wsprintf(szDisplayString2,"%d second"
  611.                 "%s left",iTimerCount,iTimerCount==1?
  612.                 (LPSTR)"":(LPSTR)"s");
  613.             }
  614.             else lstrcpy(szDisplayString2,iReadyToGo?
  615.             "Ready to call":"Configuration needed");
  616.         }
  617.         TextOut(hDC,0,0,szDisplayString2,
  618.         lstrlen(szDisplayString2));
  619.         if(szCommError[0])TextOut(hDC,0,iRowHeight,
  620.         szCommError,lstrlen(szCommError));
  621.         EndPaint(hWnd, &ps);
  622.         break;
  623.     case WM_CLOSE:
  624.         if(iInCall){
  625.             iAutomatic=1;
  626.             FailCall("User quit");
  627.         }
  628.         else if(!iCleaningUp)DestroyWindow(hWnd);
  629.         break;
  630.     case WM_DESTROY:
  631.         WinHelp(hWnd,szHelpFile,HELP_QUIT,0);
  632.         PostQuitMessage(iAutomatic?iThisRunFailed:0);
  633.         break;
  634.     default:
  635.          return DefWindowProc(hWnd,Message,wParam,lParam);
  636.     }
  637.     return 0L;
  638. }                                   /* End of WndProc */
  639. BOOL FAR PASCAL CONFIGMsgProc(HWND hWndDlg,WORD Message,
  640. WORD wParam,LONG lParam){
  641.     switch(Message){
  642.     case WM_INITDIALOG:
  643.         cwCenter(hWndDlg, 0);
  644.         /* save window handle for help hook */
  645.         hWndSetupDlg=hWndDlg;
  646.         /* Load up the time zone list box */
  647.         iEst=SendDlgItemMessage(hWndDlg,
  648.         IDC_SETUPDLG_TIMEZONE,CB_ADDSTRING,NULL,
  649.         (LONG)(LPSTR)"Eastern Standard Time (New York)");
  650.         iCst=SendDlgItemMessage(hWndDlg,
  651.         IDC_SETUPDLG_TIMEZONE,CB_ADDSTRING,NULL,
  652.         (LONG)(LPSTR)"Central Standard Time (Chicago)");
  653.         iMtn=SendDlgItemMessage(hWndDlg,
  654.         IDC_SETUPDLG_TIMEZONE,CB_ADDSTRING,NULL,
  655.         (LONG)(LPSTR)"Mountain Time (Denver)");
  656.         iPst=SendDlgItemMessage(hWndDlg,
  657.         IDC_SETUPDLG_TIMEZONE,CB_ADDSTRING,NULL,
  658.         (LONG)(LPSTR)"Pacific Standard Time (Seattle)");
  659.         iOther=SendDlgItemMessage(hWndDlg,
  660.         IDC_SETUPDLG_TIMEZONE,CB_ADDSTRING,NULL,
  661.         (LONG)(LPSTR)"User-Specified TimeOffset in "
  662.         "WIN.INI");
  663.         if(iEst==CB_ERRSPACE||iEst==CB_ERR||
  664.         iCst==CB_ERRSPACE||iCst==CB_ERR||
  665.         iMtn==CB_ERRSPACE||iMtn==CB_ERR||
  666.         iPst==CB_ERRSPACE||iPst==CB_ERR||
  667.         iOther==CB_ERRSPACE||iOther==CB_ERR){
  668.              MessageBox(NULL,"Insufficient memory to "
  669.              "create list box",NULL,MB_ICONSTOP);
  670.              EndDialog(hWndDlg, FALSE);
  671.              break;
  672.         }
  673.         /* if no preexisting data do Reset Defaults */
  674.         if(iReadyToGo){                 /* current prefs */
  675.             for(;;){
  676.                 WORD i;
  677.                 /* set time zone */
  678.                 switch(iTimeOffset){
  679.                 case TZOFF_EST: i=(WORD)iEst; break;
  680.                 case TZOFF_CST: i=(WORD)iCst; break;
  681.                 case TZOFF_MTN: i=(WORD)iMtn; break;
  682.                 case TZOFF_PST: i=(WORD)iPst; break;
  683.                 default:      i=(WORD)iOther; break;
  684.                 };
  685.                 SendDlgItemMessage(hWndDlg,
  686.                 IDC_SETUPDLG_TIMEZONE,CB_SETCURSEL,i,0);
  687.                 /* set daylight savings preference */
  688.                 SendDlgItemMessage(hWndDlg,
  689.                 IDC_SETUPDLG_DAYLIGHT,BM_SETCHECK,
  690.                 iUseDaylightSavings?1:0,0);
  691.                 /* put in old dial string */
  692.                 SetDlgItemText(hWndDlg,
  693.                 IDC_SETUPDLG_DIALSTRING,szModemDialString);
  694.                 /* set right COM radio button */
  695.                 if(iComPort==1){
  696.                     CheckRadioButton(hWndDlg,
  697.                     IDC_SETUPDLG_COM1,
  698.                     IDC_SETUPDLG_COM4,IDC_SETUPDLG_COM1);
  699.                 }
  700.                 else if(iComPort==2){
  701.                     CheckRadioButton(hWndDlg,
  702.                     IDC_SETUPDLG_COM1,IDC_SETUPDLG_COM4,
  703.                     IDC_SETUPDLG_COM2);
  704.                 }
  705.                 else if(iComPort==3){
  706.                     CheckRadioButton(hWndDlg,
  707.                     IDC_SETUPDLG_COM1,IDC_SETUPDLG_COM4,
  708.                     IDC_SETUPDLG_COM3);
  709.                 }
  710.                 else if(iComPort==4){
  711.                     CheckRadioButton(hWndDlg,
  712.                     IDC_SETUPDLG_COM1,IDC_SETUPDLG_COM4,
  713.                     IDC_SETUPDLG_COM4);
  714.                 }
  715.                 else iReadyToGo=0;
  716.                 break;
  717.             }
  718.         }
  719.         if(!iReadyToGo)PostMessage(hWndDlg,WM_COMMAND,
  720.         IDC_SETUPDLG_DEFAULTS,0L);
  721.         break;                  /* end of WM_INITDIALOG */
  722.     case WM_CLOSE:
  723.         PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  724.         break;
  725.     case WM_COMMAND:
  726.         switch(wParam){
  727.         case IDC_SETUPDLG_HELP:
  728.             {
  729.                 int help_topic=0;
  730.                 if(lParam==IDC_SETUPDLG_COM1)
  731.                 help_topic=HLP_WTIME_SDPORTS;
  732.                 else if(lParam==IDC_SETUPDLG_COM2)
  733.                 help_topic=HLP_WTIME_SDPORTS;
  734.                 else if(lParam==IDC_SETUPDLG_COM3)
  735.                 help_topic=HLP_WTIME_SDPORTS;
  736.                 else if(lParam==IDC_SETUPDLG_COM4)
  737.                 help_topic=HLP_WTIME_SDPORTS;
  738.                 else if(lParam==IDC_SETUPDLG_DAYLIGHT)
  739.                 help_topic=HLP_WTIME_SDDAYLT;
  740.                 else if(lParam==IDC_SETUPDLG_DIALSTRING)
  741.                 help_topic=HLP_WTIME_SDDIALSTR;
  742.                 else if(lParam==IDC_SETUPDLG_TIMEZONE)
  743.                 help_topic=HLP_WTIME_SDTIMZON;
  744.                 else if(lParam==IDC_SETUPDLG_DEFAULTS)
  745.                 help_topic=HLP_WTIME_SDRESTDEF;
  746.                 else if(lParam==IDOK)help_topic=
  747.                 HLP_WTIME_SDSAVCNF;
  748.                 else if(lParam==IDCANCEL)help_topic=
  749.                 HLP_WTIME_SDCANCEL;
  750.                 else if(lParam==IDC_SETUPDLG_HELPBUTTON)
  751.                 help_topic=HLP_WTIME_SDHELP;
  752.                 else MessageBox(hWndDlg,"Couldn't find "
  753.                 "help topic","Program Error",MB_ICONSTOP);
  754.                 if(help_topic){
  755.                     if(!WinHelp(hWndMain,szHelpFile,
  756.                     HELP_CONTEXT,help_topic)){
  757.                         MessageBox(NULL,"Could not start"
  758.                         " Windows Help\n"
  759.                         "or WTIME.HLP absent",
  760.                         "Windows Error",MB_ICONSTOP);
  761.                     }
  762.                 }
  763.                 break;
  764.             }
  765.         case IDC_SETUPDLG_DEFAULTS:
  766.             SendDlgItemMessage(hWndDlg,
  767.             IDC_SETUPDLG_TIMEZONE,CB_SETCURSEL,(WORD)iEst,0);
  768.             SendDlgItemMessage(hWndDlg,
  769.             IDC_SETUPDLG_DAYLIGHT,BM_SETCHECK,1,0);
  770.             LoadString(hInst,IDS_MODEM_DIALSTRING,szString,
  771.             sizeof(szString));
  772.             SetDlgItemText(hWndDlg,IDC_SETUPDLG_DIALSTRING,
  773.             szString);
  774.             CheckRadioButton(hWndDlg,IDC_SETUPDLG_COM1,
  775.             IDC_SETUPDLG_COM4,IDC_SETUPDLG_COM1);
  776.             break;
  777.         case IDOK:
  778.             {
  779.                 DWORD rv;
  780.                 int success=0;
  781.                 for(;;){
  782.                     /* get tz offset unless User-Defined */
  783.                     rv=SendDlgItemMessage(hWndDlg,
  784.                     IDC_SETUPDLG_TIMEZONE,
  785.                     CB_GETCURSEL,0,0);
  786.                     if(rv==iEst)iTimeOffset=TZOFF_EST;
  787.                     else if(rv==iCst)iTimeOffset=TZOFF_CST;
  788.                     else if(rv==iMtn)iTimeOffset=TZOFF_MTN;
  789.                     else if(rv==iPst)iTimeOffset=TZOFF_PST;
  790.                     else if(rv!=iOther)break;
  791.                     /* get daylight savings selection */
  792.                     rv=SendDlgItemMessage(hWndDlg,
  793.                     IDC_SETUPDLG_DAYLIGHT,BM_GETCHECK,0,0);
  794.                     iUseDaylightSavings=rv?1:0;
  795.                     /* get modem dial string */
  796.                     if(!GetDlgItemText(hWndDlg,
  797.                     IDC_SETUPDLG_DIALSTRING,
  798.                     szModemDialString,
  799.                     sizeof(szModemDialString)))break;
  800.                     /* get com port selection */
  801.                     if(SendDlgItemMessage(hWndDlg,
  802.                     IDC_SETUPDLG_COM1,BM_GETCHECK,0,0))
  803.                     iComPort=1;
  804.                     else if(SendDlgItemMessage(hWndDlg,
  805.                     IDC_SETUPDLG_COM2,BM_GETCHECK,0,0))
  806.                     iComPort=2;
  807.                     else if(SendDlgItemMessage(hWndDlg,
  808.                     IDC_SETUPDLG_COM3,BM_GETCHECK,0,0))
  809.                     iComPort=3;
  810.                     else if(SendDlgItemMessage(hWndDlg,
  811.                     IDC_SETUPDLG_COM4,BM_GETCHECK,0,0))
  812.                     iComPort=4;
  813.                     else break;
  814.                     /* now save it all */
  815.                     success=iSetConfigurationInformation();
  816.                     break;
  817.                 }
  818.                 if(!success){
  819.                     MessageBox(hWndDlg,
  820.                     "Could not save "
  821.                     "configuration information",
  822.                     "Configuration Error",MB_ICONSTOP);
  823.                 }
  824.                 UpdateStatusLineText("");
  825.                 EndDialog(hWndDlg,FALSE);
  826.                 break;
  827.             }
  828.         case IDCANCEL:
  829.             EndDialog(hWndDlg, FALSE);
  830.             break;
  831.         case IDC_SETUPDLG_HELPBUTTON:
  832.             if(!WinHelp(hWndMain,szHelpFile,HELP_CONTEXT,
  833.             HLP_WTIME_SDHELP)){
  834.                 MessageBox(NULL,
  835.                 "Couldn't start Windows Help\n"
  836.                 "or WTIME.HLP absent",
  837.                 "Windows Error",MB_ICONSTOP);
  838.             }
  839.             break;
  840.         }
  841.         break;              /* End of WM_COMMAND */
  842.     default:
  843.         return FALSE;
  844.     }
  845.     return TRUE;
  846. }                           /* End of CONFIGMsgProc */
  847. BOOL FAR PASCAL ABOUTMsgProc(HWND hWndDlg,WORD Message,
  848. WORD wParam,LONG lParam){
  849.     switch(Message){
  850.     case WM_INITDIALOG:
  851.         cwCenter(hWndDlg, 0);
  852.         break;
  853.     case WM_CLOSE:
  854.         PostMessage(hWndDlg, WM_COMMAND, IDCANCEL, 0L);
  855.         break;
  856.     case WM_COMMAND:
  857.         EndDialog(hWndDlg,FALSE);
  858.         break;
  859.     default:
  860.         return FALSE;
  861.     }
  862.     return TRUE;
  863. }                           /* End of ABOUTMsgProc */
  864. int nCwRegisterClasses(void){
  865.     WNDCLASS wndclass;
  866.     memset(&wndclass,0x00,sizeof(WNDCLASS));
  867.     wndclass.style=CS_HREDRAW|CS_VREDRAW|
  868.     CS_BYTEALIGNWINDOW;
  869.     wndclass.lpfnWndProc=WndProc;
  870.     wndclass.cbClsExtra=0;
  871.     wndclass.cbWndExtra=0;
  872.     wndclass.hInstance=hInst;
  873.     wndclass.hIcon=LoadIcon(hInst,"WTimeIcon");
  874.     wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
  875.     wndclass.hbrBackground =(HBRUSH)(COLOR_WINDOW+1);
  876.     wndclass.lpszMenuName=szAppName;
  877.     wndclass.lpszClassName=szAppName;
  878.     if(!RegisterClass(&wndclass))return -1;
  879.     return(0);
  880. }                       /* End of nCwRegisterClasses() */
  881. void cwCenter(HWND hWnd,int top){
  882.     POINT pt;
  883.     RECT swp,rParent;
  884.     int iwidth,iheight;
  885.     GetWindowRect(hWnd,&swp);
  886.     GetClientRect(hWndMain,&rParent);
  887.     iwidth=swp.right-swp.left;
  888.     iheight=swp.bottom-swp.top;
  889.     pt.x=(rParent.right-rParent.left)/2;
  890.     pt.y=(rParent.bottom-rParent.top)/2;
  891.     ClientToScreen(hWndMain,&pt);
  892.     pt.x=pt.x-(iwidth/2);
  893.     pt.y=pt.y-(iheight/2);
  894.     if(top)pt.y=pt.y+top;
  895.     if(pt.y<0)pt.y=0;
  896.     if(pt.x<0)pt.x=0;
  897.     MoveWindow(hWnd,pt.x,pt.y,iwidth,iheight,FALSE);
  898. }
  899. void CwUnRegisterClasses(void){
  900.     WNDCLASS wndclass;
  901.     memset(&wndclass,0x00,sizeof(WNDCLASS));
  902.     UnregisterClass(szAppName,hInst);
  903. }
  904.  
  905. void SetCallOption(void){
  906. /*
  907. **  this function grays or ungrays the Menu|Call option
  908. **  depending on if iReadyToGo is nonzero
  909. */
  910.     if(iReadyToGo)EnableMenuItem(hMainMenu,IDM_M_CALL,
  911.                                  MF_ENABLED|MF_BYCOMMAND);
  912.     else EnableMenuItem(hMainMenu,IDM_M_CALL,
  913.                         MF_GRAYED|MF_BYCOMMAND);
  914. }
  915. int iGetConfigurationInformation(void){
  916. /*
  917. **  this function gets the setup stuff from the .INI file
  918. **  writes to szModemDialString,iTimeOffset,
  919. **  iUseDaylightSavings,iComPort
  920. **  returns 0 for fail, 1 for success
  921. */
  922.     if(2>GetProfileString(szAppName,"ModemDialString","",
  923.     szModemDialString,sizeof(szModemDialString))){
  924.         return 0;
  925.     }
  926.     iTimeOffset=MyGetProfileInt(szAppName,"TimeOffset",
  927.     9999);
  928.     if(iTimeOffset<-1439||iTimeOffset>1439)return 0;
  929.     iUseDaylightSavings=MyGetProfileInt(szAppName,
  930.     "UseDaylightSavings",-1);
  931.     if(iUseDaylightSavings<0||iUseDaylightSavings>1)
  932.     return 0;
  933.     iComPort=MyGetProfileInt(szAppName,"ComPort",-1);
  934.     if(iComPort<1||iComPort>4)return 0;
  935.     return 1;
  936. }
  937. int iSetConfigurationInformation(void){
  938. /*
  939. **  writes the stuff to the .INI file
  940. **  writes to ModemDialString, TimeOffset,
  941. **  UseDaylightSavings, ComPort
  942. **  returns 0 for fail, 1 for success
  943. */
  944.     if(!WriteProfileString(szAppName,"ModemDialString",
  945.     szModemDialString))return 0;
  946.     wsprintf(szString,"%d",iTimeOffset);
  947.     if(!WriteProfileString(szAppName,"TimeOffset",
  948.     szString))return 0;
  949.     wsprintf(szString,"%d",iUseDaylightSavings);
  950.     if(!WriteProfileString(szAppName,"UseDaylightSavings",
  951.     szString))return 0;
  952.     wsprintf(szString,"%d",iComPort);
  953.     if(!WriteProfileString(szAppName,"ComPort",szString)){
  954.         return 0;
  955.     }
  956.     return 1;
  957. }
  958. DWORD FAR PASCAL SetupDlgMsgHook(int nCode,WORD wParam,
  959. LPMSG lpMsg){
  960.     DWORD retval=0L;
  961.     int did_it=0;
  962.     if(nCode==MSGF_DIALOGBOX){
  963.         if(lpMsg->message==WM_KEYDOWN){
  964.             if(lpMsg->wParam==VK_F1){
  965.                 if(!(lpMsg->lParam&0x40000000L)){
  966.                     did_it=1;
  967.                     PostMessage(hWndSetupDlg,WM_COMMAND,
  968.                     IDC_SETUPDLG_HELP,
  969.                     (long)GetDlgCtrlID(lpMsg->hwnd));
  970.                     retval=1L;
  971.                 }
  972.             }
  973.         }
  974.     }
  975.     if((nCode<0)||(!did_it&&oldfilter))retval=
  976.     DefHookProc(nCode,wParam,(LONG)lpMsg,&oldfilter);
  977.     return(retval);
  978. }
  979. void UpdateStatusLine(void){
  980.     if(!IsIconic(hWndMain)){
  981.         InvalidateRect(hWndMain,NULL,TRUE);
  982.         UpdateWindow(hWndMain);
  983.     }
  984. }
  985. void UpdateStatusLineText(LPSTR string){
  986.     lstrcpy(szDisplayString,string);
  987.     UpdateStatusLine();
  988. }
  989. LPSTR init_comm_port(void){
  990.     /*
  991.     **  Sets up the COM port for access.
  992.     **  Returns LPSTR to fail description,
  993.     **  or NULL if success
  994.     **  Uses the global variable DCB dcb.
  995.     **  Also sets iGotComPort if success.
  996.     */
  997.     int rv;
  998.     wsprintf(szString,"COM%d",iComPort);
  999.     rv=OpenComm(szString,2048,2048);    /* tx rx buffs */
  1000.     dcb.Id=(BYTE)rv;
  1001.     if(rv<0){
  1002.         LPSTR p;
  1003.         switch(rv){
  1004.         case IE_BADID:
  1005.             p="Invalid or unsupported ID";
  1006.             break;
  1007.         case IE_BAUDRATE:
  1008.             p="Unsupported baud rate";
  1009.             break;
  1010.         case IE_BYTESIZE:
  1011.             p="Invalid byte size";
  1012.             break;
  1013.         case IE_DEFAULT:
  1014.             p="Error in default parameters";
  1015.             break;
  1016.         case IE_HARDWARE:
  1017.             p="Hardware not present";
  1018.             break;
  1019.         case IE_MEMORY:
  1020.             p="Unable to allocate queues";
  1021.             break;
  1022.         case IE_NOPEN:
  1023.             p="Device not open";
  1024.             break;
  1025.         case IE_OPEN:
  1026.             p="Device already open";
  1027.             break;
  1028.         default:
  1029.             p="Unknown communication error";
  1030.             break;
  1031.         }
  1032.         return p;
  1033.     }
  1034.     else iGotComPort=1;
  1035.     dcb.BaudRate=1200;
  1036.     dcb.ByteSize=8;
  1037.     dcb.Parity=NOPARITY;
  1038.     dcb.StopBits=ONESTOPBIT;
  1039.     dcb.RlsTimeout=0;
  1040.     dcb.CtsTimeout=0;
  1041.     dcb.DsrTimeout=0;
  1042.     dcb.fBinary=1;
  1043.     dcb.fRtsDisable=0;
  1044.     dcb.fParity=0;
  1045.     dcb.fOutxCtsFlow=0;
  1046.     dcb.fOutxDsrFlow=0;
  1047.     dcb.fDummy=0;
  1048.     dcb.fDtrDisable=0;
  1049.     dcb.fOutX=0;
  1050.     dcb.fInX=0;
  1051.     dcb.fPeChar=0;
  1052.     dcb.fNull=1;
  1053.     dcb.fChEvt=1;
  1054.     dcb.fDtrflow=0;
  1055.     dcb.fRtsflow=0;
  1056.     dcb.fDummy2=0;
  1057.     dcb.XonChar=0;
  1058.     dcb.XoffChar=0;
  1059.     dcb.XonLim=10;
  1060.     dcb.XoffLim=10;
  1061.     dcb.PeChar=0;
  1062.     dcb.EofChar=0;
  1063.     dcb.EvtChar='>'; /* end of line, start of data */
  1064.     dcb.TxDelay=0;
  1065.     if(SetCommState(&dcb))return "SetCommState() fail";
  1066.     GetCommEventMask(dcb.Id,EV_ERR|EV_RXCHAR|EV_RXFLAG|
  1067.     EV_TXEMPTY);
  1068.     GetDisplayCommError(dcb.Id,NULL);
  1069.     FlushComm(dcb.Id,0);    /* stop transmitting */
  1070.     FlushComm(dcb.Id,1);     /* stop receiving */
  1071.     return NULL;
  1072. }
  1073. void close_comm_port(void){
  1074.     /*
  1075.     **  Releases the COM port allocated into dcb.
  1076.     **  Does nothing unless iGotComPort is nonzero.
  1077.     */
  1078.     if(!iGotComPort)return;
  1079.     EscapeCommFunction(dcb.Id,RESETDEV);
  1080.     FlushComm(dcb.Id,0);/* stop transmitting */
  1081.     CloseComm(dcb.Id);  /* release port, buffers */
  1082.     iGotComPort=0;
  1083. }
  1084. void FailCall(LPSTR failure){
  1085.     /*
  1086.     **  Turns off iInCall, displays a message box with
  1087.     **  failure string (if not iAutomatic), and posts
  1088.     **  IDM_CMD_CALLDONE command to hWndMain
  1089.     */
  1090.     if(!iInCall)return;
  1091.     iInCall=0;
  1092.     iTimerCount=0;
  1093.     iCleaningUp=1;
  1094.     UpdateStatusLineText(failure);
  1095.     iThisRunFailed=1;
  1096.     if(failure&&failure[0])lstrcpy(szFailString,failure);
  1097.     PostMessage(hWndMain,WM_COMMAND,IDM_CMD_CALLDONE,0L);
  1098. }
  1099. void WaitSecondsCommand(int seconds,WORD command){
  1100.     iTargetTime=iTimerCount-(1+seconds);
  1101.     if(iTimerCount<1)iTimerCount=10;
  1102.     if(iTargetTime<1)iTargetTime=1;
  1103.     if(iTargetTime>=iTimerCount)iTargetTime=iTimerCount-1;
  1104.     wTimedTargetCmdToPost=command;
  1105. }
  1106. WORD MyGetProfileInt(LPSTR lpAppName,LPSTR lpKeyName,
  1107. int nDefault){
  1108.     /*
  1109.     **  This is simply an implementation of
  1110.     **  GetProfileInt(), necessary because OS/2 2.0's
  1111.     ** Windows box version of GetProfileInt() chokes
  1112.     **  on negative numbers.
  1113.     */
  1114.     char nearbuffer[20];/* big enough to hold my ints */
  1115.     char *nearptr=nearbuffer;
  1116.     int got_int=0,got_negative=0,this_character,retval=0;
  1117.     if(1>GetProfileString(lpAppName,lpKeyName,"",
  1118.     nearbuffer,sizeof(nearbuffer)))return (WORD)nDefault;
  1119.     /* ensure null termination */
  1120.     nearbuffer[sizeof(nearbuffer)-1]=0;
  1121.     while(this_character=(int)*nearptr++){
  1122.         if(isspace(this_character)&&!got_int)continue;
  1123.         if(this_character=='-'&&!got_int&&!got_negative){
  1124.             got_negative=1;
  1125.             continue;
  1126.         }
  1127.         if(isdigit(this_character)){
  1128.             got_int=1;
  1129.             retval*=10;
  1130.             retval+=this_character-'0';
  1131.             continue;
  1132.         }
  1133.         if(got_int)break;
  1134.         return (WORD)nDefault;
  1135.     }
  1136.     if(got_int){
  1137.         if(got_negative)retval*=-1;
  1138.         return (WORD)retval;
  1139.     }
  1140.     return nDefault;
  1141. }
  1142. int GetDisplayCommError(int nCid,COMSTAT FAR *lpStat){
  1143.     /*
  1144.     **  wrapper for GetCommError()
  1145.     **  same function as GetCommError() but displays
  1146.     **  found errors on second line of text window
  1147.     */
  1148.     char local_buffer[9];
  1149.     int temp,retval=GetCommError(nCid,lpStat);
  1150.     if(retval){
  1151.         temp=retval;
  1152.         wsprintf(szCommError,"Comm Error %04X",retval);
  1153.         if(temp&CE_BREAK){
  1154.             lstrcat(szCommError,", break");
  1155.             temp&=~CE_BREAK;
  1156.         }
  1157.         if(temp&CE_CTSTO){
  1158.             lstrcat(szCommError,", CTS timeout");
  1159.             temp&=~CE_CTSTO;
  1160.         }
  1161.         if(temp&CE_DSRTO){
  1162.             lstrcat(szCommError,", DSR timeout");
  1163.             temp&=~CE_DSRTO;
  1164.         }
  1165.         if(temp&CE_FRAME){
  1166.             lstrcat(szCommError,", framing error");
  1167.             temp&=~CE_FRAME;
  1168.         }
  1169.         if(temp&CE_MODE){
  1170.             lstrcat(szCommError,", bad device or mode");
  1171.             temp&=~CE_MODE;
  1172.         }
  1173.         if(temp&CE_OVERRUN){
  1174.             lstrcat(szCommError,", read overrun");
  1175.             temp&=~CE_OVERRUN;
  1176.         }
  1177.         if(temp&CE_RLSDTO){
  1178.             lstrcat(szCommError,
  1179.             ", RX line signal detect timeout");
  1180.             temp&=~CE_RLSDTO;
  1181.         }
  1182.         if(temp&CE_RXOVER){
  1183.             lstrcat(szCommError,", RX queue overflow");
  1184.             temp&=~CE_RXOVER;
  1185.         }
  1186.         if(temp&CE_RXPARITY){
  1187.             lstrcat(szCommError,", RX parity error");
  1188.             temp&=~CE_RXPARITY;
  1189.         }
  1190.         if(temp&CE_TXFULL){
  1191.             lstrcat(szCommError,", TX buffer full");
  1192.             temp&=~CE_TXFULL;
  1193.         }
  1194.         if(temp){
  1195.             if(temp==retval){
  1196.                 lstrcat(szCommError,", unknown error!");
  1197.             }
  1198.             else{
  1199.                 lstrcat(szCommError," -- leftover: ");
  1200.                 wsprintf(local_buffer,"%04X",temp);
  1201.                 lstrcat(szCommError,local_buffer);
  1202.             }
  1203.         }
  1204.         if(szCommError[15])szCommError[15]=':';
  1205.         szCommError[17]=
  1206.         (char)toupper((int)szCommError[17]);
  1207.     }
  1208.     return retval;
  1209. }
  1210. #ifdef __TURBOC__
  1211. /*
  1212. **  Turbo C's localtime(), contrary to the documentation,
  1213. **  calls tzset() before doing its own work. This will
  1214. **  obviously overwrite any data you've put into daylight
  1215. **  or timezone. This null function makes the behavior
  1216. **  unimportant -- unless you need tzset() for some
  1217. **  other reason in your program!
  1218. */
  1219. void tzset(void){}
  1220. #endif
  1221.