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