home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: SysTools / SysTools.zip / sysba021.zip / SRC.ZIP / sysbar2 / sysbar2.cpp < prev    next >
C/C++ Source or Header  |  2003-01-03  |  19KB  |  632 lines

  1. /*
  2.  
  3.   SysBar/2 Utility Set  version 0.21
  4.  
  5.   SYSBAR2.DLL main module
  6.  
  7.   ..................................................................
  8.  
  9.   Copyright (c) 1995-1999  Dmitry I. Platonoff
  10.                            All rights reserved
  11.  
  12.                          dip@platonoff.com
  13.  
  14.   ..................................................................
  15.  
  16.   LICENSE
  17.   ~~~~~~~
  18.   Redistribution and use in source and binary forms, with or without
  19.   modification, are permitted provided that the following conditions
  20.   are met:
  21.  
  22.   1. Redistributions of source code must retain the above copyright
  23.      notice, this list of conditions and the following disclaimer.
  24.  
  25.   2. Redistributions in binary form must reproduce the above
  26.      copyright notice, this list of conditions and the following
  27.      disclaimer in the documentation and/or other materials provided
  28.      with the distribution.
  29.  
  30.   3. Redistributions of any form whatsoever, as well as all
  31.      advertising materials mentioning features or use of this
  32.      software (if any), must include the following acknowledgment:
  33.      "This product includes software developed by Dmitry I. Platonoff".
  34.  
  35.   4. The names "SysBar/2" and "Dmitry I. Platonoff" must not be
  36.      used to endorse or promote products derived from this software
  37.      without prior written permission. For such permission, please
  38.      contact dplatonoff@canada.com.
  39.  
  40.   5. Products derived from this software may not be called
  41.      "SysBar/2" nor may "Dmitry I. Platonoff" appear in their
  42.      contributor lists without prior written permission.
  43.  
  44.   ..................................................................
  45.  
  46.   DISCLAIMER
  47.   ~~~~~~~~~~
  48.   THIS SOFTWARE IS PROVIDED BY THE AUTHOR OR CONTRIBUTORS "AS IS"
  49.   AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  50.   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  51.   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  52.   AUTHOR OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  53.   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  54.   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  55.   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  56.   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  57.   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  58.   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  59.   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60.  
  61. */
  62.  
  63. #define __IBMCPP__
  64.  
  65. #define INCL_DOSMODULEMGR
  66. #define INCL_GPI
  67. #define INCL_WIN
  68.  
  69. #include <os2.h>
  70. #include <stdio.h>
  71. #include <stdlib.h>
  72. #include <string.h>
  73. #include "SysBar2_.h"
  74. #include "SysBar2_res.h"
  75.  
  76.  
  77.  
  78. // Structure to describe a bitmap with digit pictures
  79. struct DigitBitmap
  80. {
  81.   HBITMAP hBitmap[2];  //bitmap handle
  82.   int iWidth;          //single digit width
  83.   int iXStep;          //horisontal size of digit to display
  84.   int iHeight;         //single digit height
  85. };
  86. static struct DigitBitmap bLargeDigits[2] =
  87.   { { { 0, 0 }, 8, 8, 14 }, { { 0, 0 }, 12, 12, 21 } };
  88. static struct DigitBitmap bSmallDigits[2] =
  89.   { { { 0, 0 }, 5, 7, 6 }, { { 0, 0 }, 7, 10, 9 } };
  90.  
  91.  
  92. static short int iSysBar2Modules = 0;  // SysBar2.DLL call counter
  93.  
  94. static HMODULE hmSysBar2 = NULLHANDLE;  // SysBar2.DLL module handle
  95.  
  96. // Copyright strings
  97. static char *szSysBar2[3] =
  98. {
  99.   "SysBar/2 Utility Set  version 0.21",
  100.   "(c) Dmitry I. Platonoff, 1995-1999",
  101.   "dip@platonoff.com"
  102. };
  103.  
  104. char* __export SB2_Strings( int iIndex )
  105. {
  106.   return szSysBar2[iIndex];
  107. }
  108.  
  109.  
  110. // Resource loader
  111. void SB2_LoadResources( void )
  112. {
  113.   int iID = BMP_LARGEDIGITS;
  114.   HPS hps = WinGetPS( HWND_DESKTOP );
  115.   for ( int i = 0; i < 2; i++ ) for ( int j = 0; j < 2; j++ )
  116.   {
  117.     bLargeDigits[i].hBitmap[j] = GpiLoadBitmap( hps, hmSysBar2, iID,
  118.       bLargeDigits[i].iWidth * 11, bLargeDigits[i].iHeight );
  119.     bSmallDigits[i].hBitmap[j] = GpiLoadBitmap( hps, hmSysBar2, iID++ + 4,
  120.       bSmallDigits[i].iWidth * 10, bSmallDigits[i].iHeight );
  121.   }
  122.   WinReleasePS( hps );
  123. }
  124.  
  125. // Initialzation/registration procedure
  126. HMODULE __export SB2_Init( void )
  127. {
  128.   if ( iSysBar2Modules++ == 0 )
  129.   {
  130.     DosQueryModuleHandle( "SYSBAR2.DLL", ( PHMODULE ) & hmSysBar2 );
  131.     
  132.     SB2_LoadResources();
  133.   }
  134.  
  135.   return hmSysBar2;
  136. }
  137.  
  138. // Resource dumper
  139. void SB2_FreeResources( void )
  140. {
  141.   for ( int i = 0; i < 2; i++ ) for ( int j = 0; j < 2; j++ )
  142.   {
  143.     GpiDeleteBitmap( bLargeDigits[i].hBitmap[j] );
  144.     GpiDeleteBitmap( bSmallDigits[i].hBitmap[j] );
  145.   }
  146. }
  147.  
  148. // Unregistration/shutdown procedure
  149. void __export SB2_Over( void )
  150. {
  151.   if ( --iSysBar2Modules == 0 )
  152.     SB2_FreeResources();
  153. }
  154.  
  155. // Config filename creator
  156. char* __export SB2_CfgFilename( char *pszCfg, char *pszExe )
  157. {
  158.   if ( pszCfg )
  159.   {
  160.     int l = strlen( pszExe );
  161.     strcpy( pszCfg, pszExe );
  162.     pszCfg[l - 3] = 'C';
  163.     pszCfg[l - 2] = 'f';
  164.     pszCfg[l - 1] = 'g';
  165.   }
  166.   return pszCfg;
  167. }
  168.  
  169. // Procedure to display some digits passed as the character string
  170. void SB2_DisplayDigits( struct DigitBitmap bDigits, HPS hps, int x, int y,
  171.   char *pszString, short int bMonochrome, int iCount )
  172. {
  173.   if ( ! iCount ) iCount = strlen( pszString );
  174.  
  175.   POINTL pt4[4];
  176.   for ( short i = 0; i < iCount; i++ )
  177.   {
  178.     pt4[0].x = i * bDigits.iXStep + x;
  179.     pt4[0].y = y;
  180.     pt4[1].x = pt4[0].x + bDigits.iWidth - 1;
  181.     pt4[1].y = pt4[0].y + bDigits.iHeight - 1;
  182.     pt4[2].x = ( pszString[i] - '0' ) * bDigits.iWidth;
  183.     pt4[2].y = 0;
  184.     pt4[3].x = pt4[2].x + bDigits.iWidth;
  185.     pt4[3].y = bDigits.iHeight;
  186.     GpiWCBitBlt( hps, bDigits.hBitmap[bMonochrome], 4L, pt4,
  187.       ROP_SRCCOPY, BBO_IGNORE );
  188.   }
  189. }
  190.  
  191. // Procedure to display some large (LCD-style) digits passed as the 
  192. //  character string
  193. void __export SB2_LargeDigits( HPS hps, int x, int y, char *pszString, 
  194.   short int bMonochrome, short int bLarge, int iCount )
  195. {
  196.   SB2_DisplayDigits( bLargeDigits[bLarge], hps, x, y, pszString, bMonochrome,
  197.     iCount );
  198. }
  199.  
  200. // Procedure to display some small digits passed as the character string
  201. void __export SB2_SmallDigits( HPS hps, int x, int y, char *pszString,
  202.   short int bMonochrome, short int bLarge, int iCount )
  203. {
  204.   SB2_DisplayDigits( bSmallDigits[bLarge], hps, x, y, pszString, bMonochrome,
  205.     iCount );
  206. }
  207.  
  208. void __export SB2_Border( HPS hps, int iLeft, int iBottom, int iRight,
  209.   int iTop, short int iRaised, int iFiller, int bOutlined )
  210. {
  211.   POINTL pt;
  212.   if ( bOutlined )
  213.   {
  214.     GpiSetColor( hps, CLR_BLACK );
  215.     pt.x = iLeft;
  216.     pt.y = iBottom;
  217.     GpiMove( hps, &pt );
  218.     pt.x = iRight;
  219.     pt.y = iTop;
  220.     GpiBox( hps, DRO_OUTLINE, &pt, 0, 0 );
  221.   }
  222.   if ( iFiller )
  223.   {
  224.     GpiSetColor( hps, iFiller );
  225.     pt.x = iLeft + bOutlined;
  226.     pt.y = iBottom + bOutlined;
  227.     GpiMove( hps, &pt );
  228.     pt.x = iRight - bOutlined;
  229.     pt.y = iTop - bOutlined;
  230.     GpiBox( hps, DRO_FILL, &pt, 0, 0 );
  231.   }
  232.   GpiSetColor( hps, iRaised == 1 ? SB2c_Brighter : SB2c_Darker );
  233.   pt.x = iLeft + bOutlined;
  234.   pt.y = iBottom + bOutlined;
  235.   GpiMove( hps, &pt );
  236.   pt.y = iTop - bOutlined;
  237.   GpiLine( hps, &pt );
  238.   pt.x = iRight - bOutlined;
  239.   GpiLine( hps, &pt );
  240.   GpiSetColor( hps, iRaised ? ( iRaised == 1 ? SB2c_Darker : SB2c_Filler ) :
  241.     SB2c_Brighter );
  242.   pt.y = iBottom + bOutlined;
  243.   GpiLine( hps, &pt );
  244.   pt.x = iLeft + bOutlined;
  245.   GpiLine( hps, &pt );
  246. }
  247.  
  248.  
  249. // Method to read a line from the file and strip extra spaces & comments
  250. // Returns "cleaned" string
  251. char* /*__export*/ IniFile::Read( void )
  252. {
  253.   // Get next text line from the source file
  254.   if ( ReadString() )
  255.   {
  256.     sBuffer[0] = 0;
  257.     return sBuffer;
  258.   }
  259.   
  260.   // Strip leading spaces
  261.   char* curr_ptr = sBuffer;
  262.   while ( *curr_ptr == ' ' || *curr_ptr == '\t' ) curr_ptr++;
  263.   
  264.   // Strip comments (the comment starts with the ";" character in the beginning
  265.   //  of the text line or with the " ;" sequence in the middle of the line)
  266.   char* semicolon = strchr( curr_ptr, ';' );
  267.   if ( semicolon && ( semicolon == curr_ptr || *( semicolon - 1 ) == ' ' ||
  268.     *( semicolon - 1 ) == '\t' ) ) *semicolon = 0;
  269.     
  270.   // Cut extra spaces in the end of line
  271.   if ( *curr_ptr )
  272.   {
  273.     semicolon = curr_ptr + strlen( curr_ptr ) - 1;
  274.     while( ( *semicolon == ' ' || *semicolon == 9 || *semicolon == 13 ||
  275.        *semicolon == 10 ) && *semicolon ) *semicolon-- = 0;
  276.   }
  277.   
  278.   return curr_ptr;
  279. }
  280.  
  281. // Get the next value of the same entry
  282. // Parameter: entry name
  283. // Returns entry value
  284. char* /*__export*/ IniFile::GetNext( char* pszEntry )
  285. {
  286.   // Read an input file until the end
  287.   while ( ! feof( f ) )
  288.   {
  289.     char* s = Read();  //get the next line and strip spaces and comments
  290.     
  291.     if ( *s == '[' ) return NULL;  //return if we've reached the next section
  292.     
  293.     // Search for "=" char
  294.     char* equals = strchr( s, '=' );
  295.     if ( equals )
  296.     {
  297.       // Get the rest of line (all after "=")
  298.       *equals = 0;
  299.       if ( equals++ != s )
  300.       {
  301.         // Strip spaces between the entry name and "="
  302.         char* entryend = equals - 2;
  303.         while ( entryend > s && ( *entryend == ' ' || *entryend == 9 ) )
  304.           *entryend-- = 0;
  305.       }
  306.     }
  307.     
  308.     // Compare entry name with given. Return the rest of line if OK
  309.     if ( ! strcmp( s, pszEntry ) ) return equals;
  310.   }
  311.   
  312.   // Otherwise return NULL
  313.   return NULL;
  314. }
  315.  
  316. // Method to get the first value of entry from specified section
  317. // Parameters are:
  318. //   pszSection - section name,
  319. //   pszEntry - entry name,
  320. //   pszDefault - default value (used when entry not found)
  321. // Returns entry value in the static buffer
  322. char* /*__export*/ IniFile::Get( char* pszSection, char* pszEntry,
  323.   char* pszDefault )
  324. {
  325.   // Rewind to the beginning if INI-file
  326.   fseek( f, 0L, 0 );
  327.   
  328.   // Read an input file until the end
  329.   while ( ! feof( f ) )
  330.   {
  331.     char* s = Read();  //get next line
  332.     
  333.     // Search for section name
  334.     if ( s[0] == '[' )
  335.     {
  336.       char* close = strchr( ++s, ']' );
  337.       if ( close )
  338.       {
  339.         *close = 0;
  340.  
  341.         // Compare section name with given
  342.         if ( ! strcmp( s, pszSection ) )
  343.         {
  344.           // Look for an entry and return its value at success
  345.           if ( s = GetNext( pszEntry ) ) return s;
  346.           else return pszDefault;  //otherwise return the default value
  347.         }
  348.       }
  349.     }
  350.   }
  351.   return pszDefault;  //if section not found, return the default value
  352. }
  353.  
  354.  
  355. void __export SB2_Button( HPS hps, int iLeft, int iBottom, int iRight,
  356.   int iTop, short int iRaised, 
  357.   HBITMAP hBitmap, int iBitmapWidth, int iBitmapHeight )
  358. {
  359.   SB2_Border( hps, iLeft, iBottom, iRight, iTop, iRaised == 1 ? 1 : 2,
  360.     SB2c_Filler, 0 );
  361.   if ( hBitmap )
  362.   {
  363.     POINTL pt4[4];
  364.     pt4[0].x = ( ( iRight + iLeft - iBitmapWidth + 1 ) >> 1 ) + 1 - iRaised;
  365.     pt4[0].y = ( ( iTop + iBottom - iBitmapHeight + 1 ) >> 1 ) - 1 + iRaised;
  366.     pt4[1].x = pt4[0].x + iBitmapWidth - 1;
  367.     pt4[1].y = pt4[0].y + iBitmapHeight - 1;
  368.     pt4[2].x = 0;
  369.     pt4[2].y = 0;
  370.     pt4[3].x = iBitmapWidth;
  371.     pt4[3].y = iBitmapHeight;
  372.     GpiWCBitBlt( hps, hBitmap, 4L, pt4, ROP_SRCCOPY, BBO_IGNORE );
  373.   }
  374. }
  375.  
  376. // Dialog page adder
  377. ULONG __export SB2_AddDlgPage( HWND hwnd, ULONG ulNotebookID,
  378.   char *pszTabText, char *pszComment )
  379. {
  380.   ULONG ulPageID = ( ULONG ) WinSendDlgItemMsg( hwnd, ulNotebookID,
  381.     BKM_INSERTPAGE, ( MPARAM ) NULL, MPFROM2SHORT( ( BKA_MAJOR |
  382.     BKA_STATUSTEXTON | BKA_AUTOPAGESIZE ), BKA_LAST ) );
  383.   WinSendDlgItemMsg( hwnd, ulNotebookID, BKM_SETTABTEXT,
  384.     ( MPARAM ) ulPageID, MPFROMP ( pszTabText ) );
  385.   WinSendDlgItemMsg( hwnd, ulNotebookID, BKM_SETSTATUSLINETEXT,
  386.     ( MPARAM ) ulPageID, MPFROMP ( pszComment ) );
  387.   return ulPageID;
  388. }
  389.  
  390.  
  391.  
  392. inline int atoi2( char *s, int iDefault = 0 )
  393. {
  394.   if ( s && *s ) return atoi( s );
  395.   else return iDefault;
  396. }
  397.  
  398.  
  399.  
  400. static char *pszFontConfig[] =
  401. {
  402.   "fsSelection",     // 0
  403.   "lMatch",          // 1
  404.   "szFacename",      // 2
  405.   "idRegistry",      // 3
  406.   "lMaxBaselineExt", // 4
  407.   "lAveCharWidth",   // 5
  408.   "fsType"           // 6
  409. };
  410.  
  411. void __export SB2_LoadFontCfg( char *pszSection, FATTRS *pF, IniFile *pCfg )
  412. {
  413.   memset( pF, 0, sizeof ( FATTRS ) );
  414.   pF->usRecordLength = sizeof ( FATTRS );
  415.   pF->usCodePage = 0;
  416.   pF->lMaxBaselineExt = 13;
  417.   pF->lAveCharWidth = 5;
  418.   pF->fsFontUse = FATTR_FONTUSE_NOMIX;
  419.   strcpy( pF->szFacename, "Helv" );
  420.   if ( pCfg && ( *pCfg )() )
  421.   {
  422.     pF->fsSelection =
  423.       atoi2( pCfg->Get( pszSection, pszFontConfig[0] ) );
  424.     pF->lMatch = atoi2( pCfg->Get( pszSection, pszFontConfig[1] ) );
  425.     pF->idRegistry = atoi2( pCfg->Get( pszSection, pszFontConfig[3] ) );
  426.     pF->lMaxBaselineExt =
  427.       atoi2( pCfg->Get( pszSection, pszFontConfig[4] ), 13 );
  428.     pF->lAveCharWidth =
  429.       atoi2( pCfg->Get( pszSection, pszFontConfig[5] ), 5 );
  430.     pF->fsType = atoi2( pCfg->Get( pszSection, pszFontConfig[6] ) );
  431.     char *pS = pCfg->Get( pszSection, pszFontConfig[2] );
  432.     if ( pS && *pS ) strcpy( pF->szFacename, pS );
  433.   }
  434. }
  435.  
  436. void __export SB2_SaveFontCfg( char *pszSection, FATTRS *pF, FILE *f )
  437. {
  438.   fprintf( f,
  439.     "[%s]\n"
  440.     "%s=%i\n"
  441.     "%s=%i\n"
  442.     "%s=%s\n"
  443.     "%s=%i\n"
  444.     "%s=%i\n"
  445.     "%s=%i\n"
  446.     "%s=%i\n\n",
  447.     pszSection,
  448.     pszFontConfig[0], pF->fsSelection,
  449.     pszFontConfig[1], pF->lMatch,
  450.     pszFontConfig[2], pF->szFacename,
  451.     pszFontConfig[3], pF->idRegistry,
  452.     pszFontConfig[4], pF->lMaxBaselineExt,
  453.     pszFontConfig[5], pF->lAveCharWidth,
  454.     pszFontConfig[6], pF->fsType );
  455. }
  456.  
  457. void DescWindow::Hide( void )
  458. {
  459.   WinSetWindowPos( hwDescFrame, 0, 0, 0, 0, 0, SWP_HIDE );
  460. }
  461. void DescWindow::SetText( char *pszNewText )
  462. {
  463.   int l = strlen( pszNewText );
  464.   while ( l > 0 && ( pszNewText[l - 1] == '\r' || pszNewText[l - 1] == '\n' ) )
  465.     l--;
  466.   char *p = new char[l + 1];
  467.   if ( p )
  468.   {
  469.     for ( int i = 0; i < l ; i++ ) p[i] = ( pszNewText[i] == '\n' ||
  470.       pszNewText[i] == '\r' ? ' ' : pszNewText[i] );
  471.     p[i] = 0;
  472.  
  473.     if ( pszText ) delete pszText;
  474.     pszText = p;
  475.   }
  476. }
  477. void DescWindow::AdjustSize( FATTRS *pF, HWND hwnd )
  478. {
  479.   if ( pszText )
  480.   {
  481.     HPS hps = WinGetPS( hwnd );
  482.     pF->usCodePage = GpiQueryCp( hps );
  483.     GpiCreateLogFont( hps, NULL, 200L, pF );
  484.     GpiSetCharSet( hps, 200L );
  485.     CHARBUNDLE cb;
  486.     cb.usTextAlign = TA_LEFT | TA_BASE;
  487.     GpiSetAttrs( hps, PRIM_CHAR, CBB_TEXT_ALIGN, 0, &cb );
  488.     POINTL ptl[TXTBOX_COUNT];
  489.     GpiQueryTextBox( hps, strlen( pszText ), pszText, TXTBOX_COUNT, ptl );
  490.     iDescWidth = ptl[TXTBOX_TOPRIGHT].x + 10;
  491.     iDescHeight = ptl[TXTBOX_TOPRIGHT].y + 10;
  492.     GpiDeleteSetId( hps, 200L );
  493.     WinReleasePS( hps );
  494.   }
  495. }
  496. void DescWindow::MoveTo( int x, int y )
  497. {
  498.   iDescX = x;
  499.   iDescY = y;
  500.   WinSetWindowPos( hwDescFrame, HWND_TOP, x, y, iDescWidth, iDescHeight,
  501.     SWP_MOVE | SWP_SIZE | SWP_SHOW | SWP_ZORDER );
  502.   WinInvalidateRect( hwDescFrame, NULL, TRUE );
  503. }
  504. void DescWindow::Paint( FATTRS *pF, HWND hwnd )
  505. {
  506.   HPS hps;
  507.   RECTL rc;
  508.   hps = WinBeginPaint( hwnd, 0L, &rc );
  509.   SB2_Border( hps, 0, 0, iDescWidth - 1, iDescHeight - 1, 1, SB2c_Filler, 1 );
  510. //  SB2_Border( hps, 2, 2, iDescWidth - 3, iDescHeight - 3, 0, CLR_BLACK );
  511.   if ( pszText )
  512.   {
  513.     GpiCreateLogFont( hps, NULL, 200L, pF );
  514.     GpiSetCharSet( hps, 200L );
  515.     CHARBUNDLE cb;
  516.     cb.lColor = CLR_WHITE;
  517.     cb.usTextAlign = TA_LEFT | TA_BASE;
  518.     GpiSetAttrs( hps, PRIM_CHAR, CBB_COLOR | CBB_TEXT_ALIGN, 0, &cb );
  519.     POINTL pt;
  520.     pt.x = 4;
  521.     pt.y = 6;
  522.     RECTL rc1;
  523.     rc1.xLeft = 4;
  524.     rc1.yBottom = 4;
  525.     rc1.xRight = iDescWidth - 5;
  526.     rc1.yTop = iDescHeight - 5;
  527.     ULONG uOptions = CHS_CLIP;
  528.     GpiCharStringPosAt( hps, &pt, &rc1, uOptions, strlen( pszText ), pszText,
  529.       NULL );
  530.     GpiDeleteSetId( hps, 200L );
  531.   }
  532.   WinEndPaint( hps );
  533. }
  534. HWND DescWindow::CreateWindow( char *pszClassName )
  535. {
  536.   ULONG ulWinStyle = FCF_NOBYTEALIGN;
  537.   return ( hwDescFrame = WinCreateStdWindow( HWND_DESKTOP, 0, &ulWinStyle,
  538.     pszClassName, 0, 0, NULLHANDLE, 1, &hwDescClient ) );
  539. }
  540. DescWindow::~DescWindow( void )
  541. {
  542.   if ( hwDescFrame ) WinDestroyWindow( hwDescFrame );
  543.   if ( pszText ) delete pszText;
  544. }
  545. DescWindow::DescWindow( void )
  546. {
  547.   pszText = NULL;
  548.   hwDescFrame = NULL;
  549. }
  550. void DescWindow::AdjustPos( int x, int y, int dx, int dy, int bVertical )
  551. {
  552.   int iMaxX = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
  553.   int iMaxY = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
  554.   if ( bVertical )
  555.   {
  556.     x += ( ( x + dx + 3 + iDescWidth ) < iMaxX ) ? dx + 3 : - 3 - iDescWidth;
  557.     if ( y < 0 ) y = 0;
  558.     else if ( y + iDescHeight >= iMaxY ) y = iMaxY - iDescHeight;
  559.   }
  560.   else
  561.   {
  562.     y += ( ( y - 3 - iDescHeight ) < 0 ) ? dy + 3 : -3 - iDescHeight;
  563.     if ( x < 0 ) x = 0;
  564.     else if ( x + iDescWidth >= iMaxX ) x = iMaxX - iDescWidth;
  565.   }
  566.   MoveTo( x, y );
  567. }
  568.  
  569. static char *pszColorNames[] =
  570. {
  571.   "white", "palegray", "blue", "red", "pink", "green", "cyan", "yellow",
  572.   "darkgray", "darkblue", "darkred", "darkpink", "darkgreen", "darkcyan",
  573.   "brown", "black"
  574. };
  575. int iColorValues[] =
  576. {
  577.   CLR_WHITE, CLR_PALEGRAY, CLR_BLUE, CLR_RED, CLR_PINK, CLR_GREEN, CLR_CYAN,
  578.   CLR_YELLOW, CLR_DARKGRAY, CLR_DARKBLUE, CLR_DARKRED, CLR_DARKPINK,
  579.   CLR_DARKGREEN, CLR_DARKCYAN, CLR_BROWN, CLR_BLACK
  580. };
  581. const int iColorCount = 16;
  582.  
  583. void __export SB2_FillColorList( HWND hwnd, ULONG ulID, int iSelected )
  584. {
  585.   for ( int i = 0; i < iColorCount; i++ )
  586.     WinSendDlgItemMsg( hwnd, ulID, LM_INSERTITEM, ( MPARAM )
  587.       LIT_END, MPFROMP( pszColorNames[i] ) );
  588.   WinSendDlgItemMsg( hwnd, ulID, LM_SELECTITEM,
  589.     ( MPARAM ) iSelected, ( MPARAM ) 1 );
  590. }
  591.  
  592. char* __export SB2_ColorName( int iIndex )
  593. {
  594.   return pszColorNames[iIndex];
  595. }
  596.  
  597. int __export SB2_ColorValue( int iIndex )
  598. {
  599.   return iColorValues[iIndex];
  600. }
  601.  
  602. int __export SB2_ColorA2I( char *pszName )
  603. {
  604.   for ( int i = 0; i < iColorCount; i++ )
  605.     if ( ! strcmp( pszName, pszColorNames[i] ) ) return i;
  606.   return 0;
  607. }
  608.  
  609. int __export SB2_ColorCount( void )
  610. {
  611.   return iColorCount;
  612. }
  613.  
  614.  
  615. char* __export SB2_ParseValue( char *s, int& i )
  616. {
  617.   if ( ! s || s[0] == 0 ) return NULL;
  618.   char *pS = strchr( s, ',' );
  619.   if ( pS ) *pS++ = 0;
  620.   i = atoi( s );
  621.   return pS;
  622. }
  623. char* __export SB2_ParseValue( char *s, char *d )
  624. {
  625.   if ( ! s || s[0] == 0 ) return NULL;
  626.   char *pS = strchr( s, ',' );
  627.   if ( pS ) *pS++ = 0;
  628.   strcpy( d, s );
  629.   return pS;
  630. }
  631.  
  632.