home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol11n19.zip / TIME!.C < prev    next >
Text File  |  1992-09-22  |  16KB  |  528 lines

  1. //========================================================================
  2. //  
  3. //  TIME!.C -- A Timer program for Windows
  4. //
  5. //  (c) Douglas Boling, 1992
  6. //
  7. //  For better readability, set tab stops to every 3 characters.
  8. //
  9. //========================================================================
  10.  
  11. #include <windows.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <time.h>
  15. #include "digit.h"                            //Include ctl equates
  16.  
  17. #include "Time!.h"
  18.  
  19. #define    NUMTIMERS   3
  20. #define    MAXTIME     3600
  21. #define    NUMDIGITS   4
  22.  
  23. //------------------------------------------------------------------------
  24. //Function prototypes
  25. //------------------------------------------------------------------------
  26. int    PASCAL         WinMain (HANDLE, HANDLE, LPSTR, int);
  27. long    FAR PASCAL    WndProc (HWND, WORD, WORD, LONG);
  28.  
  29. struct TIMERSTRUCT {
  30.     BOOL    bRunning;
  31.     int    sValue;
  32.     DWORD    dwStart;    
  33. } tsTimer [NUMTIMERS];
  34.  
  35. char        szAppName[] = "Time!";
  36. char        szProfileName[] = "TIME!.INI";
  37. HANDLE      hInst;
  38.  
  39. //=======================================================================
  40. //
  41. // Program Entry Point (WinMain)
  42. //
  43. //=======================================================================
  44. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  45.                 LPSTR lpszCmdParam, int nCmdShow) {
  46.  
  47.    HWND            hwnd;
  48.     HANDLE        hAccel, hLibInst;
  49.    MSG            msg;
  50.    WNDCLASS        wndclass;
  51.     int            i, j;
  52.  
  53.     if (!hPrevInstance) {
  54.       wndclass.style          = CS_HREDRAW | CS_VREDRAW;
  55.       wndclass.lpfnWndProc    = (FARPROC) WndProc;
  56.       wndclass.cbClsExtra     = 0;
  57.       wndclass.cbWndExtra     = DLGWINDOWEXTRA;
  58.       wndclass.hInstance      = hInstance;
  59.       wndclass.hIcon          = LoadIcon (hInstance, szAppName);
  60.       wndclass.hCursor        = LoadCursor (NULL, IDC_ARROW);
  61.       wndclass.hbrBackground  = COLOR_WINDOW + 1;
  62.       wndclass.lpszMenuName   = 0;
  63.       wndclass.lpszClassName  = szAppName;
  64.  
  65.       RegisterClass (&wndclass);
  66.    }
  67.     hInst = hInstance;
  68.     
  69.     hLibInst = LoadLibrary ("digit.dll");
  70.     if (hLibInst < 32) {
  71.         MessageBox (NULL, "Unable to load DIGIT.DLL", 
  72.                     szAppName, MB_ICONEXCLAMATION | MB_OK);
  73.         return 1;
  74.     }    
  75.     hwnd = CreateDialog (hInstance, szAppName, 0, NULL);
  76.     
  77.     if (lpszCmdParam[0] == '/' || lpszCmdParam[0] == '-') 
  78.         if (lpszCmdParam[1] == 'i' || lpszCmdParam[1] == 'I') 
  79.             nCmdShow |= SW_MINIMIZE;
  80.  
  81.     i = GetPrivateProfileInt (szAppName, "x", 300, szProfileName);
  82.     j = GetPrivateProfileInt (szAppName, "y", 100, szProfileName);
  83.  
  84.     if (GetPrivateProfileInt (szAppName, "icon", 0, szProfileName)) 
  85.           nCmdShow |= SW_MINIMIZE;
  86.  
  87.     SetWindowPos (hwnd, NULL, i, j, 0, 0, SWP_NOSIZE);
  88.     ShowWindow (hwnd, nCmdShow);
  89.     hAccel = LoadAccelerators (hInstance, szAppName);
  90.  
  91.     while (GetMessage (&msg, NULL, 0, 0)) {
  92.        if (hwnd == 0 || !IsDialogMessage (hwnd, &msg))
  93.             if (!TranslateAccelerator (hwnd, hAccel, &msg)) {
  94.                TranslateMessage (&msg);
  95.                DispatchMessage (&msg);
  96.             }
  97.     }
  98.     FreeLibrary (hLibInst);
  99.    return msg.wParam;
  100. }
  101.  
  102. //       if (hwnd == 0 || !IsDialogMessage (hwnd, &msg))
  103.  
  104. //========================================================================
  105. //
  106. // Routines used by WndProc
  107. //
  108. //========================================================================
  109.  
  110. //------------------------------------------------------------------------
  111. // About box dialog procedure
  112. //------------------------------------------------------------------------
  113. BOOL FAR PASCAL AboutDlgProc (HWND hwnd, WORD message, WORD wParam, 
  114.                                LONG lParam) {
  115.     switch (message) {
  116.  
  117.         case WM_COMMAND:
  118.             switch (wParam) {
  119.  
  120.                 case IDOK:
  121.                     EndDialog (hwnd, 1);
  122.                     return TRUE;
  123.             }
  124.             break;
  125.  
  126.         case WM_CLOSE:
  127.             EndDialog (hwnd, 0);
  128.             return TRUE;
  129.     }
  130.     return FALSE;    
  131. }
  132.  
  133. //------------------------------------------------------------------------
  134. // SetDigits - Sets the digits to the value specified
  135. //------------------------------------------------------------------------
  136. void SetDigits (HWND hwnd, WORD wValue) {
  137.  
  138.     WORD    wRemainder;
  139.     BOOL    bNoBlank;
  140.  
  141.     bNoBlank = FALSE;
  142.     wRemainder = wValue / 600;
  143.     if (wRemainder) {
  144.         SendDlgItemMessage (hwnd, IDD_TMINDIG, DIGM_BLANK, FALSE, 0);
  145.         wValue -= wRemainder * 600;
  146.         bNoBlank = TRUE;
  147.     } else 
  148.         SendDlgItemMessage (hwnd, IDD_TMINDIG, DIGM_BLANK, TRUE, 0);
  149.  
  150.     SendDlgItemMessage (hwnd, IDD_TMINDIG, DIGM_SET, wRemainder, 0);
  151.  
  152.     wRemainder = wValue / 60;
  153.     if (wRemainder || bNoBlank) {
  154.         SendDlgItemMessage (hwnd, IDD_MINDIG, DIGM_BLANK, FALSE, 0);
  155.         wValue -= wRemainder * 60;
  156.     } else
  157.         SendDlgItemMessage (hwnd, IDD_MINDIG, DIGM_BLANK, TRUE, 0);
  158.  
  159.     SendDlgItemMessage (hwnd, IDD_MINDIG, DIGM_SET, wRemainder, 0);
  160.  
  161.     wRemainder = wValue / 10;
  162.     if (wRemainder)
  163.         wValue -= wRemainder * 10;
  164.  
  165.     SendDlgItemMessage (hwnd, IDD_TSECDIG, DIGM_SET, wRemainder, 0);
  166.  
  167.     SendDlgItemMessage (hwnd, IDD_SECDIG, DIGM_SET, wValue, 0);
  168.  
  169.     return;
  170. }
  171.  
  172. //------------------------------------------------------------------------
  173. // GetDigits - Gets the value loaded in the digit controls
  174. //------------------------------------------------------------------------
  175. int GetDigits (HWND hwnd) {
  176.  
  177.     WORD    sValue;
  178.  
  179.     sValue =  600 * (int) SendDlgItemMessage (hwnd, IDD_TMINDIG, 
  180.                                               DIGM_GET, 0, 0);
  181.     sValue +=  60 * SendDlgItemMessage (hwnd, IDD_MINDIG, DIGM_GET, 0, 0);
  182.     sValue +=  10 * SendDlgItemMessage (hwnd, IDD_TSECDIG, DIGM_GET, 0, 0);
  183.     sValue +=       SendDlgItemMessage (hwnd, IDD_SECDIG, DIGM_GET, 0, 0);
  184.  
  185.     return sValue;
  186. }
  187.  
  188. //------------------------------------------------------------------------
  189. // Sounds the alarm for a timer.
  190. //------------------------------------------------------------------------
  191. void SoundAlarm (void) {
  192.     MessageBeep (30);
  193. }
  194. //------------------------------------------------------------------------
  195. // Sets the proper state for each of the buttons
  196. //------------------------------------------------------------------------
  197. void SetButtons (HWND hwnd, BOOL bRunning, WORD wOTimer, WORD wTimer) {
  198.  
  199.     if (wOTimer != 0xFFFF) 
  200.         ShowWindow (GetDlgItem (hwnd, IDD_MTIME1 + wOTimer), SW_HIDE);
  201.  
  202.     ShowWindow (GetDlgItem (hwnd, IDD_MTIME1 + wTimer), SW_SHOW);
  203.  
  204.     if (bRunning) {
  205.         SetDlgItemText (hwnd, IDD_GO, "S&top");
  206.         EnableWindow (GetDlgItem (hwnd, IDD_BMINUTES), FALSE);
  207.         EnableWindow (GetDlgItem (hwnd, IDD_BSECONDS), FALSE);
  208.     } else {
  209.         SetDlgItemText (hwnd, IDD_GO, "S&tart");
  210.         EnableWindow (GetDlgItem (hwnd, IDD_BMINUTES), TRUE);
  211.         EnableWindow (GetDlgItem (hwnd, IDD_BSECONDS), TRUE);
  212.     }
  213.  
  214. }
  215.  
  216. //------------------------------------------------------------------------
  217. // Computes the time remaining for a timer
  218. //------------------------------------------------------------------------
  219. int ComputeTime (DWORD dwCurrentTime, DWORD dwStart, int sValue) {
  220.  
  221.     DWORD dwTemp;
  222.  
  223.     dwTemp = (dwCurrentTime - dwStart);
  224.  
  225.     return sValue - (int) dwTemp;
  226. }                
  227.  
  228. //========================================================================
  229. //
  230. // Main Window Procedure.
  231. //
  232. //========================================================================
  233. long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam) {
  234.  
  235.     static    int    sSelTimer, sActiveTimers;    
  236.     static    BOOL    bFirst;
  237.     int        i, sTime;
  238.     DWORD        dwTemp, dwCurrTime;
  239.     char        szTemp[10];
  240.     RECT        rect;
  241.  
  242.    switch (message) {
  243.  
  244.       case WM_CREATE:          
  245.             for (i = 0; i < NUMTIMERS; i++) {
  246.                 tsTimer[i].bRunning = FALSE;
  247.                 tsTimer[i].sValue = 0;
  248.                 tsTimer[i].dwStart = 0;
  249.             }
  250.             bFirst = TRUE;
  251.             sActiveTimers = 0;
  252.             sSelTimer = 0;
  253.              return 0;
  254.  
  255.         case WM_SIZE:
  256.             if (bFirst) {
  257.  
  258.                 if (GetPrivateProfileInt (szAppName, "LCD", 0, szProfileName)) 
  259.                     for (i = 0; i < NUMDIGITS; i++) {
  260.                         dwTemp = GetWindowLong (GetDlgItem (hwnd, IDD_SECDIG+i),
  261.                                                 GWL_STYLE);
  262.                         SetWindowLong (GetDlgItem (hwnd, IDD_SECDIG+i),
  263.                                       GWL_STYLE, dwTemp & ~DIGS_LED);
  264.                     }
  265.                 //
  266.                 //Set proper base for each digit
  267.                 //
  268.                 SendDlgItemMessage (hwnd, IDD_SECDIG, DIGM_SETBASE, 10, 0);
  269.                 SendDlgItemMessage (hwnd, IDD_TSECDIG, DIGM_SETBASE, 6, 0);
  270.                 SendDlgItemMessage (hwnd, IDD_MINDIG, DIGM_SETBASE, 10, 0);
  271.                 SendDlgItemMessage (hwnd, IDD_TMINDIG, DIGM_SETBASE, 6, 0);
  272.                 //
  273.                 //Set Timer 1 active
  274.                 //
  275.                 ShowWindow (GetDlgItem (hwnd, IDD_MTIME2), SW_HIDE);
  276.                 ShowWindow (GetDlgItem (hwnd, IDD_MTIME3), SW_HIDE);
  277.                 SetButtons (hwnd, FALSE, -1, sSelTimer);
  278.                 SetDigits (hwnd, 0);
  279.  
  280.                 SetFocus (GetDlgItem (hwnd, IDD_GO));
  281.  
  282.                 bFirst = FALSE;
  283.             }
  284.             break;
  285.  
  286.         case WM_TIMER:
  287.  
  288.             time (&dwCurrTime);
  289.             for (i = 0; i < NUMTIMERS; i++) {
  290.                 if (tsTimer[i].bRunning) {
  291.             
  292.                     sTime = ComputeTime (dwCurrTime, tsTimer[i].dwStart,
  293.                                          tsTimer[i].sValue);
  294.                 
  295.                     if (sTime <= 0) {
  296.                         sTime = 0;
  297.                         tsTimer[i].sValue = 0;
  298.                         tsTimer[i].bRunning = FALSE;
  299.                         SoundAlarm ();
  300.                         SetActiveWindow (hwnd);
  301.                         sActiveTimers--;
  302.                         if (i == sSelTimer) 
  303.                             SetButtons (hwnd, FALSE, i, sSelTimer);
  304.                     }
  305.                     if (i == sSelTimer) 
  306.                         SetDigits (hwnd, sTime);
  307.                 }
  308.             }
  309.             if (sActiveTimers == 0) KillTimer (hwnd, 1);
  310.             break;
  311.  
  312.         case WM_COMMAND:
  313.             switch (wParam) {
  314.                 //
  315.                 // DigitClass control messages
  316.                 //
  317.                 case IDD_SECDIG:
  318.                 case IDD_TSECDIG:
  319.                 case IDD_MINDIG:
  320.                 case IDD_TMINDIG:
  321.                     switch (HIWORD (lParam)) {
  322.  
  323.                         case DIGN_CARRY:
  324.                             if (wParam != IDD_TMINDIG) 
  325.                                 SendDlgItemMessage (hwnd, wParam+1, DIGM_INC, 0, 0);
  326.                             break;
  327.  
  328.                         case DIGN_BORROW:
  329.                             if (wParam != IDD_TMINDIG) { 
  330.                                 SendDlgItemMessage (hwnd, wParam+1, DIGM_DEC, 0, 0);
  331.                                 dwTemp = GetWindowLong (GetDlgItem (hwnd, wParam+1),
  332.                                                         GWL_STYLE);
  333.                                 if (dwTemp & DIGS_BLANK)
  334.                                     SendDlgItemMessage (hwnd, wParam+1, DIGM_BLANK,
  335.                                                         FALSE, 0);
  336.                             }
  337.                             break;
  338.  
  339.                         case DIGN_RCLICK:
  340.                         case DIGN_LCLICK:
  341.                             if (!tsTimer[sSelTimer].bRunning) {
  342.  
  343.                                 if (HIWORD (lParam) == DIGN_LCLICK) {
  344.                                     i = (int) SendDlgItemMessage (hwnd, wParam, 
  345.                                                                   DIGM_GET, 0, 0);
  346.                                     if (++i == (int) SendDlgItemMessage (hwnd, wParam, 
  347.                                                                      DIGM_GETBASE, 
  348.                                                                                 0, 0))
  349.                                         i = 0;
  350.                                 } else {
  351.                                     i = (int) SendDlgItemMessage (hwnd, wParam, 
  352.                                                                   DIGM_GET, 0, 0);
  353.                                     if (i-- == 0) i = 10;
  354.                                 }
  355.                                 SendDlgItemMessage (hwnd, wParam, DIGM_SET, 
  356.                                                     i, 0);
  357.  
  358.                                 if (wParam == IDD_TMINDIG && i == 0) {
  359.                                     SendDlgItemMessage (hwnd, IDD_TMINDIG,                                                         DIGM_BLANK, TRUE, 0);
  360.                                 }
  361.  
  362.                                 if (wParam == IDD_MINDIG && i == 0) {
  363.                                     if (DIGS_BLANK & GetWindowLong (
  364.                                                             GetDlgItem (hwnd, 
  365.                                                                                 IDD_TMINDIG),
  366.                                                             GWL_STYLE))
  367.                                         SendDlgItemMessage (hwnd, IDD_MINDIG, 
  368.                                                             DIGM_BLANK, TRUE, 0);
  369.                                 }
  370.  
  371.                                 if (i != 0) {
  372.                                       for (i = wParam; i > IDD_TSECDIG; i--) {
  373.                                           dwTemp = GetWindowLong (GetDlgItem (hwnd, i),
  374.                                                                 GWL_STYLE);
  375.                                         if (dwTemp & DIGS_BLANK)
  376.                                             SendDlgItemMessage (hwnd, i, DIGM_BLANK,
  377.                                                                 FALSE, 0);
  378.                                         else
  379.                                             break;
  380.                                     }
  381.                                 }
  382.                                 tsTimer[sSelTimer].sValue = GetDigits (hwnd);
  383.                             }
  384.                             break;
  385.  
  386.                     }
  387.                     break;
  388.  
  389.                 //
  390.                 // Menu messages
  391.                 //
  392.                 case IDM_LED:
  393.                     dwTemp = GetWindowLong (GetDlgItem (hwnd, IDD_SECDIG),
  394.                                             GWL_STYLE);
  395.                     if (!(dwTemp & DIGS_LED)) {
  396.                         for (i = 0; i < NUMDIGITS; i++) {
  397.                             dwTemp = GetWindowLong (GetDlgItem (hwnd, IDD_SECDIG+i),
  398.                                                     GWL_STYLE);
  399.                             SetWindowLong (GetDlgItem (hwnd, IDD_SECDIG+i),
  400.                                           GWL_STYLE, dwTemp | DIGS_LED);
  401.                         }
  402.                         InvalidateRect (hwnd, NULL, TRUE);
  403.                     }
  404.                     return 0;
  405.  
  406.                 case IDM_LCD:
  407.                     dwTemp = GetWindowLong (GetDlgItem (hwnd, IDD_SECDIG),
  408.                                             GWL_STYLE);
  409.                     if (dwTemp & DIGS_LED != 0) {
  410.                         for (i = 0; i < NUMDIGITS; i++) {
  411.                             dwTemp = GetWindowLong (GetDlgItem (hwnd, IDD_SECDIG+i),
  412.                                                     GWL_STYLE);
  413.                             SetWindowLong (GetDlgItem (hwnd, IDD_SECDIG+i),
  414.                                           GWL_STYLE, dwTemp & ~DIGS_LED);
  415.                         }
  416.                         InvalidateRect (hwnd, NULL, TRUE);
  417.                     }
  418.                     return 0;
  419.  
  420.                 case IDM_ABOUT:
  421.                     {
  422.                         FARPROC    lpfnAboutDlgFn;
  423.                         lpfnAboutDlgFn = MakeProcInstance (AboutDlgProc, hInst);
  424.                         DialogBox (hInst, "About", hwnd, lpfnAboutDlgFn);
  425.                         FreeProcInstance (lpfnAboutDlgFn);
  426.                     }
  427.                     return 0;
  428.  
  429.                 case IDM_EXIT:
  430.                     EndDialog (hwnd, TRUE);
  431.                     SendMessage (hwnd, WM_CLOSE, 0, 0);
  432.                     return 0;
  433.                 //
  434.                 // Button messages
  435.                 //
  436.                 case IDD_GO:
  437.                     time (&dwCurrTime);
  438.                     if (tsTimer[sSelTimer].bRunning) {
  439.                         tsTimer[sSelTimer].bRunning = FALSE;
  440.                         tsTimer[sSelTimer].sValue = ComputeTime (dwCurrTime,
  441.                                                     tsTimer[sSelTimer].dwStart,
  442.                                                    tsTimer[sSelTimer].sValue);
  443.  
  444.                         if (--sActiveTimers == 0) KillTimer (hwnd, 1);
  445.                     } else {
  446.                         if (sActiveTimers++ == 0) {
  447.                             if (!SetTimer (hwnd, 1, 1000, 0L)) {
  448.                                 MessageBox (hwnd, "No Available Timers", 
  449.                                             szAppName, MB_ICONEXCLAMATION | MB_OK);
  450.                                 return 0;
  451.                             }
  452.                         }
  453.                         tsTimer[sSelTimer].bRunning = TRUE;
  454.                         tsTimer[sSelTimer].dwStart = dwCurrTime;
  455.                     }
  456.                     SetButtons (hwnd, tsTimer[sSelTimer].bRunning, -1, sSelTimer);
  457.                     return 0;
  458.  
  459.                 case IDD_BTIMER1:
  460.                 case IDD_BTIMER2:
  461.                 case IDD_BTIMER3:
  462.                     i = wParam - IDD_BTIMER1;
  463.                     if (sSelTimer != i) {
  464.                         //
  465.                         //Get old timer value
  466.                         //
  467.                         if (!tsTimer[sSelTimer].bRunning) 
  468.                             tsTimer[sSelTimer].sValue = GetDigits (hwnd);
  469.  
  470.                         SetButtons (hwnd, tsTimer[i].bRunning, sSelTimer, i);
  471.                         sSelTimer = i;
  472.  
  473.                         if (tsTimer[sSelTimer].bRunning) {
  474.                             time (&dwCurrTime);
  475.                             sTime = ComputeTime (dwCurrTime, tsTimer[i].dwStart,
  476.                                                  tsTimer[i].sValue);
  477.                         } else {
  478.                             sTime = tsTimer[i].sValue;
  479.                         }
  480.                         SetDigits (hwnd, sTime);
  481.                     }
  482.                     return 0;
  483.  
  484.                 case IDD_BSECONDS:
  485.                     SetDigits (hwnd, ++tsTimer[sSelTimer].sValue);                    
  486.                     return 0;
  487.  
  488.                 case IDD_BMINUTES:
  489.                     tsTimer[sSelTimer].sValue += 60;
  490.                     SetDigits (hwnd, tsTimer[sSelTimer].sValue);
  491.                     return 0;
  492.             }
  493.             break;
  494.  
  495.         case WM_DESTROY:
  496.             if (sActiveTimers) KillTimer (hwnd, 1);
  497.             //
  498.             //Save values
  499.             //
  500.             if (GetWindowLong (GetDlgItem (hwnd, IDD_SECDIG), GWL_STYLE)
  501.                  & DIGS_LED) 
  502.                 WritePrivateProfileString (szAppName, "LCD", "0", 
  503.                                            szProfileName);
  504.             else        
  505.                 WritePrivateProfileString (szAppName, "LCD", "1", 
  506.                                            szProfileName);
  507.  
  508.             if (IsIconic (hwnd)) {
  509.                 WritePrivateProfileString (szAppName, "Icon", "1", 
  510.                                            szProfileName);
  511.             } else if (!IsIconic (hwnd)) {
  512.                 WritePrivateProfileString (szAppName, "Icon", "0", 
  513.                                            szProfileName);
  514.                 GetWindowRect (hwnd, &rect);
  515.                 itoa (rect.left, szTemp, 10);
  516.                 WritePrivateProfileString (szAppName, "x", szTemp, 
  517.                                            szProfileName);
  518.                 itoa (rect.top, szTemp, 10);
  519.                 WritePrivateProfileString (szAppName, "y", szTemp, 
  520.                                            szProfileName);
  521.             }
  522.             PostQuitMessage (0);
  523.             return 0;
  524.     }
  525.     return DefWindowProc (hwnd, message, wParam, lParam);
  526. }
  527. 
  528.