home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / VMEM.ZIP / VMEM.C < prev    next >
C/C++ Source or Header  |  1993-03-01  |  14KB  |  450 lines

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