home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / timup13.zip / source.zip / timeup.c < prev    next >
C/C++ Source or Header  |  1993-06-21  |  15KB  |  532 lines

  1. /* TimeUP.C, Ronald Van Iwaarden 1993
  2. // Compiler: EMX/GCC 0.8f or better.
  3.  
  4. // Modified from
  5. // VMEM.C - Copyright (c) 1992 M.B.Mallory
  6.  
  7. // TimeUP displays the amount time has elapsed since OS/2 2.0 was last
  8. // booted in the smallest window possible... a title bar. TimeUP can run
  9. // along the edge of the screen (or under it's own icon) with no loss of 
  10. // screen real estate.
  11.  
  12. */
  13.  
  14. #define INCL_WIN
  15. #define INCL_GPIPRIMITIVES
  16. #define INCL_DOSMISC
  17. #define INCL_WINWINDOWMGR
  18.  
  19. #include <os2.h>
  20. #include <string.h>
  21. #include <time.h>
  22. #include "timeup.h"
  23.  
  24. #define CMD (COMMANDMSG(&msg)->cmd)
  25.  
  26. /* data structure and profile info to be written to OS2.INI */
  27.  
  28. typedef LHANDLE HINI;
  29. typedef HINI *PHINI;
  30.  
  31. #define HINI_USERPROFILE   (HINI) -1L
  32.  
  33. typedef struct
  34.    {
  35.    POINTL pt;
  36.    SHORT savescrpos;
  37.    SHORT format;
  38.    ULONG record;
  39.    } INIINFO;
  40.  
  41.  
  42. #define MEM_APP      "TIMEUP"
  43. #define MEM_KEY      "OptionsData"
  44.  
  45. /* define items to remove from the System menu*/
  46. #define MIR_COUNT    5
  47. #define MIR_DATA     SC_RESTORE, SC_SIZE, SC_HIDE, SC_MINIMIZE, SC_MAXIMIZE
  48.  
  49. /* define additions to the System menu*/
  50. #define MI_COUNT     4
  51. #define IDM_ABOUT    88
  52. #define IDM_OPTIONS  89
  53. #define MI_STR       0, 0, "~About  TIMEUP", "TIMEUP  ~Options"
  54. #define MI_DATA      MIT_END, MIS_SEPARATOR, 0, 0, 0, 0,\
  55.                      MIT_END, MIS_SEPARATOR, 0, 0, 0, 0,\
  56.                      MIT_END, MIS_TEXT, 0, IDM_ABOUT, 0, 0,\
  57.                      MIT_END, MIS_TEXT, 0, IDM_OPTIONS, 0, 0
  58.  
  59. /* initial title bar text*/
  60. #define TITLEBAR_TEXT "Time Since Boot"
  61.  
  62. /* no timers error message*/
  63. #define TIMER_TITLE  "Error initializing  TIMEUP"
  64. #define TIMER_TEXT   "TIMEUP cannot be initialized because"\
  65.                      " too many timers are already running."\
  66.                      " Close some applications to free system resources."
  67.  
  68. /* prototype for revectored (subclassed) system frame procedure*/
  69. MRESULT (* EXPENTRY DefaultFrameProc) (HWND, ULONG, MPARAM, MPARAM);
  70.  
  71. /* prototypes for new frame & dialog procedures*/
  72. MRESULT EXPENTRY NewFrameProc (HWND, ULONG, MPARAM, MPARAM);
  73. MRESULT EXPENTRY AboutProc (HWND, ULONG, MPARAM, MPARAM);
  74. MRESULT EXPENTRY OptionsProc (HWND, ULONG, MPARAM, MPARAM);
  75. MRESULT EXPENTRY HelpProc (HWND, ULONG, MPARAM, MPARAM);
  76.  
  77. /* misc. prototypes*/
  78. VOID ReviseSystemMenu (VOID);
  79. VOID SetFramePosition (PRECTL);
  80. ULONG GetTimeUp (VOID);
  81. BOOL GetIniInfo (VOID);
  82. void _setuparg (void);
  83. CHAR* NumToDate(ULONG);
  84.  
  85.  
  86. CHAR * ULongToString (LONG number)
  87. {
  88.   static char str[5];
  89.   LONG pwrof10 = 1000;
  90.   int temp;
  91.   if (pwrof10 > number) pwrof10 = pwrof10/10;
  92.   if (pwrof10 > number) pwrof10 = pwrof10/10;
  93.   if (pwrof10 > number) pwrof10 = pwrof10/10;
  94.   strcpy(str,"");
  95.   while (pwrof10 != 0){
  96.     temp=number/pwrof10;
  97.     switch(temp){
  98.     case 0: strcat(str,"0"); break;
  99.     case 1: strcat(str,"1"); break;
  100.     case 2: strcat(str,"2"); break;
  101.     case 3: strcat(str,"3"); break;
  102.     case 4: strcat(str,"4"); break;
  103.     case 5: strcat(str,"5"); break;
  104.     case 6: strcat(str,"6"); break;
  105.     case 7: strcat(str,"7"); break;
  106.     case 8: strcat(str,"8"); break;
  107.     case 9: strcat(str,"9"); break;
  108.     }
  109.     number = number - pwrof10*(temp);
  110.     pwrof10 = pwrof10/10;
  111.     };
  112.   if (strlen(str) == 0) strcat(str,"0");
  113.   return str;
  114. };
  115.  
  116.  
  117. /* globals*/
  118. HWND hwndFrame, hwndTitleBar;
  119. INIINFO ini;
  120. BOOL bRestoreFlag = FALSE;
  121. BOOL bDisplayTimeUP = FALSE;
  122. ULONG BootTime;
  123.  
  124. char * NumToDate(ULONG Number)
  125. {
  126.   ULONG Day, Hour, Minute;
  127.   static char str[400];
  128.   static double OldNumber = 0;
  129.   Day    = Number/NumDay;
  130.   Hour   = (Number/NumHour) % 24;
  131.   Minute = Number/NumMilSeconds - Day*1440 - Hour*60;
  132.   strcpy (str, ULongToString (Day));
  133.   if (Day != 1) strcat(str, " Days  ");
  134.   else          strcat(str, " Day  ");
  135.   strcat (str, ULongToString (Hour));
  136.   strcat (str, ":");
  137.   if (Minute < 10) strcat (str, "0");
  138.   strcat (str, ULongToString (Minute));
  139.   return str;
  140. }
  141.  
  142.  
  143.  
  144.  
  145. /* declare dummy function to eliminate command line parsing */
  146. void _setuparg (void)  
  147.     {}
  148.  
  149.  
  150. ULONG GetTimeUP (VOID)
  151. {
  152.   LONG X;
  153.   DosQuerySysInfo (14, 14, &X, sizeof X); /* Sec's elapsed since boot*/
  154.   return X/1000;
  155. }
  156.  
  157.  
  158. int main (void)
  159. {
  160.   HAB hab;
  161.   HMQ hmq;
  162.   QMSG qmsg;
  163.   RECTL rect;
  164.   
  165.   FRAMECDATA framecdata = {
  166.     sizeof framecdata,
  167.     FCF_TITLEBAR | FCF_SYSMENU | FCF_TASKLIST | FCF_ICON | FCF_BORDER,
  168.     0,
  169.     TIMEUP_ICON };
  170.   
  171.   hab = WinInitialize (0);            /* create anchor block*/
  172.   hmq = WinCreateMsgQueue (hab, 0);   /* create message queue*/
  173.   
  174.   /* initialize handle & create frame window*/
  175.   hwndFrame = WinCreateWindow (
  176.                    HWND_DESKTOP,           /* window parent */
  177.                    WC_FRAME,               /* frame window class */
  178.                    TITLEBAR_TEXT,          /* window text */
  179.                    0,                      /* frame creation style (invisible) */
  180.                    0,0,                    /* x, y position */
  181.                    0,0,                    /* width, height */
  182.                    0,                      /* owner window */
  183.                    HWND_TOP,               /* top of z-order */
  184.                    ID_FRAME,               /* frame window ID */
  185.                    &framecdata,            /* control data */
  186.                    0);                     /* presentation parameters */
  187.   
  188.   /* initialize handle to title bar*/
  189.   hwndTitleBar = WinWindowFromID (hwndFrame, FID_TITLEBAR);
  190.   
  191.   /* hook the vector to this instance of the system frame procedure*/
  192.   DefaultFrameProc = WinSubclassWindow (hwndFrame, (PFNWP) NewFrameProc);
  193.  
  194.  
  195.   ReviseSystemMenu ();   /* delete disabled stuff & add new items*/
  196.  
  197.   BootTime = time(NULL) - GetTimeUP(); /* get the time since boot in seconds */
  198.  
  199.   SetFramePosition (&rect);    /* initial window frame position*/
  200.  
  201.  
  202.   WinSetWindowPos (hwndFrame, HWND_TOP, rect.xLeft, rect.yBottom,
  203.            rect.xRight, rect.yTop + 1, SWP_SIZE | SWP_MOVE | SWP_SHOW);
  204.   
  205.   if (WinStartTimer (hab, hwndFrame, ID_TIMER, 1000))
  206.     /* enter message loop*/
  207.     {
  208.       while (WinGetMsg (hab, &qmsg, 0, 0, 0))
  209.     {
  210.       WinDispatchMsg (hab, &qmsg);
  211.     }      
  212.  
  213.       WinStopTimer (hab, hwndFrame, ID_TIMER);
  214.     }
  215.   
  216.   else    /* display error message*/
  217.     WinMessageBox (HWND_DESKTOP, hwndFrame, TIMER_TEXT, TIMER_TITLE, 0,
  218.            MB_OK | MB_WARNING | MB_MOVEABLE );
  219.   
  220.   /* destroy window frame and exit*/
  221.   WinDestroyWindow (hwndFrame);
  222.   WinDestroyMsgQueue (hmq);
  223.   WinTerminate (hab);
  224.   return 0;
  225. }
  226.  
  227.  
  228. VOID ReviseSystemMenu (VOID)
  229. {
  230.   HWND hwndSysMenu;
  231.   MENUITEM miSysMenu;
  232.   SHORT sSysMenu, i;
  233.   static PCHAR pItemIns[MI_COUNT]  = { MI_STR };
  234.   static SHORT sItemDel[MIR_COUNT] = { MIR_DATA };
  235.     static MENUITEM mi[MI_COUNT]     = { MI_DATA };
  236.   
  237.   /* get handle of the system menu*/
  238.   hwndSysMenu = WinWindowFromID (hwndFrame, FID_SYSMENU);
  239.   
  240.   /* get ID of the system menu bitmap*/
  241.   sSysMenu = SHORT1FROMMR (
  242.             WinSendMsg (hwndSysMenu, MM_ITEMIDFROMPOSITION, 0, 0));
  243.   
  244.   /* get handle of system submenu (in miSysMenu structure)*/
  245.     WinSendMsg (hwndSysMenu, MM_QUERYITEM,
  246.         MPFROM2SHORT (sSysMenu, FALSE), MPFROMP (&miSysMenu));
  247.   
  248.   /* remove disabled and unneeded menu items*/
  249.   for (i = 0; i < MIR_COUNT; i++)
  250.     WinSendMsg (miSysMenu.hwndSubMenu, MM_REMOVEITEM,
  251.                 MPFROM2SHORT (sItemDel[i], FALSE), 0);
  252.   
  253.   /* insert new menu items*/
  254.   for (i = 0; i < MI_COUNT; i++)
  255.     WinSendMsg (miSysMenu.hwndSubMenu, MM_INSERTITEM,
  256.                 MPFROMP (mi + i), MPFROMP (pItemIns[i]));
  257.     }
  258.  
  259.  
  260.  
  261.  
  262.  
  263. BOOL GetIniInfo (VOID)  /* get data from OS2.INI, if it exists*/
  264. {
  265.   ULONG length = sizeof ini;
  266.   HINI hini = HINI_USERPROFILE;
  267.   BOOL rval;
  268.   rval = PrfQueryProfileData (hini, MEM_APP, MEM_KEY, &ini, &length);
  269.   if (!rval)
  270.     {
  271.       ini.record = 0;
  272.       ini.record = 0;
  273.       ini.savescrpos  = TRUE;     /* set defaults*/
  274.       ini.format  = ARB_TIMEUP;
  275.     }
  276.   if (ini.format == ARB_TIMEUP) bDisplayTimeUP = TRUE;
  277.   return rval;
  278. }
  279.  
  280.  
  281. VOID SetFramePosition (PRECTL prect)
  282. {
  283.   CHAR pPtr[30];
  284.   HPS hps ;
  285.   POINTL apt[TXTBOX_COUNT];
  286.   SHORT xMax, yMax;
  287.   
  288.   /* produce initial string*/
  289.   strcpy (pPtr, "  Time Since Boot  R ");
  290.   
  291.   /* get length of text string*/
  292.   hps = WinGetPS (hwndFrame);
  293.   GpiQueryTextBox (hps, strlen (pPtr), pPtr, TXTBOX_COUNT, apt);
  294.   WinReleasePS (hps);
  295.   
  296.   /* put text length + room for system menu into RECTL */
  297.     prect->xLeft = prect->yBottom = prect->yTop = 0;
  298.   prect->xRight = (apt[2].x - apt[0].x) + (apt[0].y - apt[1].y);
  299.   
  300.   /* expand text string to frame coordinates*/
  301.   WinCalcFrameRect (hwndFrame, prect, FALSE);
  302.   
  303.     /* get current absolute screen size*/
  304.   xMax = WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN);
  305.   yMax = WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN);
  306.  
  307.   if (GetIniInfo ())
  308.         {
  309.       /* set window position to OS2.INI data*/
  310.       prect->xLeft = ini.pt.x;
  311.       prect->yBottom = ini.pt.y;
  312.       
  313.       /* logic to ensure window displays on current screen size*/
  314.       if ((prect->xLeft + prect->xRight / 2 - 3) > xMax)
  315.             prect->xLeft = xMax - prect->xRight / 2 + 3;
  316.       if (prect->xLeft + 3 < 0)
  317.             prect->xLeft = -3;
  318.       if ((prect->yBottom + prect->yTop - 3) > yMax)
  319.             prect->yBottom = yMax - prect->yTop + 3;
  320.       if (prect->yBottom + 3 < 0)
  321.             prect->yBottom = -3;
  322.         }
  323.   else
  324.     {
  325.       /* set window position to center of screen (default)*/
  326.       prect->xLeft = (xMax - prect->xRight) / 2;
  327.       prect->yBottom = (yMax - prect->yTop) / 2;
  328.     }
  329.   
  330.   /* set INIINFO structure to current values*/
  331.   ini.pt.x = prect->xLeft;
  332.   ini.pt.y = prect->yBottom;
  333. }
  334.  
  335.  
  336. MRESULT EXPENTRY 
  337.   NewFrameProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  338. {
  339.   ULONG MSecondsUP;
  340.   static  CHAR oldtext[40];
  341.   CHAR pTempText[40];
  342.   HINI hini = HINI_USERPROFILE;
  343.   POINTL pt;
  344.   MRESULT rc;
  345.   ULONG display;
  346.  
  347.   switch (msg)
  348.     {
  349.     case WM_TIMER:
  350.       MSecondsUP = difftime(time(NULL), BootTime);
  351.       display = (bDisplayTimeUP) ? MSecondsUP : ini.record;
  352.       strcpy(pTempText, NumToDate(display));
  353.       if (!bDisplayTimeUP) strcat(pTempText, " R");
  354.       if (strcmp(oldtext, pTempText)) /* determine whether or not to update */
  355.     {                             /* the display */
  356.       strcpy(oldtext, pTempText);
  357.       WinSetWindowText (hwndFrame, pTempText);
  358.  
  359.       /* check if update of record is needed */
  360.       if (MSecondsUP > ini.record)
  361.         {
  362.           ini.record = MSecondsUP;
  363.           PrfWriteProfileData(hini,MEM_APP,MEM_KEY,&ini,(ULONG)sizeof ini);
  364.         }
  365.     }
  366.       return 0 ;
  367.       
  368.     case WM_PAINT:
  369.     case WM_ACTIVATE:
  370.       /* set title bar hilite to always ON*/
  371.       rc = DefaultFrameProc (hwnd, msg, mp1, mp2);
  372.       WinSendMsg (hwndTitleBar, TBM_SETHILITE, (MPARAM) TRUE, 0);
  373.       return rc;
  374.       
  375.     case WM_COMMAND:
  376.       switch (CMD)
  377.     {
  378.     case IDM_ABOUT:     /* open About dialog box*/
  379.       WinDlgBox (HWND_DESKTOP, hwnd, 
  380.              (PFNWP) AboutProc, 0, IDD_ABOUT, 0);    
  381.       return 0;
  382.       
  383.     case IDM_OPTIONS:   /* open Options dialog box*/
  384.       WinDlgBox (HWND_DESKTOP, hwnd, 
  385.              (PFNWP) OptionsProc, 0, IDD_OPTIONS, 0);
  386.       return 0;
  387.     }
  388.       break;
  389.     case WM_BUTTON1DBLCLK:
  390.     case WM_BUTTON3CLICK:
  391.       /*  activate options dialog box with double-click of mouse*/
  392.       /*  button 1 on the title bar  Actually does not work right now.*/
  393.       WinDlgBox (HWND_DESKTOP, hwnd, 
  394.          (PFNWP) OptionsProc, 0, IDD_OPTIONS, 0);
  395.       return 0;
  396.       
  397.     case WM_BUTTON2DBLCLK:
  398.       /*  switch from Time UP to maximum Time UP with double-click of mouse*/
  399.       /*  button 2 on the title bar*/
  400.       bDisplayTimeUP ^= TRUE;  /* Toggle Display */
  401.       WinSendMsg (hwndFrame, WM_TIMER, 0,  0);
  402.       if (ini.format == ARB_TIMEUP) ini.format = ARB_RECORD;
  403.       else ini.format = ARB_TIMEUP;
  404.       return 0;
  405.     case WM_QUIT:
  406.     case WM_DESTROY:
  407.       if (bRestoreFlag)
  408.     /* delete data from OS2.INI*/
  409.     PrfWriteProfileData (hini, MEM_APP, 0, 0, 0);
  410.       else
  411.     {
  412.       if (ini.savescrpos)
  413.         {
  414.           /* get current screen position*/
  415.           pt.x = pt.y = 0;
  416.           WinMapWindowPoints (hwndFrame, HWND_DESKTOP, &pt, 1);
  417.           ini.pt.x = pt.x;
  418.           ini.pt.y = pt.y;
  419.     }
  420.       /* write current settings to OS2.INI*/
  421.       PrfWriteProfileData(hini, MEM_APP, MEM_KEY, &ini, (ULONG)sizeof ini);
  422.     }
  423.     }
  424.   return DefaultFrameProc (hwnd, msg, mp1, mp2);
  425. }
  426.   
  427.  
  428. MRESULT EXPENTRY 
  429.   AboutProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  430. {
  431.   if (msg == WM_COMMAND)
  432.     if (CMD == DID_OK || CMD == DID_CANCEL)
  433.       {
  434.     WinDismissDlg (hwnd, TRUE);
  435.     return 0;
  436.       }
  437.   return WinDefDlgProc (hwnd, msg, mp1, mp2);
  438. }
  439.  
  440.  
  441. MRESULT EXPENTRY 
  442.   HelpProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  443. {
  444.     if (msg == WM_COMMAND)
  445.       if (CMD == DID_OK || CMD == DID_CANCEL)
  446.             {
  447.           WinDismissDlg (hwnd, TRUE);
  448.           return 0;
  449.             }
  450.     return WinDefDlgProc (hwnd, msg, mp1, mp2);
  451.   }
  452.  
  453.  
  454. MRESULT EXPENTRY 
  455.   OptionsProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  456. {
  457.   SHORT sTemp;
  458.   if (msg == WM_CONTROL)
  459.     {
  460.       switch (SHORT1FROMMP (mp1)) /* get settings as they are changed*/
  461.     {
  462.     case ACB_SAVESCRPOS:
  463.       if (!bRestoreFlag)
  464.         {
  465.           ini.savescrpos ^= TRUE; /* toggle flag*/
  466.           WinSendDlgItemMsg (hwnd, ACB_SAVESCRPOS, BM_SETCHECK,
  467.                  (MPARAM) ini.savescrpos, 0);
  468.         }
  469.       return 0;
  470.       
  471.     case ACB_RESTORE:
  472.       bRestoreFlag ^= TRUE; /* toggle flag*/
  473.       if (bRestoreFlag)
  474.         WinSendDlgItemMsg (hwnd, ACB_SAVESCRPOS, BM_SETCHECK,
  475.                    (MPARAM) CB_3RDSTATE, 0);
  476.       else
  477.         WinSendDlgItemMsg (hwnd, ACB_SAVESCRPOS, BM_SETCHECK,
  478.                    (MPARAM) ini.savescrpos, 0);
  479.       return 0;
  480.       
  481.     case ARB_RECORD:
  482.       bDisplayTimeUP = FALSE;  /* Toggle Display */
  483.       WinSendMsg (hwndFrame, WM_TIMER, 0,  0);
  484.       ini.format = ARB_RECORD;
  485.       return 0;
  486.     case ARB_TIMEUP:
  487.       bDisplayTimeUP = TRUE;  /* Toggle Display */
  488.       WinSendMsg (hwndFrame, WM_TIMER, 0,  0);
  489.       ini.format = ARB_TIMEUP;
  490.       return 0;
  491.     }
  492.     }
  493.   
  494.   if (msg == WM_COMMAND)
  495.     {
  496.       switch (CMD)
  497.     {
  498.     case DID_OK:        /* close dialog box */
  499.     case DID_CANCEL:
  500.       WinDismissDlg (hwnd, TRUE);
  501.       return 0;
  502.       
  503.     case DID_ABOUT:
  504.       WinDlgBox (HWND_DESKTOP, hwnd, 
  505.              (PFNWP) AboutProc, 0, IDD_ABOUT, 0);    
  506.       return 0;
  507.       
  508.     case DID_HELP:
  509.       WinDlgBox (HWND_DESKTOP, hwnd, 
  510.              (PFNWP) HelpProc, 0, IDD_HELP, 0);
  511.       return 0;
  512.     }
  513.     }
  514.   
  515.   if (msg == WM_INITDLG)
  516.     {
  517.       sTemp = bRestoreFlag ? CB_3RDSTATE : ini.savescrpos;
  518.       
  519.       /* send current settings to Options dialog */
  520.       WinCheckButton (hwnd, ini.format, BM_SETCHECK);
  521.       WinSendDlgItemMsg (hwnd, ACB_SAVESCRPOS, BM_SETCHECK,
  522.              MPFROM2SHORT (sTemp, 0), 0);
  523.       WinSendDlgItemMsg (hwnd, ACB_RESTORE, BM_SETCHECK,
  524.              (MPARAM) bRestoreFlag, 0);
  525.       return 0;
  526.     }
  527.   
  528.   return WinDefDlgProc (hwnd, msg, mp1, mp2);
  529. }
  530.  
  531.  
  532.