home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / memsz331.zip / Source.zip / ITEMS.CPP < prev    next >
Text File  |  1996-12-30  |  47KB  |  1,329 lines

  1. /****************************************************************** ITEMS.CPP
  2.  *                                                                          *
  3.  *                     Display Item Class Functions                         *
  4.  *                                                                          *
  5.  ****************************************************************************/
  6.  
  7. #define INCL_BASE
  8. #define INCL_DOSDEVIOCTL
  9. #define INCL_PM
  10. #include <os2.h>
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <time.h>
  16.  
  17. #include "Config.h"
  18. #include "Debug.h"
  19. #include "DQPS.h"
  20. #include "MemSize.h"
  21. #include "Support.h"
  22. #include "ReString.h"
  23.  
  24. #include "Items.h"
  25.  
  26. static int MeasureValue ( char *Text, char *Label, BOOL ShowK, BOOL ShowM ) {
  27.    int Result ;
  28.    if ( ShowK == SHOWK_NEVER ) {
  29.       Result = sprintf ( Text, "%s 1,234,567,890 ", Label ) ;
  30.    } else if ( !ShowM ) {
  31.       Result = sprintf ( Text, "%s 1,234,567K", Label ) ;
  32.    } else {
  33.       Result = sprintf ( Text, "%s 1,234M", Label ) ;
  34.    } /* endif */
  35.    return ( Result ) ;
  36.  
  37. inline ULONG KiloScale ( ULONG Value, int ShowTrueK=TRUE, int Scale=1 ) {
  38.    if ( ShowTrueK ) {
  39.       return ( (Value+(0x200/Scale))/(0x400/Scale) ) ;
  40.    } else {
  41.       return ( (Value+(500/Scale))/(1000/Scale) ) ;
  42.    } /* endif */
  43. }
  44.  
  45. inline ULONG MegaScale ( ULONG Value, int ShowTrueK=TRUE, int Scale=1 ) {
  46.    if ( ShowTrueK ) {
  47.       return ( (Value+(0x80000/Scale))/(0x100000/Scale) ) ;
  48.    } else {
  49.       return ( (Value+(500000/Scale))/(1000000/Scale) ) ;
  50.    } /* endif */
  51. }
  52.  
  53. static void FormatValue ( ULONG Value, char Text[], COUNTRYINFO &CountryInfo, int ShowK=SHOWK_ABOVE512, int ShowTrueK=TRUE, int ShowM=TRUE, int Scale=1 ) {
  54.  
  55.    int MegaBreak = ShowTrueK ? 0x800000/Scale : 8000000/Scale ;
  56.    int KiloBreak = ShowTrueK ? 0x80000/Scale : 500000/Scale ;
  57.  
  58.    switch ( ShowK ) {
  59.       case SHOWK_NEVER:
  60.          sprintf ( Text, "%lu", Value*Scale ) ;
  61.          break;
  62.       case SHOWK_ALWAYS:
  63.          if ( !ShowM || ( Value < MegaBreak ) )
  64.             sprintf ( Text, "%lu", KiloScale(Value,ShowTrueK,Scale) ) ;
  65.          else 
  66.             sprintf ( Text, "%lu", MegaScale(Value,ShowTrueK,Scale) ) ;
  67.          break;
  68.       case SHOWK_ABOVE512:
  69.       default:
  70.          if ( Value < KiloBreak )
  71.             sprintf ( Text, "%lu", Value*Scale ) ;
  72.          else if ( !ShowM || ( Value < MegaBreak ) )
  73.             sprintf ( Text, "%lu", KiloScale(Value,ShowTrueK,Scale) ) ;
  74.          else
  75.             sprintf ( Text, "%lu", MegaScale(Value,ShowTrueK,Scale) ) ;
  76.          break;
  77.    } /* endswitch */
  78.  
  79.    char Work[100] ;
  80.    char *p1 = Text ;
  81.    char *p2 = Work ;
  82.    while ( *p1 ) {
  83.       *p2 = *p1 ;
  84.       p1 ++ ;
  85.       p2 ++ ;
  86.       if ( *p1 ) {
  87.          if ( strlen(p1) % 3 == 0 ) {
  88.             *p2 = CountryInfo.szThousandsSeparator [0] ;
  89.             p2 ++ ;
  90.          } /* endif */
  91.       } /* endif */
  92.    } /* endwhile */
  93.    *p2 = 0 ;
  94.    strcpy ( Text, Work ) ;
  95.  
  96.    p2 = Text + strlen(Text) ;
  97.    *(p2+1) = 0 ;
  98.    switch ( ShowK ) {
  99.       case SHOWK_NEVER:
  100.          *p2 = ' ' ;
  101.          break;
  102.       case SHOWK_ALWAYS:
  103.          if ( !ShowM || ( Value < MegaBreak ) )
  104.             *p2 = (char) ( ShowTrueK ? 'K' : 'k' ) ;
  105.          else 
  106.             *p2 = (char) ( ShowTrueK ? 'M' : 'm' ) ;
  107.          break;
  108.       case SHOWK_ABOVE512:
  109.       default:
  110.          if ( Value < KiloBreak )
  111.             *p2 = ' ' ;
  112.          else if ( !ShowM || ( Value < MegaBreak ) )
  113.             *p2 = (char) ( ShowTrueK ? 'K' : 'k' ) ;
  114.          else 
  115.             *p2 = (char) ( ShowTrueK ? 'M' : 'm' ) ;
  116.          break;
  117.    } /* endswitch */
  118. }
  119.  
  120.  
  121. Item::Item ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, Dde_Server *ddeserver, char *topic ) :
  122.    Id(id), Flag(TRUE), Value(0), pDdeServer(ddeserver), LevelSense(0) {
  123.    strcpy ( Name, pName ) ;
  124.    strcpy ( CurrentLabel, pCurrentLabel ) ;
  125.    strcpy ( DefaultLabel, pDefaultLabel ) ;
  126.    strcpy ( Topic, topic ) ;
  127.    pDdeServer->AddItem ( Topic, DefaultLabel, DDEFMT_TEXT, "", 1 ) ;
  128.    pDdeItem = pDdeServer->FindItem ( Topic, DefaultLabel ) ;
  129.    NormalColors [0] = 0xFFFFFF ;
  130.    NormalColors [1] = 0x000000 ;
  131.    WarningColors[0] = 0xFFFF00 ;
  132.    WarningColors[1] = 0x000000 ;
  133.    ErrorColors  [0] = 0xFF0000 ;
  134.    ErrorColors  [1] = 0xFFFFFF ;
  135. } /* endmethod */
  136.  
  137. Item::~Item ( ) {
  138.    pDdeServer->RemoveItem ( Topic, DefaultLabel ) ;
  139. } /* endmethod */
  140.  
  141. void Item::GetProfile ( HINI IniHandle ) {
  142.  
  143.      Flag = TRUE ;  ULONG Size ;
  144.      if ( PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Name), &Size )
  145.         AND ( ( Size == sizeof(Flag) ) OR ( Size == sizeof(short) ) )
  146.         AND PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Name), &Flag, &Size ) ) {
  147.      } /* endif */
  148.  
  149.      char Tag [80] ;
  150.      strcpy ( Tag, PCHAR(Name) ) ;
  151.      strcat ( Tag, " Label" ) ;
  152.      if ( PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Tag), &Size )
  153.         AND ( Size == sizeof(CurrentLabel) )
  154.         AND PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Tag), &CurrentLabel, &Size ) ) {
  155.      } /* endif */
  156.  
  157.      strcpy ( Tag, PCHAR(Name) ) ;
  158.      strcat ( Tag, " Warning" ) ;
  159.      if ( PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Tag), &Size )
  160.         AND ( Size == sizeof(WarningLevel) )
  161.         AND PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Tag), &WarningLevel, &Size ) ) {
  162.      } /* endif */
  163.  
  164.      strcpy ( Tag, PCHAR(Name) ) ;
  165.      strcat ( Tag, " Error" ) ;
  166.      if ( PrfQueryProfileSize ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Tag), &Size )
  167.         AND ( Size == sizeof(ErrorLevel) )
  168.         AND PrfQueryProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Tag), &ErrorLevel, &Size ) ) {
  169.      } /* endif */
  170.  
  171. } /* endmethod */
  172.  
  173. void Item::PutProfile ( HINI IniHandle ) {
  174.  
  175.    PrfWriteProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Name), &Flag, sizeof(Flag) ) ;
  176.  
  177.    // Save custom label, if any.
  178.    char Tag [80] ;
  179.    strcpy ( Tag, PCHAR(Name) ) ;
  180.    strcat ( Tag, " Label" ) ;
  181.    if ( strcmp ( CurrentLabel, DefaultLabel ) ) {
  182.       PrfWriteProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Tag), CurrentLabel, sizeof(CurrentLabel) ) ;
  183.    } else {
  184.       PrfWriteProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Tag), 0, 0 ) ;
  185.    } /* endif */
  186.  
  187.    // If the item uses a warning/error threshold at all . . .
  188.    if ( LevelSense ) {
  189.  
  190.       // Save the warning threshold value.
  191.       ULONG Threshold = WarningLevel ;
  192.       strcpy ( Tag, PCHAR(Name) ) ;
  193.       strcat ( Tag, " Warning" ) ;
  194.       PrfWriteProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Tag), &Threshold, sizeof(Threshold) ) ;
  195.  
  196.       // Save the error threshold value.
  197.       Threshold = ErrorLevel ;
  198.       strcpy ( Tag, PCHAR(Name) ) ;
  199.       strcat ( Tag, " Error" ) ;
  200.       PrfWriteProfileData ( IniHandle, PSZ(PROGRAM_NAME), PSZ(Tag), &Threshold, sizeof(Threshold) ) ;
  201.  
  202.    } /* endif */
  203.  
  204. } /* endmethod */
  205.  
  206. void Item::FormatLine ( char *Buffer, int MaxWidth ) {
  207.  
  208.    // Get the left and right texts for the line.
  209.    char Label[100], Text[100] ;
  210.    FormatText ( Label, Text, QueryValue() ) ;
  211.  
  212.    // Format the line.
  213.    strcat ( Buffer, Label ) ;
  214.    sprintf ( Buffer+strlen(Buffer), "%*s", MaxWidth-strlen(Label)-strlen(Text), "" ) ;
  215.    strcat ( Buffer, Text ) ;
  216.    strcat ( Buffer, "\r\n" ) ;
  217. }
  218.  
  219.  
  220. void Item::DdeUpdate ( char *Text ) {
  221.  
  222.    int Format, Size ; PVOID Data ;
  223.    pDdeItem->Query ( Format, Data, Size ) ;
  224.  
  225.    int NewSize = strlen(Text) + 1 ;
  226.    if ( Data && memcmp ( Text, Data, NewSize ) )
  227.       pDdeItem->Update ( DDEFMT_TEXT, Text, NewSize ) ;
  228. }
  229.  
  230.  
  231. void Item::Paint ( HPS hPS, RECTL &Rectangle,
  232.    char *Label, char *Text, ULONG NewValue, int Scale ) {
  233.  
  234.    COLOR *Colors = NormalColors ;
  235.    if ( LevelSense > 0 ) {
  236.       if ( NewValue >= ErrorLevel/Scale ) {
  237.          Colors = ErrorColors ;
  238.       } else if ( NewValue >= WarningLevel/Scale ) {
  239.          Colors = WarningColors ;
  240.       } /* endif */
  241.    } else if ( LevelSense < 0 ) {
  242.       if ( NewValue*Scale <= ErrorLevel/Scale ) {
  243.          Colors = ErrorColors ;
  244.       } else if ( NewValue <= WarningLevel/Scale ) {
  245.          Colors = WarningColors ;
  246.       } /* endif */
  247.    } /* endif */
  248.  
  249.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle,
  250.       Colors[1], Colors[0], DT_RIGHT | DT_BOTTOM | DT_ERASERECT ) ;
  251.  
  252.    WinDrawText ( hPS, strlen(Label), PSZ(Label), &Rectangle,
  253.       Colors[1], Colors[0], DT_LEFT | DT_BOTTOM ) ;
  254.  
  255.    Value = NewValue ;
  256. }
  257.  
  258.  
  259. Clock::Clock ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  260.    Dde_Server *pDdeServer, char *Topic, COUNTRYINFO &countryinfo,
  261.    char *szam, char *szpm, ResourceString *daysofweek, BOOL showseconds, BOOL hour24 )
  262.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ),
  263.    DaysOfWeek(daysofweek), ShowSeconds(showseconds), Hour24(hour24) {
  264.    CountryInfo = countryinfo ;
  265.    memcpy ( szAm, szam, min(strlen(szam),sizeof(szAm)-1) ) ;
  266.    szAm [ sizeof(szAm) - 1 ] = 0 ;
  267.    memcpy ( szPm, szpm, min(strlen(szpm),sizeof(szPm)-1) ) ;
  268.    szPm [ sizeof(szPm) - 1 ] = 0 ;
  269. } /* endmethod */
  270.  
  271. int Clock::Measure ( HPS hPS, RECTL &Rectangle ) {
  272.    int Result ;
  273.    char Text [100] ;
  274.    if ( CountryInfo.fsDateFmt != DATEFMT_YY_MM_DD ) {
  275.       Result = sprintf ( Text, " MMM, MM-DD HH:MM%s%s ", ShowSeconds?":SS":"", CountryInfo.fsTimeFmt?"":"xx" ) ;
  276.    } else {
  277.       Result = sprintf ( Text, " MM-DD MMM HH:MM%s%s ", ShowSeconds?":SS":"", CountryInfo.fsTimeFmt?"":"xx" ) ;
  278.    } /* endif */
  279.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  280.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  281.    return ( Result ) ;
  282. }
  283.  
  284. struct Date_Time {
  285.    unsigned Weekday : 3 ;
  286.    unsigned Month : 4 ;
  287.    unsigned Day : 5 ;
  288.    unsigned Hours : 5 ;
  289.    unsigned Minutes : 6 ;
  290.    unsigned Seconds : 6 ;
  291. } ;
  292.  
  293. ULONG Clock::NewValue ( void ) {
  294.  
  295.   DATETIME DateTime ;
  296.   DosGetDateTime ( &DateTime ) ;
  297.  
  298.   struct Date_Time Dttm = { 
  299.      DateTime.weekday, 
  300.      DateTime.month, 
  301.      DateTime.day, 
  302.      DateTime.hours, 
  303.      DateTime.minutes, 
  304.      0 
  305.   } ;
  306.  
  307.   if ( ShowSeconds ) 
  308.      Dttm.Seconds = DateTime.seconds ;
  309.  
  310.   ULONG Time = * ( (PULONG) &Dttm ) ;
  311.  
  312.   return ( Time ) ;
  313. }
  314.  
  315.  
  316. void Clock::FormatText ( char *Label, char *Text, ULONG Time ) {
  317.  
  318.    strcpy ( Label, CurrentLabel ) ;
  319.  
  320.    struct Date_Time Dttm = * ( (struct Date_Time*) &Time ) ;
  321.    ULONG Dow    = Dttm.Weekday ;
  322.    ULONG Month  = Dttm.Month ;
  323.    ULONG Day    = Dttm.Day ;
  324.    ULONG Hour   = Dttm.Hours ;
  325.    ULONG Minute = Dttm.Minutes ;
  326.    ULONG Second = Dttm.Seconds ;
  327.  
  328.    switch ( CountryInfo.fsDateFmt ) {
  329.  
  330.       case DATEFMT_DD_MM_YY:
  331.          sprintf ( Text, "%0.*s, %02lu%s%02lu ",
  332.             strlen(PCHAR(*DaysOfWeek))/7, PSZ(*DaysOfWeek) + Dow*(strlen(PCHAR(*DaysOfWeek))/7),
  333.             Day, CountryInfo.szDateSeparator, Month ) ;
  334.          break ;
  335.  
  336.       case DATEFMT_YY_MM_DD:
  337.          sprintf ( Text, "%02lu%s%02lu %0.*s ",
  338.             Month, CountryInfo.szDateSeparator, Day,
  339.             strlen(PCHAR(*DaysOfWeek))/7, PSZ(*DaysOfWeek) + Dow*(strlen(PCHAR(*DaysOfWeek))/7) ) ;
  340.          break ;
  341.  
  342.       case DATEFMT_MM_DD_YY:
  343.       default:
  344.          sprintf ( Text, "%0.*s, %02lu%s%02lu ",
  345.             strlen(PCHAR(*DaysOfWeek))/7, PSZ(*DaysOfWeek) + Dow*(strlen(PCHAR(*DaysOfWeek))/7),
  346.             Month, CountryInfo.szDateSeparator, Day ) ;
  347.          break ;
  348.  
  349.    } /* endswitch */
  350.  
  351.    if ( Hour24 ) {
  352.       if ( ShowSeconds ) {
  353.          sprintf ( Text+strlen(Text), "%02lu%s%02lu%s%02lu",
  354.              Hour, CountryInfo.szTimeSeparator, Minute, CountryInfo.szTimeSeparator, Second ) ;
  355.       } else {
  356.          sprintf ( Text+strlen(Text), "%02lu%s%02lu",
  357.              Hour, CountryInfo.szTimeSeparator, Minute ) ;
  358.       } /* endif */
  359.    } else {
  360.       PCHAR AmPm ;
  361.       if ( Hour ) {
  362.          if ( Hour < 12 ) {
  363.             AmPm = szAm ;
  364.          } else if ( Hour == 12 ) {
  365.             if ( Minute )
  366.                AmPm = szPm ;
  367.             else
  368.                AmPm = szAm ;
  369.          } else if ( Hour > 12 ) {
  370.             Hour -= 12 ;
  371.             AmPm = szPm ;
  372.          } /* endif */
  373.       } else {
  374.          Hour = 12 ;
  375.          if ( Minute )
  376.             AmPm = szAm ;
  377.          else
  378.             AmPm = szPm ;
  379.       } /* endif */
  380.       if ( ShowSeconds )
  381.          sprintf ( Text+strlen(Text), "%02lu%s%02lu%s%02lu%s",
  382.              Hour, CountryInfo.szTimeSeparator, Minute, CountryInfo.szTimeSeparator, Second, AmPm ) ;
  383.       else
  384.          sprintf ( Text+strlen(Text), "%02lu%s%02lu%s",
  385.              Hour, CountryInfo.szTimeSeparator, Minute, AmPm ) ;
  386.    } /* endif */
  387.  
  388.    DdeUpdate ( Text ) ;
  389. }
  390.  
  391.  
  392. void Clock::FormatLine ( char *Buffer, int MaxWidth ) {
  393.  
  394.    // Get the left and right texts for the line.
  395.    char Label[100], Text[100] ;
  396.    FormatText ( Label, Text, QueryValue() ) ;
  397.  
  398.    // Format the line.
  399.    sprintf ( Buffer+strlen(Buffer), "%*s%s%*s", 
  400.       (MaxWidth-strlen(Text))/2, "", Text, 
  401.       MaxWidth-strlen(Text)-(MaxWidth-strlen(Text))/2, "" ) ;
  402.    strcat ( Buffer, "\r\n" ) ;
  403. }
  404.  
  405.  
  406. void Clock::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  407.    ULONG Time = NewValue ( ) ;
  408.    if ( Mandatory || ( Time != Value ) ) {
  409.       char Label[100], Text [100] ;
  410.       FormatText ( Label, Text, Time ) ;
  411.       WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle,
  412.          NormalColors[1], NormalColors[0], DT_CENTER | DT_BOTTOM | DT_ERASERECT ) ;
  413.       Value = Time ;
  414.    } /* endif */
  415. }
  416.  
  417.  
  418. ElapsedTime::ElapsedTime ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  419.    Dde_Server *pDdeServer, char *Topic, COUNTRYINFO &countryinfo,
  420.    ResourceString *day, ResourceString *days, BOOL showseconds )
  421.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ),
  422.    Day(day), Days(days), ShowSeconds(showseconds) {
  423.    CountryInfo = countryinfo ;
  424. } /* endmethod */
  425.  
  426. int ElapsedTime::Measure ( HPS hPS, RECTL &Rectangle ) {
  427.    int Result ;
  428.    char Text [100] ;
  429.    Result = sprintf ( Text, "%s XX %s, XX:XX%s", QueryCurrentLabel(), PSZ(*Days), ShowSeconds?":XX":"" ) ;
  430.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  431.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  432.    return ( Result ) ;
  433. }
  434.  
  435. ULONG ElapsedTime::NewValue ( void ) {
  436.    ULONG Milliseconds ;
  437.    DosQuerySysInfo ( QSV_MS_COUNT, QSV_MS_COUNT, &Milliseconds, sizeof(Milliseconds) ) ;
  438.    return ( Milliseconds / 1000 ) ;
  439. }
  440.  
  441. void ElapsedTime::FormatText ( char *Label, char *Text, ULONG Time ) {
  442.  
  443.    strcpy ( Label, CurrentLabel ) ;
  444.  
  445.    *Text = 0 ;
  446.  
  447.    ULONG NumberOfDays = Time / ( 60 * 60 * 24 ) ;
  448.    Time -= NumberOfDays * 60 * 60 * 24 ;
  449.    ULONG Hours   = Time / ( 60 * 60 ) ;
  450.    Time -= Hours * 60 * 60 ;
  451.    ULONG Minutes = Time / 60 ;
  452.    ULONG Seconds = Time % 60 ;
  453.  
  454.    if ( NumberOfDays ) {
  455.       sprintf ( Text, "%lu %s, ",
  456.          NumberOfDays, NumberOfDays > 1 ? PSZ(*Days) : PSZ(*Day) ) ;
  457.    } /* endif */
  458.  
  459.    if ( ShowSeconds )
  460.       sprintf ( Text+strlen(Text), "%lu%s%02lu%s%02lu",
  461.          Hours, CountryInfo.szTimeSeparator, Minutes,
  462.          CountryInfo.szTimeSeparator, Seconds ) ;
  463.    else
  464.       sprintf ( Text+strlen(Text), "%lu%s%02lu",
  465.          Hours, CountryInfo.szTimeSeparator, Minutes ) ;
  466.  
  467.    DdeUpdate ( Text ) ;
  468. }
  469.  
  470. void ElapsedTime::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  471.    ULONG Time = NewValue ( ) ;
  472.    if ( Mandatory || ( Time != Value ) ) {
  473.       char Label[100], Text[100] ;
  474.       FormatText ( Label, Text, Time ) ;
  475.       Paint ( hPS, Rectangle, Label, Text, Time ) ;
  476.    } /* endif */
  477. }
  478.  
  479.  
  480. MemoryFree::MemoryFree ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  481.    Dde_Server *pDdeServer, char *Topic, COUNTRYINFO &countryinfo, USHORT sk, USHORT stk, USHORT sm ) 
  482.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ), 
  483.    ShowK(sk), ShowTrueK(stk), ShowM(sm) {
  484.    CountryInfo = countryinfo ;
  485.    LevelSense = -1 ;
  486.    MinLevel = 0 ;
  487.    ULONG TotalPhysicalMemory ;
  488.    DosQuerySysInfo ( QSV_TOTPHYSMEM, QSV_TOTPHYSMEM, &TotalPhysicalMemory, sizeof(TotalPhysicalMemory) ) ;
  489.    MaxLevel = TotalPhysicalMemory ;
  490.    DefaultLevels [0] = WarningLevel = TotalPhysicalMemory / 8 ;
  491.    DefaultLevels [1] = ErrorLevel = TotalPhysicalMemory / 16 ;
  492. } /* endmethod */
  493.  
  494. int MemoryFree::Measure ( HPS hPS, RECTL &Rectangle ) {
  495.    char Text [100] ;
  496.    int Result = MeasureValue ( Text, QueryCurrentLabel(), ShowK, ShowM ) ;
  497.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  498.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  499.    return ( Result ) ;
  500. }
  501.  
  502. ULONG MemoryFree::NewValue ( void ) {
  503.    APIRET16 APIENTRY16 Dos16MemAvail ( PULONG pulAvailMem ) ;
  504.    ULONG Value ;
  505.    Dos16MemAvail ( &Value ) ;
  506.    return ( Value ) ;
  507. }
  508.  
  509. void MemoryFree::FormatText ( char *Label, char *Text, ULONG Value ) {
  510.    strcpy ( Label, CurrentLabel ) ;
  511.    FormatValue ( Value, Text, CountryInfo, ShowK, ShowTrueK, ShowM ) ;
  512.    DdeUpdate ( Text ) ;
  513. }
  514.  
  515. void MemoryFree::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  516.    ULONG Size = NewValue ( ) ;
  517.    if ( Mandatory || ( Size != Value ) ) {
  518.       char Label[100], Text [100] ;
  519.       FormatText ( Label, Text, Size ) ;
  520.       Paint ( hPS, Rectangle, Label, Text, Size ) ;
  521.    } /* endif */
  522. }
  523.  
  524.  
  525. VirtualFree::VirtualFree ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  526.    Dde_Server *pDdeServer, char *Topic, COUNTRYINFO &countryinfo, USHORT sk, USHORT stk, USHORT sm ) 
  527.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ), 
  528.    ShowK(sk), ShowTrueK(stk), ShowM(sm) {
  529.    CountryInfo = countryinfo ;
  530.    LevelSense = -1 ;
  531.    MinLevel = 0 ;
  532.    MaxLevel = 64*1024*1024 ;
  533.    DefaultLevels [0] = WarningLevel = 8*1024*1024 ;
  534.    DefaultLevels [1] = ErrorLevel = 4*1024*1024 ;
  535. } /* endmethod */
  536.  
  537. int VirtualFree::Measure ( HPS hPS, RECTL &Rectangle ) {
  538.    char Text [100] ;
  539.    int Result = MeasureValue ( Text, QueryCurrentLabel(), ShowK, ShowM ) ;
  540.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  541.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  542.    return ( Result ) ;
  543. }
  544.  
  545. ULONG VirtualFree::NewValue ( void ) {
  546.    ULONG Space ;
  547.    DosQuerySysInfo ( QSV_TOTAVAILMEM, QSV_TOTAVAILMEM, &Space, sizeof(Space) ) ;
  548.    return ( Space ) ;
  549. }
  550.  
  551. void VirtualFree::FormatText ( char *Label, char *Text, ULONG Value ) {
  552.    strcpy ( Label, CurrentLabel ) ;
  553.    FormatValue ( Value, Text, CountryInfo, ShowK, ShowTrueK, ShowM ) ;
  554.    DdeUpdate ( Text ) ;
  555. }
  556.  
  557. void VirtualFree::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  558.    ULONG Size = NewValue ( ) ;
  559.    if ( Mandatory || ( Size != Value ) ) {
  560.       char Label[100], Text [100] ;
  561.       FormatText ( Label, Text, Size ) ;
  562.       Paint ( hPS, Rectangle, Label, Text, Size ) ;
  563.    } /* endif */
  564. }
  565.  
  566.  
  567. SwapSize::SwapSize ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  568.    Dde_Server *pDdeServer, char *Topic, COUNTRYINFO countryinfo, 
  569.    USHORT sk, USHORT stk, USHORT sm, PSZ swappath, ULONG initialsize )
  570.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ), 
  571.    ShowK(sk), ShowTrueK(stk), ShowM(sm) {
  572.    CountryInfo = countryinfo ;
  573.    SwapPath = new BYTE [ strlen(PCHAR(swappath)) + 1 ] ;
  574.    strcpy ( PCHAR(SwapPath), PCHAR(swappath) ) ;
  575.    LevelSense = +1 ;
  576.    MinLevel = 0 ;
  577.    MaxLevel = 64*1024*1024 ;
  578.    DefaultLevels [0] = WarningLevel = initialsize > 0x2000 ? initialsize * 2 * 1024 : 16 * 1024 * 1024 ;
  579.    DefaultLevels [1] = ErrorLevel = initialsize > 0x2000 ? initialsize * 2 * 1024 : 32 * 1024 * 1024 ;
  580. } /* endmethod */
  581.  
  582. SwapSize::~SwapSize ( void ) {
  583.    delete [] SwapPath ;
  584. } /* endmethod */
  585.  
  586. int SwapSize::Measure ( HPS hPS, RECTL &Rectangle ) {
  587.    char Text [100] ;
  588.    int Result = MeasureValue ( Text, QueryCurrentLabel(), ShowK, ShowM ) ;
  589.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  590.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  591.    return ( Result ) ;
  592. }
  593.  
  594. ULONG SwapSize::NewValue ( void ) {
  595.  
  596.    char Path [_MAX_PATH+1] ;
  597.    strcpy ( Path, (PCHAR)SwapPath ) ;
  598.  
  599.    if ( Path[strlen(Path)-1] != '\\' )
  600.       strcat ( Path, "\\" ) ;
  601.  
  602.    strcat ( Path, "SWAPPER.DAT" ) ;
  603.  
  604.    ULONG SwapSize = 0 ;
  605.    FILESTATUS3 Status ;
  606.    if ( DosQueryPathInfo ( (PSZ)Path, FIL_STANDARD, &Status, sizeof(Status) ) == 0 ) 
  607.       SwapSize = Status.cbFile ;
  608.  
  609.    return ( SwapSize ) ;
  610. }
  611.  
  612. void SwapSize::FormatText ( char *Label, char *Text, ULONG Value ) {
  613.    strcpy ( Label, CurrentLabel ) ;
  614.    FormatValue ( Value, Text, CountryInfo, ShowK, ShowTrueK, ShowM ) ;
  615.    DdeUpdate ( Text ) ;
  616. }
  617.  
  618. void SwapSize::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  619.    ULONG Size = NewValue ( ) ;
  620.    if ( Mandatory || ( Size != Value ) ) {
  621.       char Label[100], Text [100] ;
  622.       FormatText ( Label, Text, Size ) ;
  623.       Paint ( hPS, Rectangle, Label, Text, Size ) ;
  624.    } /* endif */
  625. }
  626.  
  627.  
  628. SwapFree::SwapFree ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  629.    Dde_Server *pDdeServer, char *Topic, COUNTRYINFO &countryinfo,
  630.    USHORT sk, USHORT stk, USHORT sm, PSZ swappath, ULONG minfree )
  631.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ),
  632.    ShowK(sk), ShowTrueK(stk), ShowM(sm), MinFree(minfree) {
  633.    CountryInfo = countryinfo ;
  634.    SwapPath = new BYTE [ strlen(PCHAR(swappath)) + 1 ] ;
  635.    strcpy ( PCHAR(SwapPath), PCHAR(swappath) ) ;
  636.    LevelSense = -1 ;
  637.    MinLevel = 0 ;
  638.    MaxLevel = 64*1024*1024 ;
  639.    DefaultLevels [0] = WarningLevel = 8*1024*1024 ;
  640.    DefaultLevels [1] = ErrorLevel = 4*1024*1024 ;
  641. } /* endmethod */
  642.  
  643. SwapFree::~SwapFree ( void ) {
  644.    delete [] SwapPath ;
  645. } /* endmethod */
  646.  
  647. int SwapFree::Measure ( HPS hPS, RECTL &Rectangle ) {
  648.    char Text [100] ;
  649.    int Result = MeasureValue ( Text, QueryCurrentLabel(), ShowK, ShowM ) ;
  650.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  651.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  652.    return ( Result ) ;
  653. }
  654.  
  655. ULONG SwapFree::NewValue ( void ) {
  656.  
  657.    DosError ( FERR_DISABLEHARDERR ) ;
  658.    FSALLOCATE Allocation ;
  659.    DosQueryFSInfo ( SwapPath[0]-'A'+1, FSIL_ALLOC, PBYTE(&Allocation), sizeof(Allocation) ) ;
  660.    DosError ( FERR_ENABLEHARDERR ) ;
  661.  
  662.    ULONG SwapFree = Allocation.cUnitAvail*Allocation.cSectorUnit*Allocation.cbSector ;
  663.  
  664.    SwapFree -= MinFree * 1024 ;                 // The swap-file will not allocate the space required free.
  665.  
  666.    SwapFree -= ( SwapFree % ( 1024 * 1024 ) ) ; // The swap-file only expands by 1M increments.
  667.  
  668.    return ( SwapFree ) ;
  669. }
  670.  
  671. void SwapFree::FormatText ( char *Label, char *Text, ULONG Value ) {
  672.    strcpy ( Label, CurrentLabel ) ;
  673.    FormatValue ( Value, Text, CountryInfo, ShowK, ShowTrueK, ShowM ) ;
  674.    DdeUpdate ( Text ) ;
  675. }
  676.  
  677. void SwapFree::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  678.    ULONG Size = NewValue ( ) ;
  679.    if ( Mandatory || ( Size != Value ) ) {
  680.       char Label[100], Text [100] ;
  681.       FormatText ( Label, Text, Size ) ;
  682.       Paint ( hPS, Rectangle, Label, Text, Size ) ;
  683.    } /* endif */
  684. }
  685.  
  686.  
  687. SpoolSize::SpoolSize ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  688.    Dde_Server *pDdeServer, char *Topic, COUNTRYINFO &countryinfo, 
  689.    USHORT sk, USHORT stk, USHORT sm, PSZ spoolpath )
  690.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ), 
  691.    ShowK(sk), ShowTrueK(stk), ShowM(sm) {
  692.    CountryInfo = countryinfo ;
  693.    SpoolPath = new BYTE [ strlen(PCHAR(spoolpath)) + 1 ] ;
  694.    strcpy ( PCHAR(SpoolPath), PCHAR(spoolpath) ) ;
  695.    LevelSense = +1 ;
  696.    MinLevel = 0 ;
  697.    MaxLevel = 64*1024*1024 ;
  698.    DefaultLevels [0] = WarningLevel = 8*1024*1024 ;
  699.    DefaultLevels [1] = ErrorLevel = 16*1024*1024 ;
  700. } /* endmethod */
  701.  
  702. SpoolSize::~SpoolSize ( void ) {
  703.    delete [] SpoolPath ;
  704. } /* endmethod */
  705.  
  706. int SpoolSize::Measure ( HPS hPS, RECTL &Rectangle ) {
  707.    char Text [100] ;
  708.    int Result = MeasureValue ( Text, QueryCurrentLabel(), ShowK, ShowM ) ;
  709.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  710.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  711.    return ( Result ) ;
  712. }
  713.  
  714. ULONG SpoolSize::NewValue ( void ) {
  715.  
  716.    ULONG PathSize ;
  717.    DosQuerySysInfo ( QSV_MAX_PATH_LENGTH, QSV_MAX_PATH_LENGTH, &PathSize, sizeof(PathSize) ) ;
  718.  
  719.    PBYTE Path = PBYTE ( malloc ( size_t(PathSize) ) ) ;
  720.    if ( Path == NULL ) 
  721.       return ( 0 ) ;
  722.  
  723.    PFILEFINDBUF3 Found = PFILEFINDBUF3 ( malloc ( size_t( PathSize + sizeof(FILEFINDBUF3) ) ) ) ;
  724.    if ( Found == NULL ) {
  725.       free ( Path ) ;
  726.       return ( 0 ) ;
  727.    } /* endif */
  728.  
  729.    strcpy ( (PCHAR)Path, (PCHAR)SpoolPath ) ;
  730.    strcat ( (PCHAR)Path, "\\*.*" ) ;
  731.  
  732.    HDIR hDir = (HDIR) HDIR_CREATE ;
  733.    ULONG Count = 1 ;
  734.    ULONG TotalSize = 0 ;
  735.  
  736.    if ( !DosFindFirst2 ( Path, &hDir,
  737.       FILE_NORMAL | FILE_READONLY | FILE_DIRECTORY | FILE_ARCHIVED,
  738.       Found, PathSize+sizeof(FILEFINDBUF3), &Count, FIL_STANDARD ) ) {
  739.  
  740.       do {
  741.  
  742.          if ( !strcmp ( (PCHAR)Found->achName, "." ) OR !strcmp ( (PCHAR)Found->achName, ".." ) )
  743.             continue ;
  744.  
  745.          if ( Found->attrFile & FILE_DIRECTORY ) {
  746.  
  747.             HDIR hDir2 = (HDIR) HDIR_CREATE ;
  748.  
  749.             strcpy ( (PCHAR)Path, (PCHAR)SpoolPath ) ;
  750.             strcat ( (PCHAR)Path, "\\" ) ;
  751.             strcat ( (PCHAR)Path, (PCHAR)Found->achName ) ;
  752.             strcat ( (PCHAR)Path, "\\*.*" ) ;
  753.  
  754.             ULONG Count2 = 1 ;
  755.             if ( !DosFindFirst2 ( Path, &hDir2,
  756.                FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED,
  757.                Found, PathSize+sizeof(FILEFINDBUF3), &Count2, FIL_STANDARD ) ) {
  758.                do {
  759.                   TotalSize += Found->cbFile ;
  760.                } while ( !DosFindNext ( hDir2, Found, PathSize+sizeof(FILEFINDBUF3), &Count2 ) ) ;
  761.                DosFindClose ( hDir2 ) ;
  762.             } /* endif */
  763.          } else {
  764.             TotalSize += Found->cbFile ;
  765.          } /* endif */
  766.       } while ( !DosFindNext ( hDir, Found, PathSize+sizeof(FILEFINDBUF3), &Count ) ) ;
  767.  
  768.       DosFindClose ( hDir ) ;
  769.  
  770.    } /* enddo */
  771.  
  772.    free ( Path ) ;
  773.    free ( Found ) ;
  774.  
  775.    return ( TotalSize ) ;
  776. }
  777.  
  778. void SpoolSize::FormatText ( char *Label, char *Text, ULONG Value ) {
  779.    strcpy ( Label, CurrentLabel ) ;
  780.    FormatValue ( Value, Text, CountryInfo, ShowK, ShowTrueK, ShowM ) ;
  781.    DdeUpdate ( Text ) ;
  782. }
  783.  
  784. void SpoolSize::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  785.    ULONG Size = NewValue ( ) ;
  786.    if ( Mandatory || ( Size != Value ) ) {
  787.       char Label[100], Text [100] ;
  788.       FormatText ( Label, Text, Size ) ;
  789.       Paint ( hPS, Rectangle, Label, Text, Size ) ;
  790.    } /* endif */
  791. }
  792.  
  793.  
  794. CpuLoad::CpuLoad ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  795.    Dde_Server *pDdeServer, char *Topic, ULONG maxcount, PULONG idlecount, ResourceString *error )
  796.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ), 
  797.    MaxCount(maxcount), IdleCount(idlecount), Error(error) { 
  798.    LevelSense = +1 ;
  799.    MinLevel = 0 ;
  800.    MaxLevel = 100 ;
  801.    DefaultLevels [0] = WarningLevel = 75 ;
  802.    DefaultLevels [1] = ErrorLevel = 90 ;
  803. } /* endmethod */
  804.  
  805. int CpuLoad::Measure ( HPS hPS, RECTL &Rectangle ) {
  806.    int Result ;
  807.    char Text [100] ;
  808.    Result = sprintf ( Text, "%s 100%", QueryCurrentLabel() ) ;
  809.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  810.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  811.    return ( Result ) ;
  812. }
  813.  
  814. ULONG CpuLoad::NewValue ( void ) {
  815.    if ( *IdleCount == 0xFFFFFFFF ) 
  816.       return ( 0xFFFFFFFF ) ;
  817.    MaxCount = (ULONG) max ( MaxCount, *IdleCount ) ;
  818.    ULONG Load = ( ( MaxCount - *IdleCount ) * 100 ) / MaxCount ;
  819.    return ( Load ) ;
  820. }
  821.  
  822. void CpuLoad::FormatText ( char *Label, char *Text, ULONG Value ) {
  823.    if ( Value == 0xFFFFFFFF ) {
  824.       strcpy ( Text, PCHAR(*Error) ) ;
  825.    } else {
  826.       strcpy ( Label, CurrentLabel ) ;
  827.       sprintf ( Text, "%lu%%", Value ) ;
  828.    } /* endif */
  829.    DdeUpdate ( Text ) ;
  830. }
  831.  
  832. void CpuLoad::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  833.    ULONG Load = NewValue ( ) ;
  834.    if ( Mandatory || ( Load != Value ) ) {
  835.       char Label[100], Text [100] ;
  836.       FormatText ( Label, Text, Load ) ;
  837.       Paint ( hPS, Rectangle, Label, Text, Load ) ;
  838.    } /* endif */
  839. }
  840.  
  841.  
  842. TaskCount::TaskCount ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  843.    Dde_Server *pDdeServer, char *Topic, HAB anchor )
  844.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ), 
  845.    Anchor(anchor) { 
  846.    LevelSense = +1 ;
  847.    MinLevel = 0 ;
  848.    MaxLevel = 256 ;     
  849.    DefaultLevels [0] = WarningLevel = 30 ;  
  850.    DefaultLevels [1] = ErrorLevel = 40 ;    
  851. } /* endmethod */
  852.  
  853. int TaskCount::Measure ( HPS hPS, RECTL &Rectangle ) {
  854.    int Result ;
  855.    char Text [100] ;
  856.    Result = sprintf ( Text, "%s 999 ", QueryCurrentLabel() ) ;
  857.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  858.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  859.    return ( Result ) ;
  860. }
  861.  
  862. ULONG TaskCount::NewValue ( void ) {
  863.    return ( WinQuerySwitchList ( Anchor, PSWBLOCK(NULL), 0 ) ) ;
  864. }
  865.  
  866. void TaskCount::FormatText ( char *Label, char *Text, ULONG Value ) {
  867.    strcpy ( Label, CurrentLabel ) ;
  868.    sprintf ( Text, "%lu ", Value ) ;
  869.    DdeUpdate ( Text ) ;
  870. }
  871.  
  872. void TaskCount::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  873.    ULONG Count = NewValue ( ) ;
  874.    if ( Mandatory || ( Count != Value ) ) {
  875.       char Label[100], Text [100] ;
  876.       FormatText ( Label, Text, Count ) ;
  877.       Paint ( hPS, Rectangle, Label, Text, Count ) ;
  878.    } /* endif */
  879. }
  880.  
  881.  
  882. DriveFree::DriveFree ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  883.    Dde_Server *pDdeServer, char *Topic, COUNTRYINFO &countryinfo, 
  884.    USHORT sk, USHORT stk, USHORT sm, USHORT drivenumber, ResourceString *driveerror, BOOL showfilesystemname, 
  885.    PSZ filesystem, BOOL showdisklabel, PSZ disklabel ) 
  886.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ), 
  887.    ShowK(sk), ShowTrueK(stk), ShowM(sm), DriveError(driveerror), DriveNumber(drivenumber),
  888.    ShowFileSystemName(showfilesystemname), ShowDiskLabel(showdisklabel), 
  889.    Error(FALSE) {
  890.    CountryInfo = countryinfo ;
  891.    strcpy ( PCHAR(FileSystem), PCHAR(filesystem) ) ;
  892.    strcpy ( PCHAR(DiskLabel), PCHAR(disklabel) ) ;
  893.    LevelSense = -1 ;
  894.    MinLevel = 0 ;
  895.    DosError ( FERR_DISABLEHARDERR ) ;
  896.    FSALLOCATE Allocation ;
  897.    DosQueryFSInfo ( DriveNumber, FSIL_ALLOC, (PBYTE)&Allocation, sizeof(Allocation) ) ;
  898.    DosError ( FERR_ENABLEHARDERR ) ;
  899.    MaxLevel = Allocation.cUnit*Allocation.cSectorUnit*Allocation.cbSector ;
  900.    DefaultLevels [0] = WarningLevel = MaxLevel / 5 ;
  901.    DefaultLevels [1] = ErrorLevel = MaxLevel / 10 ;
  902. } /* endmethod */
  903.  
  904. int DriveFree::Measure ( HPS hPS, RECTL &Rectangle ) {
  905.    char Label[100] ;
  906.    if ( ShowFileSystemName && *FileSystem ) {
  907.       if ( ShowDiskLabel && *DiskLabel ) {
  908.          sprintf ( Label, "%s (%s,%s)", QueryCurrentLabel(), DiskLabel, FileSystem ) ;
  909.       } else {
  910.          sprintf ( Label, "%s (%s)", QueryCurrentLabel(), FileSystem ) ;
  911.       } /* endif */
  912.    } else {
  913.       if ( ShowDiskLabel && *DiskLabel ) {
  914.          sprintf ( Label, "%s (%s)", QueryCurrentLabel(), DiskLabel ) ;
  915.       } else {
  916.          sprintf ( Label, "%s", QueryCurrentLabel() ) ;
  917.       } /* endif */
  918.    } /* endif */
  919.    char Text[100] ;
  920.    int Result = MeasureValue ( Text, Label, ShowK, ShowM ) ;
  921.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  922.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  923.    return ( Result ) ;
  924. }
  925.  
  926. ULONG DriveFree::NewValue ( void ) {
  927.  
  928.    if ( Error ) 
  929.       return ( 0 ) ;
  930.  
  931.    DosError ( FERR_DISABLEHARDERR ) ;
  932.  
  933.    FSALLOCATE Allocation ;
  934.    APIRET Status = DosQueryFSInfo ( DriveNumber, FSIL_ALLOC, (PBYTE)&Allocation, sizeof(Allocation) ) ;
  935.  
  936.    DosError ( FERR_ENABLEHARDERR ) ;
  937.  
  938.    if ( Status ) {
  939.       Error = TRUE ;
  940.       return ( 0 ) ;
  941.    } /* endif */
  942.  
  943.    return ( Allocation.cUnitAvail*Allocation.cSectorUnit*Allocation.cbSector ) ;
  944. }
  945.  
  946. void DriveFree::FormatText ( char *Label, char *Text, ULONG Value ) {
  947.  
  948.    if ( ShowFileSystemName && *FileSystem ) {
  949.       if ( ShowDiskLabel && *DiskLabel ) {
  950.          sprintf ( Label, "%s (%s,%s)", QueryCurrentLabel(), DiskLabel, FileSystem ) ;
  951.       } else {
  952.          sprintf ( Label, "%s (%s)", QueryCurrentLabel(), FileSystem ) ;
  953.       } /* endif */
  954.    } else {
  955.       if ( ShowDiskLabel && *DiskLabel ) {
  956.          sprintf ( Label, "%s (%s)", QueryCurrentLabel(), DiskLabel ) ;
  957.       } else {
  958.          sprintf ( Label, "%s", QueryCurrentLabel() ) ;
  959.       } /* endif */
  960.    } /* endif */
  961.  
  962.    if ( Error )
  963.       strcpy ( Text, PCHAR(*DriveError) ) ;
  964.    else
  965.       FormatValue ( Value, Text, CountryInfo, ShowK, ShowTrueK, ShowM ) ;
  966.  
  967.    DdeUpdate ( Text ) ;
  968. }
  969.  
  970. void DriveFree::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  971.    ULONG Size = NewValue ( ) ;
  972.    if ( Mandatory || ( Size != Value ) ) {
  973.       char Label[100], Text [100] ;
  974.       FormatText ( Label, Text, Size ) ;
  975.       Paint ( hPS, Rectangle, Label, Text, Size ) ;
  976.    } /* endif */
  977. }
  978.  
  979.  
  980. TotalFree::TotalFree ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  981.    Dde_Server *pDdeServer, char *Topic, COUNTRYINFO &countryinfo, 
  982.    USHORT sk, USHORT stk, USHORT sm, ULONG drives )
  983.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ), 
  984.    ShowK(sk), ShowTrueK(stk), ShowM(sm), Drives(drives) {
  985.    CountryInfo = countryinfo ;
  986.    LevelSense = -1 ;
  987.    MinLevel = 0 ;
  988.    MaxLevel = 64*1024*1024 ;    
  989.    DefaultLevels [0] = WarningLevel = 8*1024*1024 ;
  990.    DefaultLevels [1] = ErrorLevel = 4*1024*1024 ;
  991. } /* endmethod */
  992.  
  993. int TotalFree::Measure ( HPS hPS, RECTL &Rectangle ) {
  994.    char Text [100] ;
  995.    int Result = MeasureValue ( Text, QueryCurrentLabel(), ShowK, ShowM ) ;
  996.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  997.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  998.    return ( Result ) ;
  999. }
  1000.  
  1001. ULONG TotalFree::NewValue ( void ) {
  1002.  
  1003.    ULONG Free = 0 ;
  1004.    ULONG Mask = Drives >> 2 ;
  1005.  
  1006.    for ( int Drive=3; Drive<=26; Drive++ ) {
  1007.       if ( Mask & 1 ) {
  1008.  
  1009.          DosError ( FERR_DISABLEHARDERR ) ;
  1010.  
  1011.          FSALLOCATE Allocation ;
  1012.          APIRET Status = DosQueryFSInfo ( Drive, FSIL_ALLOC, (PBYTE)&Allocation, sizeof(Allocation) ) ;
  1013.  
  1014.          DosError ( FERR_ENABLEHARDERR ) ;
  1015.  
  1016.          if ( Status )
  1017.             Drives &= ~ ( 1 << (Drive-1) ) ;
  1018.          else
  1019.             Free += Allocation.cUnitAvail*Allocation.cSectorUnit*(Allocation.cbSector/256) ;
  1020.       } /* endif */
  1021.       Mask >>= 1 ;
  1022.  
  1023.    } /* endfor */
  1024.  
  1025.    return ( Free ) ;
  1026. }
  1027.  
  1028. void TotalFree::FormatText ( char *Label, char *Text, ULONG Value ) {
  1029.    strcpy ( Label, CurrentLabel ) ;
  1030.    FormatValue ( Value, Text, CountryInfo, ShowK, ShowTrueK, ShowM, 256 ) ;
  1031.    DdeUpdate ( Text ) ;
  1032. }
  1033.  
  1034. void TotalFree::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  1035.    ULONG Size = NewValue ( ) ;
  1036.    if ( Mandatory || ( Size != Value ) ) {
  1037.       char Label[100], Text [100] ;
  1038.       FormatText ( Label, Text, Size ) ;
  1039.       Paint ( hPS, Rectangle, Label, Text, Size, 256 ) ;
  1040.    } /* endif */
  1041. }
  1042.  
  1043.  
  1044. SwapSlack::SwapSlack ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel, 
  1045.    Dde_Server *pDdeServer, char *Topic, COUNTRYINFO &countryinfo, 
  1046.    USHORT sk, USHORT stk, USHORT sm, VirtualFree *pvf, SwapFree *psf, MemoryFree *pmf ) 
  1047.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ), 
  1048.    ShowK(sk), ShowTrueK(stk), ShowM(sm), pVirtualFree(pvf), pSwapFree(psf), pMemFree(pmf) {
  1049.    CountryInfo = countryinfo ;
  1050. } /* endmethod */
  1051.  
  1052. int SwapSlack::Measure ( HPS hPS, RECTL &Rectangle ) {
  1053.    char Text [100] ;
  1054.    int Result = MeasureValue ( Text, QueryCurrentLabel(), ShowK, ShowM ) ;
  1055.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  1056.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  1057.    return ( Result ) ;
  1058. }
  1059.  
  1060. ULONG SwapSlack::NewValue ( void ) {
  1061.    LONG Slack = pVirtualFree->QueryFlag() ? pVirtualFree->QueryValue() : pVirtualFree->NewValue() ;
  1062.    Slack -= pSwapFree->QueryFlag() ? pSwapFree->QueryValue() : pSwapFree->NewValue() ;
  1063.    Slack -= pMemFree->QueryFlag() ? pMemFree->QueryValue() : pMemFree->NewValue() ;
  1064.    return ( ULONG ( max ( 0, Slack ) ) ) ;
  1065. }
  1066.  
  1067. void SwapSlack::FormatText ( char *Label, char *Text, ULONG Value ) {
  1068.    strcpy ( Label, CurrentLabel ) ;
  1069.    FormatValue ( Value, Text, CountryInfo, ShowK, ShowTrueK, ShowM ) ;
  1070.    DdeUpdate ( Text ) ;
  1071. }
  1072.  
  1073. void SwapSlack::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  1074.    ULONG Size = NewValue ( ) ;
  1075.    if ( Mandatory || ( Size != Value ) ) {
  1076.       char Label[100], Text[100] ;
  1077.       FormatText ( Label, Text, Size ) ;
  1078.       Paint ( hPS, Rectangle, Label, Text, Size ) ;
  1079.    } /* endif */
  1080. } /* endmethod */
  1081.  
  1082.  
  1083. ProcessCount::ProcessCount ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel,
  1084.    Dde_Server *pDdeServer, char *Topic )
  1085.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ) { 
  1086.    DosAllocMem ( (PPVOID)&DQPS_Buffer, 0x10000, PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_TILE ) ;
  1087.    LevelSense = +1 ;
  1088.    MinLevel = 0 ;
  1089.    MaxLevel = 256 ;    
  1090.    DefaultLevels [0] = WarningLevel = 30 ; 
  1091.    DefaultLevels [1] = ErrorLevel = 40 ;   
  1092. } /* endmethod */
  1093.  
  1094. ProcessCount::~ProcessCount ( ) { 
  1095.    DosFreeMem ( DQPS_Buffer ) ; 
  1096. } /* endmethod */
  1097.  
  1098. int ProcessCount::Measure ( HPS hPS, RECTL &Rectangle ) {
  1099.    int Result ;
  1100.    char Text [100] ;
  1101.    Result = sprintf ( Text, "%s 123 ", QueryCurrentLabel() ) ;
  1102.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  1103.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  1104.    return ( Result ) ;
  1105. } /* endmethod */
  1106.  
  1107. ULONG ProcessCount::NewValue ( void ) {
  1108.  
  1109.    if ( DosQProcStatus ( DQPS_Buffer, 0xFFFF ) ) 
  1110.       return ( 0 ) ;
  1111.  
  1112.    qsPrec_s *pProcRecord = ((qsPtrRec_s*)DQPS_Buffer)->pProcRec ;
  1113.    int ProcessCount = 0 ;
  1114.    while ( pProcRecord->RecType == 1 ) {
  1115.       int Size = sizeof(qsPrec_s) ;
  1116.       Size += pProcRecord->cTCB * sizeof(qsTrec_s) ;
  1117.       Size += pProcRecord->c16Sem * sizeof(short) ;
  1118.       Size += pProcRecord->cLib * sizeof(short) ;
  1119.       Size += pProcRecord->cShrMem * sizeof(short) ;
  1120.       pProcRecord = (qsPrec_s*) ( (char*)pProcRecord + Size ) ;
  1121.       ProcessCount ++ ;
  1122.    } /* endwhile */
  1123.    return ( ProcessCount ) ;
  1124. } /* endmethod */
  1125.  
  1126. void ProcessCount::FormatText ( char *Label, char *Text, ULONG Value ) {
  1127.    strcpy ( Label, CurrentLabel ) ;
  1128.    sprintf ( Text, "%lu ", Value ) ;
  1129.    DdeUpdate ( Text ) ;
  1130. } /* endmethod */
  1131.  
  1132. void ProcessCount::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  1133.    ULONG Count = NewValue ( ) ;
  1134.    if ( Mandatory || ( Count != Value ) ) {
  1135.       char Label[100], Text[100] ;
  1136.       FormatText ( Label, Text, Count ) ;
  1137.       Paint ( hPS, Rectangle, Label, Text, Count ) ;
  1138.    } /* endif */
  1139. } /* endmethod */
  1140.  
  1141.  
  1142. ThreadCount::ThreadCount ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel,
  1143.    Dde_Server *pDdeServer, char *Topic )
  1144.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ) { 
  1145.    DosAllocMem ( (PPVOID)&DQPS_Buffer, 0x10000, PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_TILE ) ;
  1146.    LevelSense = +1 ;
  1147.    MinLevel = 0 ;
  1148.    PSZ Threads = ScanSystemConfig ( 0, "THREADS" ) ;
  1149.    if ( Threads == 0 ) 
  1150.       Threads = (PSZ) "64" ;
  1151.    int MaxThreads = atoi ( Threads ) ;
  1152.    MaxLevel = MaxThreads ;
  1153.    DefaultLevels [0] = WarningLevel = ( MaxThreads * 3 ) / 4 ; 
  1154.    DefaultLevels [1] = ErrorLevel = ( MaxThreads * 9 ) / 10 ;   
  1155. } /* endmethod */
  1156.  
  1157. ThreadCount::~ThreadCount ( ) { 
  1158.    DosFreeMem ( DQPS_Buffer ) ; 
  1159. } /* endmethod */
  1160.  
  1161. int ThreadCount::Measure ( HPS hPS, RECTL &Rectangle ) {
  1162.    int Result ;
  1163.    char Text [100] ;
  1164.    Result = sprintf ( Text, "%s 123 ", QueryCurrentLabel() ) ;
  1165.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  1166.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  1167.    return ( Result ) ;
  1168. } /* endmethod */
  1169.  
  1170. ULONG ThreadCount::NewValue ( void ) {
  1171.  
  1172.    if ( DosQProcStatus ( DQPS_Buffer, 0xFFFF ) )
  1173.       return ( 0 ) ;
  1174.  
  1175.    return ( ((qsPtrRec_s*)DQPS_Buffer)->pGlobalRec->cThrds ) ;
  1176. } /* endmethod */
  1177.  
  1178. void ThreadCount::FormatText ( char *Label, char *Text, ULONG Value ) {
  1179.    strcpy ( Label, CurrentLabel ) ;
  1180.    sprintf ( Text, "%lu ", Value ) ;
  1181.    DdeUpdate ( Text ) ;
  1182. } /* endmethod */
  1183.  
  1184. void ThreadCount::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  1185.    ULONG Count = NewValue ( ) ;
  1186.    if ( Mandatory || ( Count != Value ) ) {
  1187.       char Label[100], Text[100] ;
  1188.       FormatText ( Label, Text, Count ) ;
  1189.       Paint ( hPS, Rectangle, Label, Text, Count ) ;
  1190.    } /* endif */
  1191. } /* endmethod */
  1192.  
  1193.  
  1194. Battery::Battery ( USHORT id, char *pName, char *pCurrentLabel, char *pDefaultLabel,
  1195.    Dde_Server *pDdeServer, char *Topic, ResourceString *error, ResourceString *charging, ResourceString *ac )
  1196.    : Item ( id, pName, pCurrentLabel, pDefaultLabel, pDdeServer, Topic ), 
  1197.    Handle(-1), Error(error), Charging(charging), AC(ac) { 
  1198.    LevelSense = -1 ;
  1199.    MinLevel = 0 ;
  1200.    MaxLevel = 100 ;
  1201.    DefaultLevels [0] = WarningLevel = 25 ; 
  1202.    DefaultLevels [1] = ErrorLevel = 10 ;   
  1203.    ULONG Action = 0;
  1204.    APIRET Status = DosOpen ( (PSZ) "APM$", &Handle, &Action, 0, FILE_NORMAL,
  1205.          FILE_OPEN, OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE | OPEN_FLAGS_FAIL_ON_ERROR, 0 ) ;
  1206.    if ( Status ) 
  1207.       Handle = 0xFFFFFFFF ;
  1208. } /* endmethod */
  1209.  
  1210. Battery::~Battery ( ) {
  1211.    if ( Handle != 0xFFFFFFFF ) 
  1212.       DosClose ( Handle ) ;
  1213. } /* endmethod */
  1214.  
  1215. int Battery::Measure ( HPS hPS, RECTL &Rectangle ) {
  1216.    int Result ;
  1217.    char Text [100] ;
  1218.    Result = sprintf ( Text, "%s %s ", QueryCurrentLabel(), PCHAR(*Charging) ) ;
  1219.    WinQueryWindowRect ( HWND_DESKTOP, &Rectangle ) ;
  1220.    WinDrawText ( hPS, strlen(Text), PSZ(Text), &Rectangle, 0, 0, DT_LEFT | DT_BOTTOM | DT_QUERYEXTENT ) ;
  1221.    return ( Result ) ;
  1222. } /* endmethod */
  1223.  
  1224. ULONG Battery::NewValue ( void ) {
  1225.  
  1226.    if ( Handle != 0xFFFFFFFF ) 
  1227.       return ( -1 ) ;
  1228.  
  1229.    struct {
  1230.       USHORT ParmLength ;
  1231.       USHORT PowerFlags ;
  1232.       UCHAR  ACStatus ;
  1233.       UCHAR  BatteryStatus ;
  1234.       UCHAR  BatteryLife ;
  1235.    } Parm ;
  1236.    Parm.ParmLength = sizeof(Parm) ;
  1237.    ULONG ParmLen = sizeof(Parm) ;
  1238.    USHORT Data ;
  1239.    ULONG DataLen = sizeof(Data) ;
  1240.    APIRET Status = DosDevIOCtl ( Handle, IOCTL_POWER, POWER_GETPOWERSTATUS, &Parm, sizeof(Parm), &ParmLen, &Data, sizeof(Data), &DataLen ) ;
  1241.    if ( Status ) {
  1242. //    Log ( "Unable to call APM$ for power status.  Status %i.", Status ) ;
  1243.       DosClose ( Handle ) ;
  1244.       Handle = 0xFFFFFFFF ;
  1245.       return ( -1 ) ;
  1246.    } else {
  1247.       if ( Parm.PowerFlags & 1 ) {                       // If APM enabled,
  1248.          if ( Parm.BatteryStatus == 3 ) {                //   If battery charging,
  1249.             if ( Parm.BatteryLife < 100 )                //     If not fully charged,
  1250.                return ( 101 ) ;                          //       Report CHARGING.
  1251.             else                                         //     Else
  1252.                return ( 100 ) ;                          //       Report 100%.
  1253.          } else if ( Parm.ACStatus == 1 ) {              //   Else if A/C,
  1254.             return ( 201 ) ;                             //     Report A/C.
  1255.          } else if ( Parm.BatteryLife <= 100 ) {         //   Else if not fully charged,
  1256.             return ( Parm.BatteryLife ) ;                //     Report percentage full.
  1257.          } else {                                        //   Else,
  1258.             return ( -1 ) ;                              //     Report error.
  1259.          } /* endif */                                   //
  1260.       } else {                                           // Else,
  1261.          return ( -1 ) ;                                 //   Report error.
  1262.       } /* endif */
  1263.    } /* endif */
  1264. } /* endmethod */
  1265.  
  1266. void Battery::FormatText ( char *Label, char *Text, ULONG Value ) {
  1267.    strcpy ( Label, CurrentLabel ) ;
  1268.    if ( (long)Value < 0 ) {
  1269.       strcpy ( Text, PCHAR(*Error) ) ;
  1270.       strcat ( Text, " " ) ;
  1271.    } else if ( Value > 200 ) {
  1272.       strcpy ( Text, PCHAR(*AC) ) ;
  1273.       strcat ( Text, " " ) ;
  1274.    } else if ( Value > 100 ) {
  1275.       strcpy ( Text, PCHAR(*Charging) ) ;
  1276.       strcat ( Text, " " ) ;
  1277.    } else { 
  1278.       sprintf ( Text, "%lu%%", Value ) ;
  1279.    } /* endif */
  1280.    DdeUpdate ( Text ) ;
  1281. } /* endmethod */
  1282.  
  1283. void Battery::Repaint ( HPS hPS, RECTL &Rectangle, BOOL Mandatory ) {
  1284.    ULONG Count = NewValue ( ) ;
  1285.    if ( Mandatory || ( Count != Value ) ) {
  1286.       char Label[100], Text[100] ;
  1287.       FormatText ( Label, Text, Count ) ;
  1288.       Paint ( hPS, Rectangle, Label, Text, Count ) ;
  1289.    } /* endif */
  1290. } /* endmethod */
  1291.  
  1292. int Battery::Discharging ( ) {
  1293.  
  1294.    if ( Handle != 0xFFFFFFFF ) 
  1295.       return ( FALSE ) ;
  1296.  
  1297.    struct {
  1298.       USHORT ParmLength ;
  1299.       USHORT PowerFlags ;
  1300.       UCHAR  ACStatus ;
  1301.       UCHAR  BatteryStatus ;
  1302.       UCHAR  BatteryLife ;
  1303.    } Parm ;
  1304.    Parm.ParmLength = sizeof(Parm) ;
  1305.    ULONG ParmLen = sizeof(Parm) ;
  1306.    USHORT Data ;
  1307.    ULONG DataLen = sizeof(Data) ;
  1308.    APIRET Status = DosDevIOCtl ( Handle, IOCTL_POWER, POWER_GETPOWERSTATUS, &Parm, sizeof(Parm), &ParmLen, &Data, sizeof(Data), &DataLen ) ;
  1309.    if ( Status ) {
  1310. //    Log ( "Unable to call APM$ for power status.  Status %i.", Status ) ;
  1311.       DosClose ( Handle ) ;
  1312.       Handle = 0xFFFFFFFF ;
  1313.    } else {
  1314.       if ( Parm.PowerFlags & 1 ) {
  1315.          if ( Parm.BatteryStatus == 3 ) {
  1316.             ;
  1317.          } else if ( Parm.ACStatus == 1 ) {     
  1318.             ;
  1319.          } else if ( Parm.BatteryLife <= 100 ) {
  1320.             return ( TRUE ) ;
  1321.          } /* endif */                          
  1322.       } /* endif */
  1323.    } /* endif */
  1324.  
  1325.    return ( FALSE ) ;
  1326. }
  1327.  
  1328.