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

  1. /*
  2.  
  3.   SysBar/2 Utility Set  version 0.21
  4.  
  5.   Task Switcher module (modified by Eugen Kuleshov)
  6.  
  7.   ..................................................................
  8.  
  9.   Copyright (c) 1995-1999  Dmitry I. Platonoff
  10.                            All rights reserved
  11.  
  12.                          dplatonoff@canada.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_GPI
  66. #define INCL_WIN
  67. #define INCL_DOSPROCESS
  68. #define INCL_DOSRESOURCES
  69.  
  70. #include <os2.h>
  71. #include <stdio.h>
  72. #include <stdlib.h>
  73. #include <string.h>
  74. #include "..\SysBar2.h"
  75. #include "SB2_Switcher_res.h"
  76.  
  77. // Main application and window handles
  78. HAB hab;
  79. HWND hwSwClient = NULLHANDLE;
  80. HWND hwSwFrame = NULLHANDLE;
  81. DescWindow *pTaskDesc;
  82. HWND hmPopupMenu = NULLHANDLE;
  83. HWND hmTaskMenu = NULLHANDLE;
  84. HMODULE hmSysBar2Dll = NULLHANDLE;
  85. HBITMAP hbQ = NULLHANDLE;
  86. HDC hMemDC = NULLHANDLE;
  87. HPS hMemPS = NULLHANDLE;
  88. HBITMAP hbMem = NULLHANDLE;
  89. HWND hwLastActive = NULLHANDLE;
  90.  
  91.  
  92. ULONG ulSCValues[] =
  93. {
  94.   SC_RESTORE,
  95.   SC_MOVE,
  96.   SC_SIZE,
  97.   SC_MINIMIZE,
  98.   SC_MAXIMIZE,
  99.   SC_HIDE,
  100.   SC_SYSMENU
  101. };
  102.  
  103. // Appearance flags and modes
  104. short int bActive = 0;
  105. short int iTopmost = 1;
  106. short int iLarge = 0;
  107. short int bSwap = 0;
  108. short int bLockPosition = 0;
  109. short int bSwitchlistTitles = 0;
  110. short int bCheckPID = 1;
  111. short int bCheckVis = 1;
  112. short int bCheckJump = 1;
  113. short int bAlienMenu = 0;
  114. short int bForceRescan = 0;
  115. short int bClearIt = 0;
  116. short int bFixedSize = 0;
  117. int iFixedSize = 16;
  118. static short int bLastVisible = 0;
  119. short int iBindToCorner = 0;
  120. int iOrientation = 0;
  121. int iCellColor = 0;
  122. FATTRS fatDesc;
  123. FONTDLG fd;
  124. char szDescFontSection[] = "desc_font";
  125. char szFamilyname[FACESIZE] = "";
  126. char *pszOtherFltConfig[] =
  127. {
  128.   "other_filters",   // 0
  129.   "pid",             // 1
  130.   "visibility",      // 2
  131.   "jump"             // 3
  132. };
  133. const int iHide2SwCount = 3;
  134. char *pszHide2Sw[] =
  135. {
  136.   "default",   // 0
  137.   "always",    // 1
  138.   "never"      // 2
  139. };
  140.  
  141.  
  142. // Just a dummy data structure
  143. typedef struct
  144. {
  145.   short int iSize;
  146. } DummyData;
  147. DummyData DummyInit = { sizeof ( DummyData ) };
  148.  
  149. // Configuration file stuff
  150. char *pszIniFile = NULL;
  151. char szSysBar2Sw[] = "SysBar2_Switcher";
  152. char *pszYesNo[2] = { "no", "yes" };
  153.  
  154. // Task list structures and counters
  155. int iTaskCount = 0;
  156. int iRealTaskCount = 0;
  157. SWENTRY *pTasks = NULL;
  158. PSWBLOCK pRealTasks = NULL;
  159. int iCurrTask = -1;
  160.  
  161. // Window size variables
  162. int iSwCellSize[4] = { 22, 29, 34, 22 };
  163. int iSwWHeight = 0,
  164.   iSwWWidth = 0;
  165. int iSwWrkLeft = 0,
  166.   iSwWrkBottom = 0,
  167.   iSwWrkRight = 0,
  168.   iSwWrkTop = 0;
  169.  
  170.  
  171. // Config value processing routines ------------------------------------------
  172. inline int strcmp2( char *s1, char *s2, int iDefault = -1 )
  173. {
  174.   if ( ! s1 || ! s2 ) return iDefault;
  175.   else return strcmp( s1, s2 );
  176. }
  177.  
  178. inline int atoi2( char *s, int iDefault = 0 )
  179. {
  180.   if ( s && *s ) return atoi( s );
  181.   else return iDefault;
  182. }
  183.  
  184.  
  185. // Abnormal startup handler --------------------------------------------------
  186. void AbortStartup( void )
  187. {
  188.   PERRINFO pErrInfoBlk;
  189.   PSZ pszOffSet;
  190.   PSZ pszErrMsg;
  191.  
  192.   if ( ( pErrInfoBlk = WinGetErrorInfo( hab ) ) != ( PERRINFO ) NULL )
  193.   {
  194.     pszOffSet = ( ( PSZ ) pErrInfoBlk ) + pErrInfoBlk->offaoffszMsg;
  195.     pszErrMsg = ( ( PSZ ) pErrInfoBlk ) + *( ( PSHORT ) pszOffSet );
  196.     if ( ( int ) hwSwFrame && ( int ) hwSwClient )
  197.       WinMessageBox( HWND_DESKTOP, hwSwFrame, ( PSZ ) pszErrMsg,
  198.         "SysBar/2 Task switcher startup error :(", 8999, 
  199.         MB_MOVEABLE | MB_ERROR | MB_CANCEL );
  200.     WinFreeErrorInfo( pErrInfoBlk );
  201.   }
  202.   WinPostMsg( hwSwClient, WM_QUIT, ( MPARAM ) NULL, ( MPARAM ) NULL );
  203. }
  204.  
  205.  
  206. //MRESULT EXPENTRY _FilterWndProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  207. void SaveOptions( void );
  208.  
  209. void SetSwitchlistVisibility( SWENTRY& swe, int bShow = 1 )
  210. {
  211.   swe.swctl.uchVisibility = ( bShow ? SWL_VISIBLE : SWL_INVISIBLE );
  212.   WinChangeSwitchEntry( swe.hswitch, &( swe.swctl ) );
  213. }
  214.  
  215. void SetTaskJumpability( SWENTRY& swe, int bJumpable = 1 )
  216. {
  217.   swe.swctl.fbJump = ( bJumpable ? SWL_JUMPABLE : SWL_NOTJUMPABLE );
  218.   WinChangeSwitchEntry( swe.hswitch, &( swe.swctl ) );
  219. }
  220.  
  221.  
  222. // Filter dialog class declaration and methods -------------------------------
  223. const int iMaxFilterString = 96;
  224. #define WFO_HideDefault       0
  225. #define WFO_HideAlways        1
  226. #define WFO_HideNever         2
  227. #define WFO_HideMask          3
  228. #define WFO_HideInTasklist    4
  229. #define WFO_MakeNonjumpable   8
  230. typedef struct
  231. {
  232.   char szText[iMaxFilterString];
  233.   int iTextLength;
  234.   int iOptions;
  235. } WinFilterEntry;
  236. int iExceptionCount;
  237. WinFilterEntry *pExceptions;
  238. WinFilterEntry TempException;
  239. char *pszExceptionSection = "hidefilter";
  240. short int bExceptionsEnabled = 1;
  241.  
  242.  
  243. int FindExceptionIndex( char *s )
  244. {
  245.   for ( int i = iExceptionCount - 1; i >= 0; i-- ) if ( strncmp( s,
  246.     pExceptions[i].szText, pExceptions[i].iTextLength ) == 0 ) return i;
  247.   return -1;
  248. }
  249.  
  250. void SaveExceptions( FILE *f )
  251. {
  252.   fprintf( f,
  253.     "[%s]\n"
  254.     "enabled=%s\n"
  255.     "count=%i",
  256.     pszExceptionSection, pszYesNo[bExceptionsEnabled], iExceptionCount );
  257.   for ( int i = 0; i < iExceptionCount; i++ ) fprintf( f, "\n%03i=%s,%i", i,
  258.     pExceptions[i].szText, pExceptions[i].iOptions );
  259.   fprintf( f, "\n\n" );
  260. }
  261.  
  262. void LoadExceptions( IniFile *pCfg )
  263. {
  264.   bExceptionsEnabled = ( strcmp2( pCfg->Get( pszExceptionSection, "enabled" ),
  265.     pszYesNo[1] ) == 0 );
  266.   iExceptionCount = atoi2( pCfg->Get( pszExceptionSection, "count" ) );
  267.   if ( iExceptionCount )
  268.   {
  269.     pExceptions = new WinFilterEntry[iExceptionCount];
  270.     if ( pExceptions )
  271.     {
  272.       memset( pExceptions, 0, iExceptionCount * sizeof ( WinFilterEntry ) );
  273.       char szTmp[5];
  274.       char *pS;
  275.       for ( int i = 0; i < iExceptionCount; i++ )
  276.       {
  277.         sprintf( szTmp, "%03i", i );
  278.         if ( ( pS = pCfg->Get( pszExceptionSection, szTmp ) ) )
  279.         {
  280.           pS = SB2_ParseValue( pS, pExceptions[i].szText );
  281.           SB2_ParseValue( pS, pExceptions[i].iOptions );
  282.           pExceptions[i].iTextLength = strlen( pExceptions[i].szText );
  283.         }
  284.       }
  285.     }
  286.     else iExceptionCount = 0;
  287.   }
  288. }
  289.  
  290. int CheckExceptions( SWENTRY& swe, short int bChangesAllowed = 0 )
  291. {
  292.   if ( ! bExceptionsEnabled ) return 1;
  293.   for ( int i = iExceptionCount - 1; i >= 0; i-- )
  294.   {
  295.     if ( strncmp( swe.swctl.szSwtitle,
  296.       pExceptions[i].szText, pExceptions[i].iTextLength ) == 0 )
  297.     {
  298.       int iOptions = pExceptions[i].iOptions;
  299.  
  300.       if ( bChangesAllowed )
  301.       {
  302.         int bChangesMade = 0;
  303.         if ( swe.swctl.uchVisibility == SWL_VISIBLE &&
  304.           ( iOptions & WFO_HideInTasklist ) )
  305.         {
  306.           swe.swctl.uchVisibility = SWL_INVISIBLE;
  307.           bChangesMade = 1;
  308.         }
  309.         else if ( swe.swctl.uchVisibility == SWL_INVISIBLE && !
  310.           ( iOptions & WFO_HideInTasklist ) )
  311.         {
  312.           swe.swctl.uchVisibility = SWL_VISIBLE;
  313.           bChangesMade = 1;
  314.         }
  315.         if ( swe.swctl.fbJump == SWL_JUMPABLE &&
  316.           ( iOptions & WFO_MakeNonjumpable ) )
  317.         {
  318.           swe.swctl.fbJump = SWL_NOTJUMPABLE;
  319.           bChangesMade = 1;
  320.         }
  321.         else if ( swe.swctl.fbJump == SWL_NOTJUMPABLE && !
  322.           ( iOptions & WFO_MakeNonjumpable ) )
  323.         {
  324.           swe.swctl.fbJump = SWL_JUMPABLE;
  325.           bChangesMade = 1;
  326.         }
  327.  
  328.         if ( bChangesMade )
  329.           WinChangeSwitchEntry( swe.hswitch, &( swe.swctl ) );
  330.       }
  331.  
  332.       if ( iOptions & WFO_HideNever ) return 1;
  333.       else if ( iOptions & WFO_HideAlways ) return 0;
  334.     }
  335.   }
  336.   return ( ( swe.swctl.uchVisibility == SWL_VISIBLE || ! bCheckVis ) &&
  337.     ( swe.swctl.fbJump == SWL_JUMPABLE || ! bCheckJump ) &&
  338.     ( swe.swctl.idProcess > 0 || ! bCheckPID ) );
  339. }
  340.  
  341. // Exception setup dialog window procedure ------------------------------------
  342. MRESULT EXPENTRY ExceptionSetupDlgProc( HWND hwnd, ULONG msg, MPARAM mp1,
  343.   MPARAM mp2 )
  344. {
  345.   switch ( msg )
  346.   {
  347.     case WM_INITDLG:
  348.       {
  349.         WinSetDlgItemText( hwnd, D_Filter_Title, TempException.szText );
  350.         WinSendDlgItemMsg( hwnd, D_Filter_Invisible, BM_SETCHECK,
  351.           ( MPARAM ) ( ( TempException.iOptions & WFO_HideInTasklist ) ==
  352.           WFO_HideInTasklist ), 0 );
  353.         WinSendDlgItemMsg( hwnd, D_Filter_NonJumpable, BM_SETCHECK,
  354.           ( MPARAM ) ( ( TempException.iOptions & WFO_MakeNonjumpable ) ==
  355.           WFO_MakeNonjumpable ), 0 );
  356.         for ( int i = 0; i < iHide2SwCount; i++ )
  357.           WinSendDlgItemMsg( hwnd, D_Filter_Hide4SwOnly, LM_INSERTITEM,
  358.             ( MPARAM ) LIT_END, MPFROMP( pszHide2Sw[i] ) );
  359.         WinSendDlgItemMsg( hwnd, D_Filter_Hide4SwOnly, LM_SELECTITEM,
  360.           ( MPARAM ) ( TempException.iOptions & WFO_HideMask ), ( MPARAM ) 1 );
  361.       }
  362.       break;
  363.  
  364.     case WM_DESTROY:
  365.       WinQueryDlgItemText( hwnd, D_Filter_Title,
  366.         sizeof( TempException.szText ), TempException.szText );
  367.       TempException.iOptions = 0;
  368.       if ( WinQueryButtonCheckstate( hwnd, D_Filter_Invisible ) )
  369.         TempException.iOptions |= WFO_HideInTasklist;
  370.       if ( WinQueryButtonCheckstate( hwnd, D_Filter_NonJumpable ) )
  371.         TempException.iOptions |= WFO_MakeNonjumpable;
  372.       TempException.iOptions |= ( WFO_HideMask & ( int )
  373.         WinSendDlgItemMsg( hwnd, D_Filter_Hide4SwOnly,
  374.           LM_QUERYSELECTION, ( MPARAM ) LIT_CURSOR, ( MPARAM ) 0 ) );
  375.  
  376.     default:
  377.       return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  378.   }
  379.   return ( MRESULT ) FALSE;
  380. }
  381.  
  382. void FillExceptionList( HWND hwnd, int iID )
  383. {
  384.   WinSendDlgItemMsg( hwnd, iID, LM_DELETEALL, ( MPARAM ) 0, ( MPARAM ) 0 );
  385.   for ( int i = 0; i < iExceptionCount; i++ )
  386.     WinSendDlgItemMsg( hwnd, iID, LM_INSERTITEM,
  387.       ( MPARAM ) LIT_END, MPFROMP( pExceptions[i].szText ) );
  388.   if ( iExceptionCount ) WinSendDlgItemMsg( hwnd, iID,
  389.     LM_SELECTITEM, ( MPARAM ) 0, ( MPARAM ) 1 );
  390. }
  391.  
  392. int CompareExceptions( const void *p1, const void *p2 )
  393. {
  394.   return strcmp( ( ( WinFilterEntry* ) p1 )->szText,
  395.     ( ( WinFilterEntry* ) p2 )->szText );
  396. }
  397.  
  398. int EditException( HWND hwnd, int iIndex = -1 )
  399. {
  400.   if ( iIndex >= 0 ) TempException = pExceptions[iIndex];
  401.  
  402.   int iReturn = ( WinDlgBox( HWND_DESKTOP, hwnd, ExceptionSetupDlgProc,
  403.     ( HMODULE ) 0, DLG_FILTERS, ( PVOID ) &DummyInit ) == DID_OK );
  404.  
  405.   if ( iReturn )
  406.   {
  407.     if ( ! ( TempException.iTextLength = strlen( TempException.szText ) ) )
  408.       return 0;
  409.     if ( iIndex == -1 )
  410.     {
  411.       WinFilterEntry *pNewExceptions = new WinFilterEntry[iExceptionCount + 1];
  412.       if ( pNewExceptions )
  413.       {
  414.         if ( iExceptionCount == 0 )
  415.         {
  416.           pNewExceptions[0] = TempException;
  417.           pExceptions=pNewExceptions;
  418.           iExceptionCount = 1;
  419.           return iReturn;
  420.         }
  421.         memmove( pNewExceptions, pExceptions,
  422.           iExceptionCount * sizeof( WinFilterEntry ) );
  423.         WinFilterEntry *pOldExceptions = pExceptions;
  424.         pExceptions = pNewExceptions;
  425.         iIndex = iExceptionCount++;
  426.         delete pOldExceptions;
  427.       }
  428.       else return 0;
  429.     }
  430.     pExceptions[iIndex] = TempException;
  431.     qsort( pExceptions, iExceptionCount, sizeof( WinFilterEntry ), CompareExceptions );
  432.     bForceRescan = 1;
  433.   }
  434.  
  435.   return iReturn;
  436. }
  437.  
  438. void RemoveException( int i )
  439. {
  440.   if ( --iExceptionCount )
  441.   {
  442.     if ( i < iExceptionCount ) memmove( &pExceptions[i], &pExceptions[i + 1],
  443.       ( iExceptionCount - i ) * sizeof( WinFilterEntry ) );
  444.   }
  445.   else
  446.   {
  447.     delete pExceptions;
  448.     pExceptions = NULL;
  449.   }
  450.   bForceRescan = 1;
  451. }
  452.  
  453.  
  454.  
  455. // A procedure to save current configuration ---------------------------------
  456. void SaveOptions( void )
  457. {
  458.   SWP Swp;
  459.   if ( WinQueryWindowPos( hwSwFrame, &Swp ) )
  460.   {
  461.     FILE *f = fopen( pszIniFile, "wt" );
  462.     if ( f )
  463.     {
  464.       fprintf( f,
  465.         "[%s]\n"
  466.         "x=%i\n"
  467.         "y=%i\n"
  468.         "orientation=%i\n"
  469.         "size=%i\n"
  470.         "customsize=%i\n"
  471.         "cornerbind=%i\n"
  472.         "topmost=%i\n"
  473.         "lockposition=%s\n"
  474.         "swapbuttons=%s\n"
  475.         "switchlisttitles=%s\n"
  476.         "cellcolor=%s\n"
  477.         "fixedsize=%s\n"
  478.         "fixedcells=%i\n\n",
  479.         szSysBar2Sw,
  480.         iOrientation == 2 ? Swp.x + Swp.cx - 12 : Swp.x,
  481.         iOrientation == 1 ? Swp.y + Swp.cy - 12 : Swp.y,
  482.         iOrientation, iLarge, iSwCellSize[3], iBindToCorner,
  483.         iTopmost, pszYesNo[bLockPosition], pszYesNo[bSwap],
  484.         pszYesNo[bSwitchlistTitles], SB2_ColorName( iCellColor ),
  485.         pszYesNo[bFixedSize], iFixedSize );
  486.       SaveExceptions( f );
  487.       fprintf( f,
  488.         "[%s]\n"
  489.         "%s=%s\n"
  490.         "%s=%s\n"
  491.         "%s=%s\n\n",
  492.         pszOtherFltConfig[0],
  493.         pszOtherFltConfig[1], pszYesNo[bCheckPID],
  494.         pszOtherFltConfig[2], pszYesNo[bCheckVis],
  495.         pszOtherFltConfig[3], pszYesNo[bCheckJump] );
  496.       SB2_SaveFontCfg( szDescFontSection, &fatDesc, f );
  497.       fclose( f );
  498.     }
  499.   }
  500. }
  501.  
  502.  
  503. // Pop-up description window stuff and routines ------------------------------
  504. int iDescTask = -1;
  505.  
  506. void HideDescWindow( void )
  507. {
  508.   if ( iDescTask != -1 )
  509.   {
  510.     pTaskDesc->Hide();
  511.     iDescTask = -1;
  512.   }
  513. }
  514.  
  515.  
  516. static char szTaskTitle[256] = { 0 };
  517.  
  518. void AdjustDescPos( int x, int y )
  519. {
  520.   if ( x < iSwWrkLeft || x > iSwWrkRight || y < iSwWrkBottom ||
  521.     y > iSwWrkTop || bAlienMenu )
  522.   {
  523.     HideDescWindow();
  524.     return;
  525.   }
  526.   int i = ( ( iOrientation & 1 ) ?
  527.     ( y - iSwWrkBottom ) : ( x - iSwWrkLeft ) ) / iSwCellSize[iLarge];
  528.   if ( iOrientation == 1 || iOrientation == 2 )
  529.     i = iTaskCount - i - 1;
  530.   if ( i >= iTaskCount )
  531.   {
  532.     HideDescWindow();
  533.     return;
  534.   }
  535.   if ( i == iDescTask ) return;
  536.   iDescTask = i;
  537.  
  538.   szTaskTitle[0] = 0;
  539.   if ( ! bSwitchlistTitles ) WinQueryWindowText(
  540.     pTasks[iDescTask].swctl.hwnd, sizeof ( szTaskTitle ), szTaskTitle );
  541.   pTaskDesc->SetText(
  542.     szTaskTitle[0] ? szTaskTitle : pTasks[iDescTask].swctl.szSwtitle );
  543.   pTaskDesc->AdjustSize( &fatDesc, hwSwClient );
  544.   SWP swp;
  545.   WinQueryWindowPos( hwSwFrame, &swp );
  546.   x = y = 2;
  547.   int dx = 0, dy = 0;
  548.   switch ( iOrientation )
  549.   {
  550.     case 0:
  551.       x = 10;
  552.       dx = iSwCellSize[iLarge];
  553.       break;
  554.     case 1:
  555.       y = iSwWHeight - iSwCellSize[iLarge] - 10;
  556.       dy = -iSwCellSize[iLarge];
  557.       break;
  558.     case 2:
  559.       x = iSwWWidth - iSwCellSize[iLarge] - 10;
  560.       dx = -iSwCellSize[iLarge];
  561.       break;
  562.     case 3:
  563.       y = 10;
  564.       dy = iSwCellSize[iLarge];
  565.       break;
  566.   }
  567.   pTaskDesc->AdjustPos( x + swp.x + dx * iDescTask, y + swp.y + dy * iDescTask,
  568.     iSwCellSize[iLarge], iSwCellSize[iLarge], iOrientation & 1 );
  569. }
  570.  
  571. MRESULT EXPENTRY TaskDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  572.  
  573.  
  574. MRESULT EXPENTRY SwDescWinProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  575. {
  576.   switch ( msg )
  577.   {
  578.     case WM_PAINT:
  579.       pTaskDesc->Paint( &fatDesc, hwnd );
  580.       break;
  581.   
  582.     default:
  583.       return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  584.   }
  585.   return ( MRESULT ) FALSE;
  586. }
  587.  
  588. int iTasksToShow = 0;
  589.  
  590. // Main window shape creator -------------------------------------------------
  591. void ResizeSw( int _iNewCount, short int bResizeOnly = 1 )
  592. {
  593.   int iNewCount = bFixedSize ? iFixedSize : _iNewCount;
  594.   HideDescWindow();
  595.   SWP Swp;
  596.   WinQueryWindowPos( hwSwFrame, &Swp );
  597.   iSwWrkLeft = iSwWrkBottom = 2;
  598.   iSwWrkRight = iSwWrkTop = iSwCellSize[iLarge] + 1;
  599.   if ( iNewCount != iTasksToShow && ( Swp.x > 0 || Swp.y > 0 ) )
  600.     switch ( iOrientation )
  601.   {
  602.     case 1:
  603.       Swp.y -= ( iNewCount - iTasksToShow ) * iSwCellSize[iLarge];
  604.       break;
  605.     case 2:
  606.       Swp.x -= ( iNewCount - iTasksToShow ) * iSwCellSize[iLarge];
  607.       break;
  608.   }
  609.   if ( iOrientation & 1 )
  610.   {
  611.     iSwWWidth = iSwCellSize[iLarge] + 4;
  612.     iSwWHeight = iNewCount * iSwCellSize[iLarge] + 12;
  613.     if ( iOrientation == 3 ) iSwWrkBottom = 10;
  614.     iSwWrkTop = iSwWrkBottom + iNewCount * iSwCellSize[iLarge] - 1;
  615.   }
  616.   else
  617.   {
  618.     iSwWHeight = iSwCellSize[iLarge] + 4;
  619.     iSwWWidth = iNewCount * iSwCellSize[iLarge] + 12;
  620.     if ( iOrientation == 0 ) iSwWrkLeft = 10;
  621.     iSwWrkRight = iSwWrkLeft + iNewCount * iSwCellSize[iLarge] - 1;
  622.   }
  623.   iTasksToShow = iNewCount;
  624.   if ( ! bResizeOnly ) iTaskCount = _iNewCount;
  625.   WinSetWindowPos( hwSwFrame, HWND_TOP, Swp.x, Swp.y, iSwWWidth, iSwWHeight,
  626.     SWP_MOVE | SWP_SIZE | SWP_SHOW );
  627.   WinInvalidateRect( hwSwFrame, NULL, TRUE );
  628.  
  629.   WinSendMsg( hmPopupMenu, MM_DELETEITEM, MPFROM2SHORT(( USHORT) IDM_TASK, TRUE), ( MPARAM) NULL);
  630.   HWND hwndTaskMenu = WinCreateMenu( HWND_OBJECT, NULL);
  631.   WinSetWindowUShort( hwndTaskMenu, QWS_ID, IDM_TASK);
  632.   MENUITEM mi;
  633.   mi.iPosition = MIT_END;
  634.   mi.afStyle = MIS_TEXT | MIS_BITMAP;
  635.   mi.afAttribute = 0;
  636.   mi.hwndSubMenu = 0;
  637. //  mi.hItem = 0;
  638. //  mi.id = IDM_TASK + 1;
  639.   int iCount = iTasksToShow < iTaskCount ? iTasksToShow : iTaskCount;
  640.   for( int i = 0; i<iCount; i++) {
  641.     szTaskTitle[0] = 0;
  642.     if( !bSwitchlistTitles) WinQueryWindowText( pTasks[ i].swctl.hwnd, sizeof( szTaskTitle), szTaskTitle);
  643.     mi.id = IDM_TASK + 1 + i;
  644. //    if( pTasks[ i].swctl.hwndIcon) {
  645. //      mi.afStyle = MIS_TEXT | MIS_BITMAP;
  646. //      mi.hItem = pTasks[ i].swctl.hwndIcon;
  647. //    } else  {
  648.       mi.afStyle = MIS_TEXT;
  649.       mi.hItem = 0;
  650. //    }
  651.     WinSendMsg( hwndTaskMenu, MM_INSERTITEM, MPFROMP( &mi), szTaskTitle[ 0] ? szTaskTitle : pTasks[ i].swctl.szSwtitle);
  652.   }
  653.  
  654.   mi.afStyle = MIS_TEXT | MIS_SUBMENU;
  655.   mi.afAttribute = 0;
  656.   mi.hwndSubMenu = hwndTaskMenu;
  657.   mi.id = IDM_TASK;
  658.   mi.hItem = 0;
  659.   WinSendMsg( hmPopupMenu, MM_INSERTITEM, MPFROMP( &mi), "Tasks");
  660.  
  661. }
  662.  
  663.  
  664.  
  665. // Task list checker ---------------------------------------------------------
  666. void QueryTasks( void )
  667. {
  668.   int n = WinQuerySwitchList( hab, NULL, 0 );
  669.   int iSize = sizeof ( ULONG ) + n * ( sizeof ( SWENTRY ) );
  670.   PSWBLOCK pBlock = ( PSWBLOCK ) new char[iSize];
  671.   n = WinQuerySwitchList( hab, pBlock, iSize );
  672.   if ( n != iRealTaskCount || memcmp( pBlock, pRealTasks, iSize ) || bForceRescan )
  673.   {
  674.     bForceRescan = 0;
  675.     int iNewCount = 0;
  676.     delete pRealTasks;
  677.     pRealTasks = pBlock;
  678.     iRealTaskCount = n;
  679.     SWENTRY *pEntry = pRealTasks->aswentry;
  680.     for ( int i = 0; i < n; i++ )
  681.       if ( CheckExceptions( pEntry[i] ) ) iNewCount++;
  682.     delete pTasks;
  683.     pTasks = new SWENTRY[iNewCount];
  684.     SWENTRY *pNewEntry = &pTasks[iNewCount];
  685.     for ( i = 0; i < n; i++ ) if ( CheckExceptions( pEntry[i], 1 ) )
  686.     {
  687.       pNewEntry--;
  688.       *pNewEntry = pEntry[i];
  689.       if ( ! pNewEntry->swctl.hwndIcon ) pNewEntry->swctl.hwndIcon = ( HWND )
  690.         WinSendMsg( pNewEntry->swctl.hwnd, WM_QUERYICON, 0L, 0L );
  691.     }
  692.     ResizeSw( iNewCount, 0 );
  693.   }
  694.   else delete pBlock;
  695. }
  696.  
  697.  
  698. // Swich to task procedure ---------------------------------------------------
  699. void SwitchToTask( int n )
  700. {
  701.   SWP swp;
  702.   hwLastActive = pTasks[n].swctl.hwnd;
  703.   WinQueryWindowPos( pTasks[n].swctl.hwnd, &swp );
  704.   if ( swp.fl & SWP_HIDE ) WinSetWindowPos( pTasks[n].swctl.hwnd,
  705.     0, 0, 0, 0, 0, SWP_SHOW );
  706.   WinSwitchToProgram( pTasks[n].hswitch );
  707. }
  708.  
  709.  
  710. // About dialog window procedure ---------------------------------------------
  711. MRESULT EXPENTRY AboutDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  712. {
  713.   if ( msg == WM_INITDLG )
  714.   {
  715.     WinSetDlgItemText( hwnd, D_Version, SB2_Strings( iSB2S_Version ) );
  716.     WinSetDlgItemText( hwnd, D_Copyright, SB2_Strings( iSB2S_Copyright ) );
  717.     WinSetDlgItemText( hwnd, D_Email, SB2_Strings( iSB2S_Email ) );
  718.   }
  719.   return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  720. }
  721.  
  722.  
  723. void SetHexDecValue( char *pszBuf, ULONG uValue, HWND hw, ULONG uID )
  724. {
  725.   sprintf( pszBuf, "0x%08X (%i)", uValue, uValue );
  726.   WinSetDlgItemText( hw, uID, pszBuf );
  727. }
  728. void SetHexStrValue( char *pszBuf, ULONG uValue, char *pS, HWND hw, ULONG uID )
  729. {
  730.   sprintf( pszBuf, "0x%08X (%s)", uValue, pS );
  731.   WinSetDlgItemText( hw, uID, pszBuf );
  732. }
  733. char *pszProgTypes[] =
  734. {
  735.   "default",
  736.   "fullscreen",
  737.   "windowable VIO",
  738.   "PM application",
  739.   "VDM",
  740.   "group",
  741.   "DLL",
  742.   "widowed VDM",
  743.   "PDD",
  744.   "VDD",
  745.   "window - real mode",
  746.   "window - prot mode",
  747.   "window - auto",
  748.   "3.0 std seamless VDM",
  749.   "3.0 std seamless common",
  750.   "3.1 std seamless VDM",
  751.   "3.1 std seamless common",
  752.   "3.1 enh seamless VDM",
  753.   "3.1 enh seamless common",
  754.   "3.1 enhanced",
  755.   "3.1 standard"
  756. };
  757.  
  758. // Task control dialog procedures --------------------------------------------
  759. MRESULT EXPENTRY TaskDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  760. {
  761.   switch ( msg )
  762.   {
  763.     case WM_INITDLG:
  764.       WinSendDlgItemMsg( hwnd, D_Info_Icon, SM_SETHANDLE,
  765.         ( MPARAM ) pTasks[iCurrTask].swctl.hwndIcon, 0L );
  766.       WinSetDlgItemText( hwnd, D_Info_Title, pTasks[iCurrTask].swctl.szSwtitle );
  767.       {
  768.         char szBuf[128];
  769.         SetHexDecValue( szBuf, pTasks[iCurrTask].swctl.hwnd,
  770.           hwnd, D_Info_HWND1 );
  771.         SetHexDecValue( szBuf, pTasks[iCurrTask].swctl.hprog,
  772.           hwnd, D_Info_HPROG1 );
  773.         SetHexDecValue( szBuf, pTasks[iCurrTask].swctl.idProcess,
  774.           hwnd, D_Info_PID1 );
  775.         SetHexDecValue( szBuf, pTasks[iCurrTask].swctl.idSession,
  776.           hwnd, D_Info_SID1 );
  777.         char *pS = "";
  778.         switch ( pTasks[iCurrTask].swctl.uchVisibility )
  779.         {
  780.           case SWL_VISIBLE:
  781.             pS = "visible";
  782.             break;
  783.           case SWL_INVISIBLE:
  784.             pS = "invisible";
  785.             break;
  786.           case SWL_GRAYED:
  787.             pS = "grayed";
  788.             break;
  789.         }
  790.         SetHexStrValue( szBuf, pTasks[iCurrTask].swctl.uchVisibility, pS,
  791.           hwnd, D_Info_Vis1 );
  792.         switch ( pTasks[iCurrTask].swctl.fbJump )
  793.         {
  794.         case SWL_JUMPABLE:
  795.             pS = "jumpable";
  796.             break;
  797.           case SWL_NOTJUMPABLE:
  798.             pS = "not jumpable";
  799.             break;
  800.           default:
  801.             pS = "";
  802.             break;
  803.         }
  804.         SetHexStrValue( szBuf, pTasks[iCurrTask].swctl.fbJump, pS,
  805.           hwnd, D_Info_Jump1 );
  806.         ULONG ul = pTasks[iCurrTask].swctl.bProgType;
  807.         SetHexStrValue( szBuf, ul, ( ul < 20 ? pszProgTypes[ul] : "" ),
  808.           hwnd, D_Info_PType1 );
  809.       }
  810.       break;
  811.  
  812.     case WM_COMMAND:
  813.       {
  814.         int c = int ( mp1 );
  815.         switch ( c )
  816.         {
  817.           case DID_CANCEL:
  818.             WinSendDlgItemMsg( hwnd, D_Info_Icon, SM_SETHANDLE, 0L, 0L );
  819.             WinDismissDlg( hwnd, c );
  820.         }
  821.       }
  822.       break;
  823.  
  824.     case WM_CLOSE:
  825.       WinSendDlgItemMsg( hwnd, D_Info_Icon, SM_SETHANDLE, 0L, 0L );
  826.     
  827.     default:
  828.       return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  829.   }
  830.   return ( MRESULT ) FALSE;
  831. }
  832.  
  833.  
  834. const int iMaxAlienItems = 128;
  835. typedef struct
  836. {
  837.   ULONG ulID;
  838.   char bSysCommand;
  839. } AlienMenuItem;
  840. AlienMenuItem AlienItems[iMaxAlienItems];
  841. int iAlienItemCount = 0;
  842.  
  843. void StealMenu( HWND hMenu, void *pBuf )
  844. {
  845.  
  846.   MENUITEM miCopy = { MIT_END, MIS_SEPARATOR, 0, 0, 0, 0 };
  847.  
  848.   int iItemCount = ( int ) WinSendMsg( hMenu, MM_QUERYITEMCOUNT, 0, 0 );
  849.   for ( int i = 0; i < iItemCount; i++ )
  850.   {
  851.     int iID =
  852.       ( int ) WinSendMsg( hMenu, MM_ITEMIDFROMPOSITION, ( MPARAM ) i, 0 );
  853.     WinSendMsg( hMenu, MM_QUERYITEM, MPFROM2SHORT( iID, TRUE ),
  854.       ( MPARAM ) pBuf );
  855.     PMENUITEM pMenu = ( PMENUITEM ) pBuf;
  856.     miCopy.id = 0;
  857.     miCopy.afAttribute = 0;
  858.  
  859.     if ( pMenu->afStyle & MIS_SEPARATOR )
  860.     {
  861.       if ( ! ( miCopy.afStyle & MIS_SEPARATOR ) )
  862.       {
  863.         miCopy.afStyle = pMenu->afStyle;
  864.         miCopy.id = pMenu->id;
  865.         WinSendMsg( hmTaskMenu, MM_INSERTITEM, &miCopy, NULL );
  866.       }
  867.     }
  868.     else if ( pMenu->afStyle & MIS_SUBMENU )
  869.     {
  870.       if ( ! ( miCopy.afStyle & MIS_SEPARATOR ) )
  871.       {
  872.         miCopy.afStyle = MIS_SEPARATOR;
  873.         WinSendMsg( hmTaskMenu, MM_INSERTITEM, &miCopy, NULL );
  874.       }
  875.       miCopy.id = pMenu->id;
  876.       miCopy.afStyle = MIS_STATIC;
  877.       miCopy.afAttribute = pMenu->afAttribute;
  878.       WinSendMsg( hMenu, MM_QUERYITEMTEXT, MPFROM2SHORT( iID, 512 ),
  879.         ( MPARAM ) pBuf );
  880.       WinSendMsg( hmTaskMenu, MM_INSERTITEM, &miCopy, pBuf );
  881.       StealMenu( pMenu->hwndSubMenu, pBuf );
  882.       miCopy.afStyle = MIS_SUBMENU;
  883.     }
  884.     else if ( pMenu->afStyle & ( MIS_TEXT | MIS_STATIC ) )
  885.     {
  886.       if ( miCopy.afStyle & MIS_SUBMENU )
  887.       {
  888.         miCopy.afStyle = MIS_SEPARATOR;
  889.         WinSendMsg( hmTaskMenu, MM_INSERTITEM, &miCopy, NULL );
  890.       }
  891.       miCopy.afStyle = pMenu->afStyle & ~MIS_SYSCOMMAND;
  892.       miCopy.afAttribute = pMenu->afAttribute;
  893.       if ( pMenu->afStyle & MIS_TEXT )
  894.       {
  895.         if ( iAlienItemCount >= iMaxAlienItems ) continue;
  896.         AlienItems[iAlienItemCount].ulID = pMenu->id;
  897.         AlienItems[iAlienItemCount].bSysCommand =
  898.           ( pMenu->afStyle & MIS_SYSCOMMAND ? 1 : 0 );
  899.         miCopy.id = MNU_SW_ALIEN0 + iAlienItemCount++;
  900.       }
  901.       else miCopy.id = pMenu->id;
  902.       WinSendMsg( hMenu, MM_QUERYITEMTEXT, MPFROM2SHORT( iID, 512 ),
  903.         ( MPARAM ) pBuf );
  904.       WinSendMsg( hmTaskMenu, MM_INSERTITEM, &miCopy, pBuf );
  905.     }
  906.   }
  907. }
  908.  
  909. void TaskControlDlg( int i, int x, int y )
  910. {
  911.   iCurrTask = i;
  912.  
  913.   int iItemCount = ( int ) WinSendMsg( hmTaskMenu, MM_QUERYITEMCOUNT, 0, 0 );
  914.   for ( int j = iItemCount - 1; j > 2; j-- )
  915.   {
  916.     int iID = ( int ) WinSendMsg( hmTaskMenu, MM_ITEMIDFROMPOSITION,
  917.       ( MPARAM ) j, 0 );
  918.     WinSendMsg( hmTaskMenu, MM_REMOVEITEM, MPFROM2SHORT( iID, TRUE ), 0 );
  919.   }
  920.  
  921.   HWND hmSysMenu = WinWindowFromID( pTasks[i].swctl.hwnd, FID_SYSMENU );
  922.   if ( hmSysMenu )
  923.   {
  924.     PVOID pMem;
  925.     APIRET rc = DosAllocSharedMem( &pMem, NULL, 512,
  926.       PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE );
  927.     if ( ! rc )
  928.     {
  929.       TID tid;
  930.       PID pid;
  931.       WinQueryWindowProcess( pTasks[i].swctl.hwnd, &pid, &tid );
  932.       rc = DosGiveSharedMem( pMem, pid, PAG_READ | PAG_WRITE );
  933.       MENUITEM *mi1 = ( MENUITEM * ) pMem;
  934.       WinSendMsg( hmSysMenu, MM_QUERYITEM,
  935.         MPFROM2SHORT( SC_SYSMENU, TRUE ), ( MPARAM ) mi1 );
  936.       iAlienItemCount = 0;
  937.       if ( mi1->hwndSubMenu ) StealMenu( mi1->hwndSubMenu, pMem );
  938.       DosFreeMem( pMem );
  939.     }
  940.   }
  941.   else
  942.   {
  943.     MENUITEM mi = { MIT_END, MIS_TEXT, 0, MNU_SW_TSK_CLOSE, 0, 0 };
  944.     WinSendMsg( hmTaskMenu, MM_INSERTITEM, &mi, "~Close" );
  945.   }
  946.   bAlienMenu = 1;
  947.   i = FindExceptionIndex( pTasks[i].swctl.szSwtitle );
  948.   WinEnableMenuItem( hmTaskMenu, MNU_SW_EXC_EDIT, i > -1 );
  949.   WinEnableMenuItem( hmTaskMenu, MNU_SW_EXC_REMOVE, i > -1 );
  950.   WinPopupMenu( hwSwFrame, hwSwFrame,
  951.     hmTaskMenu, x, y, 0, PU_HCONSTRAIN | PU_VCONSTRAIN | PU_NONE |
  952.     PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2 );
  953. }
  954.  
  955.  
  956. // More task control routines ------------------------------------------------
  957. int iTaskToSwitch = -1;
  958.  
  959.  
  960. int DetermineTask( int x, int y )
  961. {
  962.   int i = ( ( iOrientation & 1 ) ? ( y - iSwWrkBottom ) :
  963.     ( x - iSwWrkLeft ) ) / iSwCellSize[iLarge];
  964.   if ( iOrientation == 1 || iOrientation == 2 ) i = iTaskCount - i - 1;
  965.   return i;
  966. }
  967.  
  968. void CloseTask( int iTask )
  969. {
  970.   if ( pTasks[iTask].swctl.bProgType == PROG_PM )
  971.     WinPostMsg( pTasks[iTask].swctl.hwnd, WM_CLOSE, 0L, 0L );
  972.   else WinPostMsg( pTasks[iTask].swctl.hwnd, WM_SYSCOMMAND,
  973.     ( MPARAM ) SC_CLOSE, MPFROM2SHORT( CMDSRC_MENU, TRUE ) );
  974. }
  975.  
  976. /*
  977. void GoToTask( int x, int y )
  978. {
  979.   int i = ( ( iOrientation & 1 ) ? ( y - iSwWrkBottom ) :
  980.     ( x - iSwWrkLeft ) ) / iSwCellSize[iLarge];
  981.   if ( iOrientation == 1 || iOrientation == 2 ) i = iTaskCount - i - 1;
  982.   iTaskToSwitch = i;
  983.   i = WinQuerySysValue( HWND_DESKTOP, SV_DBLCLKTIME );
  984.   WinStartTimer( hab, hwSwClient, TID_USERMAX + 10, i );
  985. }
  986. */
  987.  
  988. void MinimizeTask( int iTask )
  989. {
  990. /*
  991.   iTaskToSwitch = -1;
  992.   WinStopTimer( hab, hwSwClient, TID_USERMAX + 10 );
  993.   int x = SHORT1FROMMP( mp1 ),
  994.     y = SHORT2FROMMP( mp1 );
  995.   if ( x >= iSwWrkLeft && x <= iSwWrkRight &&
  996.     y >= iSwWrkBottom && y <= iSwWrkTop )
  997.   {
  998.     int i = ( ( iOrientation & 1 ) ? ( y - iSwWrkBottom ) :
  999.       ( x - iSwWrkLeft ) ) / iSwCellSize[iLarge];
  1000.     if ( iOrientation == 1 || iOrientation == 2 ) i = iTaskCount - i - 1;
  1001.   */
  1002.     WinPostMsg( pTasks[iTask].swctl.hwnd, WM_SYSCOMMAND,
  1003.       ( MPARAM ) SC_MINIMIZE, MPFROM2SHORT( CMDSRC_MENU, TRUE ) );
  1004.  
  1005. //  }
  1006. }
  1007.  
  1008.  
  1009. static HWND hwDlgToUpdate = NULL;
  1010. void UpdateSettingsDlg( void )
  1011. {
  1012.   if ( hwDlgToUpdate )
  1013.   {
  1014.     WinSendDlgItemMsg( hwDlgToUpdate, D_Bind_Off + iBindToCorner, BM_SETCHECK,
  1015.       ( MPARAM ) 1, 0 );
  1016.     WinSendDlgItemMsg( hwDlgToUpdate, D_Grow_East + iOrientation, BM_SETCHECK,
  1017.       ( MPARAM ) 1, 0 );
  1018.     WinSendDlgItemMsg( hwDlgToUpdate, D_Lock_Position, BM_SETCHECK,
  1019.       ( MPARAM ) bLockPosition, 0 );
  1020.   }
  1021. }
  1022.  
  1023. // Display settings dialog window procedure ----------------------------------
  1024. MRESULT EXPENTRY SettingsDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  1025. {
  1026.   switch ( msg )
  1027.   {
  1028.     case WM_INITDLG:
  1029.       {
  1030.         hwDlgToUpdate = hwnd;
  1031.         WinSendDlgItemMsg( hwnd, D_Size_Size, SPBM_SETLIMITS,
  1032.           ( MPARAM ) 128, ( MPARAM ) iSwCellSize[3] );
  1033.         WinSendDlgItemMsg( hwnd, D_Size_Size, SPBM_SETLIMITS,
  1034.           ( MPARAM ) 128, ( MPARAM ) 8 );
  1035.         WinSendDlgItemMsg( hwnd, D_Display_None + iTopmost, BM_SETCHECK,
  1036.           ( MPARAM ) 1, 0 );
  1037.         WinSendDlgItemMsg( hwnd, D_Size_Small + iLarge, BM_SETCHECK,
  1038.           ( MPARAM ) 1, 0 );
  1039.         UpdateSettingsDlg();
  1040.       }
  1041.       break;
  1042.  
  1043.     case WM_COMMAND:
  1044.       break;
  1045.  
  1046.     case WM_CONTROL:
  1047.       switch ( SHORT1FROMMP( mp1 ) )
  1048.       {
  1049.         case D_Lock_Position:
  1050.           if ( bLockPosition != ( int ) WinSendDlgItemMsg( hwnd,
  1051.             D_Lock_Position, BM_QUERYCHECK, 0, 0 ) ) WinPostMsg( hwSwClient,
  1052.             WM_COMMAND, ( MPARAM ) ( MNU_SW_LOCKPOSITION ), 0 );
  1053.           break;
  1054.         case D_Grow_North:
  1055.         case D_Grow_East:
  1056.         case D_Grow_South:
  1057.         case D_Grow_West:
  1058.           {
  1059.             int s = ( int ) WinSendDlgItemMsg( hwnd, D_Grow_East,
  1060.               BM_QUERYCHECKINDEX, 0, 0 );
  1061.             if ( ( s & 3 ) == s ) WinPostMsg( hwSwClient, WM_COMMAND,
  1062.               ( MPARAM ) ( MNU_SW_ORNT_EAST + s ), 0 );
  1063.           }
  1064.           break;
  1065.         case D_Display_None:
  1066.         case D_Display_OnTop:
  1067.         case D_Display_Popup:
  1068.         case D_Display_Popup2:
  1069.           {
  1070.             int s = ( int ) WinSendDlgItemMsg( hwnd, D_Display_None,
  1071.               BM_QUERYCHECKINDEX, 0, 0 );
  1072.             if ( ( s & 3 ) == s ) WinPostMsg( hwSwClient, WM_COMMAND,
  1073.               ( MPARAM ) ( MNU_SW_NOTOP + s ), 0 );
  1074.           }
  1075.           break;
  1076.         case D_Bind_Off:
  1077.         case D_Bind_NW:
  1078.         case D_Bind_NE:
  1079.         case D_Bind_SW:
  1080.         case D_Bind_SE:
  1081.           {
  1082.             int s = ( int ) WinSendDlgItemMsg( hwnd, D_Bind_Off,
  1083.               BM_QUERYCHECKINDEX, 0, 0 );
  1084.             if ( s >= 0 && s <= 4 ) WinPostMsg( hwSwClient, WM_COMMAND,
  1085.               ( MPARAM ) ( MNU_SW_BIND_OFF + s ), 0 );
  1086.           }
  1087.           break;
  1088.         case D_Size_Small:
  1089.         case D_Size_Large:
  1090.         case D_Size_Fit:
  1091.         case D_Size_Custom:
  1092.           {
  1093.             int s = ( int ) WinSendDlgItemMsg( hwnd, D_Size_Small,
  1094.               BM_QUERYCHECKINDEX, 0, 0 );
  1095.             if ( ( s & 3 ) == s ) WinPostMsg( hwSwClient, WM_COMMAND,
  1096.               ( MPARAM ) ( MNU_SW_SMALL + s ), 0 );
  1097.           }
  1098.           break;
  1099.         case D_Size_Size:
  1100.           {
  1101.             long lValue;
  1102.             WinSendDlgItemMsg( hwnd, D_Size_Size, SPBM_QUERYVALUE, &lValue, 0 );
  1103.             if ( iSwCellSize[3] != lValue )
  1104.             {
  1105.               iSwCellSize[3] = lValue;
  1106.               if ( iLarge == 3 ) WinPostMsg( hwSwClient, WM_COMMAND,
  1107.                 ( MPARAM ) ( MNU_SW_CUSTOM ), 0 );
  1108.             }
  1109.           }
  1110.           break;
  1111.       }
  1112.       break;
  1113.     default:
  1114.       return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  1115.   }
  1116.   return ( MRESULT ) FALSE;
  1117. }
  1118.  
  1119. // Display settings dialog window procedure ----------------------------------
  1120. MRESULT EXPENTRY Settings2DlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  1121. {
  1122.   switch ( msg )
  1123.   {
  1124.     case WM_INITDLG:
  1125.       {
  1126.         hwDlgToUpdate = hwnd;
  1127.         WinSendDlgItemMsg( hwnd, D_Fixed_Size, SPBM_SETLIMITS,
  1128.           ( MPARAM ) 128, ( MPARAM ) iFixedSize );
  1129.         WinSendDlgItemMsg( hwnd, D_Fixed_Size, SPBM_SETLIMITS,
  1130.           ( MPARAM ) 128, ( MPARAM ) 1 );
  1131.         WinSendDlgItemMsg( hwnd, D_Mouse_Swap, BM_SETCHECK,
  1132.           ( MPARAM ) bSwap, 0 );
  1133.         WinSendDlgItemMsg( hwnd, D_Switchlist_Titles, BM_SETCHECK,
  1134.           ( MPARAM ) bSwitchlistTitles, 0 );
  1135.         WinSendDlgItemMsg( hwnd, D_Fixed_SizeX, BM_SETCHECK,
  1136.           ( MPARAM ) bFixedSize, 0 );
  1137.         SB2_FillColorList( hwnd, D_Cell_Color, iCellColor );
  1138.       }
  1139.       break;
  1140.  
  1141.     case WM_COMMAND:
  1142.       switch ( SHORT1FROMMP( mp1 ) )
  1143.       {
  1144.         case D_Font_Settings:
  1145.           {
  1146.             HWND hwFontDlg = WinFontDlg( HWND_DESKTOP, hwnd, &fd );
  1147.             if ( hwFontDlg && ( fd.lReturn == DID_OK ) ) fatDesc = fd.fAttrs;
  1148.           }
  1149.           break;
  1150.       }
  1151.       break;
  1152.  
  1153.     case WM_CONTROL:
  1154.       switch ( SHORT1FROMMP( mp1 ) )
  1155.       {
  1156.         case D_Mouse_Swap:
  1157.           if ( bSwap != ( int ) WinSendDlgItemMsg( hwnd, D_Mouse_Swap,
  1158.             BM_QUERYCHECK, 0, 0 ) ) WinPostMsg( hwSwClient, WM_COMMAND,
  1159.             ( MPARAM ) ( MNU_SW_SWAPBUTTONS ), 0 );
  1160.           break;
  1161.         case D_Switchlist_Titles:
  1162.           if ( bSwitchlistTitles != ( int ) WinSendDlgItemMsg( hwnd,
  1163.             D_Switchlist_Titles, BM_QUERYCHECK, 0, 0 ) ) WinPostMsg( hwSwClient,
  1164.             WM_COMMAND, ( MPARAM ) ( MNU_SW_SWITCHLISTTITLES ), 0 );
  1165.           break;
  1166.         case D_Fixed_SizeX:
  1167.           if ( bFixedSize != ( int ) WinSendDlgItemMsg( hwnd,
  1168.             D_Fixed_SizeX, BM_QUERYCHECK, 0, 0 ) ) WinPostMsg( hwSwClient,
  1169.             WM_COMMAND, ( MPARAM ) ( MNU_SW_FIXED_SIZE ), 0 );
  1170.           break;
  1171.         case D_Fixed_Size:
  1172.           {
  1173.             long lValue;
  1174.             WinSendDlgItemMsg( hwnd, D_Fixed_Size, SPBM_QUERYVALUE, &lValue, 0 );
  1175.             if ( iFixedSize != lValue )
  1176.             {
  1177.               iFixedSize = lValue;
  1178.               if ( bFixedSize ) WinPostMsg( hwSwClient, WM_COMMAND,
  1179.                 ( MPARAM ) ( MNU_SW_RESIZE ), 0 );
  1180.             }
  1181.           }
  1182.           break;
  1183.         case D_Cell_Color:
  1184.           if ( SHORT2FROMMP( mp1 ) == LN_SELECT )
  1185.           {
  1186.             iCellColor = ( int ) WinSendDlgItemMsg( hwnd, D_Cell_Color,
  1187.               LM_QUERYSELECTION, ( MPARAM ) LIT_CURSOR, ( MPARAM ) 0 );
  1188.             WinInvalidateRect( hwSwFrame, NULL, TRUE );
  1189.           }
  1190.           break;
  1191.       }
  1192.       break;
  1193.     default:
  1194.       return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  1195.   }
  1196.   return ( MRESULT ) FALSE;
  1197. }
  1198.  
  1199. void EnableListButtons( HWND hwnd )
  1200. {
  1201.   int bEnable = ( iExceptionCount > 0 );
  1202.   WinEnableControl( hwnd, D_Filter_Edit, bEnable );
  1203.   WinEnableControl( hwnd, D_Filter_Clone, bEnable );
  1204.   WinEnableControl( hwnd, D_Filter_Remove, bEnable );
  1205. }
  1206.  
  1207. // Other filters dialog window procedure ----------------------------------
  1208. MRESULT EXPENTRY OtherFltDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  1209. {
  1210.   char szTemp[iMaxFilterString];
  1211.  
  1212.   switch ( msg )
  1213.   {
  1214.     case WM_INITDLG:
  1215.       {
  1216.         hwDlgToUpdate = hwnd;
  1217.         WinSendDlgItemMsg( hwnd, D_Filter_Enable, BM_SETCHECK,
  1218.           ( MPARAM ) bExceptionsEnabled, 0 );
  1219.         WinSendDlgItemMsg( hwnd, D_Check_PID, BM_SETCHECK,
  1220.           ( MPARAM ) bCheckPID, 0 );
  1221.         WinSendDlgItemMsg( hwnd, D_Check_Vis, BM_SETCHECK,
  1222.           ( MPARAM ) bCheckVis, 0 );
  1223.         WinSendDlgItemMsg( hwnd, D_Check_Jump, BM_SETCHECK,
  1224.           ( MPARAM ) bCheckJump, 0 );
  1225.         FillExceptionList( hwnd, D_Filter_List );
  1226.         EnableListButtons( hwnd );
  1227.       }
  1228.       break;
  1229.  
  1230.     case WM_COMMAND:
  1231.       {
  1232.         int i = ( int ) WinSendDlgItemMsg( hwnd, D_Filter_List,
  1233.           LM_QUERYSELECTION, ( MPARAM ) LIT_CURSOR, ( MPARAM ) 0 );
  1234.         if ( i == LIT_NONE && SHORT1FROMMP( mp1 ) != D_Filter_New ) break;
  1235.  
  1236.         switch ( SHORT1FROMMP( mp1 ) )
  1237.         {
  1238.           case D_Filter_New:
  1239.           case D_Filter_Clone:
  1240.             if ( SHORT1FROMMP( mp1 ) == D_Filter_New )
  1241.               memset( &TempException, 0, sizeof ( WinFilterEntry ) );
  1242.             else TempException = pExceptions[i];
  1243.             i = -1;
  1244.           case D_Filter_Edit:
  1245.             if ( EditException( hwnd, i ) )
  1246.               FillExceptionList( hwnd, D_Filter_List );
  1247.             break;
  1248.  
  1249.           case D_Filter_Remove:
  1250.             RemoveException( i );
  1251.             WinSendDlgItemMsg( hwnd, D_Filter_List, LM_DELETEITEM,
  1252.               ( MPARAM ) i, ( MPARAM ) 0 );
  1253.             if ( iExceptionCount ) WinSendDlgItemMsg( hwnd, D_Filter_List,
  1254.               LM_SELECTITEM, ( MPARAM ) 0, ( MPARAM ) 1 );
  1255.             break;
  1256.         }
  1257.         EnableListButtons( hwnd );
  1258.       }
  1259.       break;
  1260.  
  1261.     case WM_CONTROL:
  1262.       switch ( SHORT1FROMMP( mp1 ) )
  1263.       {
  1264.         case D_Filter_Enable:
  1265.           bExceptionsEnabled = ( int ) WinSendDlgItemMsg( hwnd,
  1266.             D_Filter_Enable, BM_QUERYCHECK, 0, 0 );
  1267.           bForceRescan = 1;
  1268.           break;
  1269.         case D_Check_PID:
  1270.           if ( bCheckPID != ( int ) WinSendDlgItemMsg( hwnd, D_Check_PID,
  1271.             BM_QUERYCHECK, 0, 0 ) ) WinPostMsg( hwSwClient, WM_COMMAND,
  1272.             ( MPARAM ) ( MNU_SW_CHECK_PID ), 0 );
  1273.           bForceRescan = 1;
  1274.           break;
  1275.         case D_Check_Vis:
  1276.           if ( bCheckVis != ( int ) WinSendDlgItemMsg( hwnd, D_Check_Vis,
  1277.             BM_QUERYCHECK, 0, 0 ) ) WinPostMsg( hwSwClient, WM_COMMAND,
  1278.             ( MPARAM ) ( MNU_SW_CHECK_VIS ), 0 );
  1279.           bForceRescan = 1;
  1280.           break;
  1281.         case D_Check_Jump:
  1282.           if ( bCheckJump != ( int ) WinSendDlgItemMsg( hwnd, D_Check_Jump,
  1283.             BM_QUERYCHECK, 0, 0 ) ) WinPostMsg( hwSwClient, WM_COMMAND,
  1284.             ( MPARAM ) ( MNU_SW_CHECK_JUMP ), 0 );
  1285.           bForceRescan = 1;
  1286.           break;
  1287.       }
  1288.       break;
  1289.  
  1290.     default:
  1291.       return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  1292.   }
  1293.   return ( MRESULT ) FALSE;
  1294. }
  1295.  
  1296.  
  1297. // Main properties dialog window procedure -----------------------------------
  1298. MRESULT EXPENTRY PropertiesDlgProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  1299. {
  1300.   static short int bInit = 1;
  1301.   static ULONG ulAboutPage;
  1302.   static ULONG ulFilterPage;
  1303.   static ULONG ulSettingsPage;
  1304.   static ULONG ulSettings2Page;
  1305.   static HWND hwSettingsDlg = NULL;
  1306.   static HWND hwSettings2Dlg = NULL;
  1307.   static HWND hwFilterDlg = NULL;
  1308.   static HWND hwAboutDlg = NULL;
  1309.  
  1310.   switch ( msg )
  1311.   {
  1312.     case WM_INITDLG:
  1313.       if ( mp2 )
  1314.       {
  1315.         WinSetWindowText( hwnd, "SysBar/2 Task Switcher - Properties" );
  1316.         WinSendDlgItemMsg( hwnd, D_Prop_Notebook, BKM_SETNOTEBOOKCOLORS,
  1317.           MPFROMLONG( SYSCLR_DIALOGBACKGROUND ),
  1318.           MPFROMLONG( BKA_BACKGROUNDPAGECOLORINDEX ) );
  1319.         HWND hwNotebook = WinWindowFromID( hwnd, D_Prop_Notebook );
  1320.  
  1321.         ulSettingsPage = SB2_AddDlgPage( hwnd, D_Prop_Notebook, "Display",
  1322.           "Appearance settings (page 1 of 2)" );
  1323.         hwSettingsDlg = WinLoadDlg( hwNotebook, hwNotebook, SettingsDlgProc,
  1324.           ( HMODULE ) 0, DLG_SETTINGS, NULL );
  1325.         WinSendDlgItemMsg( hwnd, D_Prop_Notebook, BKM_SETPAGEWINDOWHWND,
  1326.           ( MPARAM ) ulSettingsPage, ( MPARAM ) hwSettingsDlg );
  1327.  
  1328.         ulSettings2Page = ( ULONG ) WinSendDlgItemMsg( hwnd, D_Prop_Notebook,
  1329.           BKM_INSERTPAGE, ( MPARAM ) NULL, MPFROM2SHORT( ( BKA_MINOR |
  1330.           BKA_STATUSTEXTON | BKA_AUTOPAGESIZE ), BKA_LAST ) );
  1331.         WinSendMsg( hwNotebook, BKM_SETSTATUSLINETEXT, ( MPARAM ) ulSettings2Page,
  1332.           MPFROMP ( "Other display options (page 2 of 2)" ) );
  1333.         hwSettings2Dlg = WinLoadDlg( hwNotebook, hwNotebook, Settings2DlgProc,
  1334.           ( HMODULE ) 0, DLG_SETTINGS2, NULL );
  1335.         WinSendMsg( hwNotebook, BKM_SETPAGEWINDOWHWND,
  1336.           ( MPARAM ) ulSettings2Page, ( MPARAM ) hwSettings2Dlg );
  1337.  
  1338.         ulFilterPage = SB2_AddDlgPage( hwnd, D_Prop_Notebook, "Filters",
  1339.           "Filters and exceptions" );
  1340.         hwFilterDlg = WinLoadDlg( hwNotebook, hwNotebook, OtherFltDlgProc,
  1341.           ( HMODULE ) 0, DLG_FLT_OTHER, NULL );
  1342.         WinSendMsg( hwNotebook, BKM_SETPAGEWINDOWHWND,
  1343.           ( MPARAM ) ulFilterPage, ( MPARAM ) hwFilterDlg );
  1344.  
  1345.         ulAboutPage = SB2_AddDlgPage( hwnd, D_Prop_Notebook, "About",
  1346.           "About SysBar/2 Task Switcher" );
  1347.         hwAboutDlg = WinLoadDlg( hwNotebook, hwNotebook, AboutDlgProc,
  1348.           ( HMODULE ) 0, DLG_ABOUT, NULL );
  1349.         WinSendDlgItemMsg( hwnd, D_Prop_Notebook, BKM_SETPAGEWINDOWHWND,
  1350.           ( MPARAM ) ulAboutPage, ( MPARAM ) hwAboutDlg );
  1351.  
  1352.         WinSendDlgItemMsg( hwnd, D_Prop_Notebook, BKM_SETDIMENSIONS,
  1353.           MPFROM2SHORT ( 21, 21 ), MPFROMSHORT ( BKA_PAGEBUTTON ) );
  1354.         WinSendDlgItemMsg( hwnd, D_Prop_Notebook, BKM_SETDIMENSIONS,
  1355.           MPFROM2SHORT ( 80, 20 ), MPFROMSHORT ( BKA_MAJORTAB ) );
  1356.         WinSendDlgItemMsg( hwnd, D_Prop_Notebook, BKM_SETDIMENSIONS,
  1357.           MPFROM2SHORT ( 0, 0 ), MPFROMSHORT ( BKA_MINORTAB ) );
  1358.       }
  1359.       break;
  1360. /*
  1361.     case WM_COMMAND:
  1362.       switch ( SHORT1FROMMP( mp1 ) )
  1363.       {
  1364.         case DID_OK:
  1365.         case DID_CANCEL:
  1366.           WinDismissDlg( hwnd, SHORT1FROMMP( mp1 ) );
  1367.           break;
  1368.         default:
  1369.           return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  1370.       }
  1371.       break;
  1372. */
  1373.     case WM_CLOSE:
  1374.       hwDlgToUpdate = NULL;
  1375.       WinDestroyWindow( hwSettingsDlg );
  1376.       WinDestroyWindow( hwSettings2Dlg );
  1377.       WinDestroyWindow( hwFilterDlg );
  1378.       WinDestroyWindow( hwAboutDlg );
  1379.       WinPostMsg( hwSwClient, WM_COMMAND, ( MPARAM ) MNU_SW_SAVE, 0 );
  1380.     default:
  1381.       return WinDefDlgProc( hwnd, msg, mp1, mp2 );
  1382.   }
  1383.   return ( MRESULT ) FALSE;
  1384. }
  1385.  
  1386.  
  1387. HWND hwPrevWindow = HWND_DESKTOP;
  1388.  
  1389. void PopUpMainWindow( void )
  1390. {
  1391.   if ( iTopmost >= 2 ) hwPrevWindow = WinQueryWindow( hwSwFrame, QW_PREV );
  1392.   WinSetWindowPos( hwSwFrame, HWND_TOP, 0L, 0L, 0L, 0L, SWP_ZORDER | SWP_SHOW );
  1393.   bLastVisible = 1;
  1394. }
  1395.  
  1396. static ULONG ulOldMsg = 0;
  1397.  
  1398.  
  1399. // Main window procedure -----------------------------------------------------
  1400. MRESULT EXPENTRY SwWinProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  1401. {
  1402.   switch ( msg )
  1403.   {
  1404.     case WM_CREATE:
  1405.       {
  1406.         HPS hps = WinGetPS( hwnd );
  1407.         hbQ = GpiLoadBitmap( hps, NULLHANDLE, BMP_Q, 20, 20 );
  1408.         WinReleasePS( hps );
  1409.  
  1410.         hMemDC = DevOpenDC( hab, OD_MEMORY, "*", 0, NULL, NULLHANDLE );
  1411.         SIZEL sizel = { 0, 0 };
  1412.         hMemPS = GpiCreatePS( hab, hMemDC, &sizel,
  1413.           PU_PELS | GPIF_LONG | GPIT_NORMAL | GPIA_ASSOC );
  1414.         GpiAssociate( hMemPS, hMemDC );
  1415.         BITMAPINFOHEADER2 bmih;  
  1416.         memset( &bmih, 0, sizeof ( BITMAPINFOHEADER2 ) );
  1417.         bmih.cbFix = sizeof ( BITMAPINFOHEADER2 );
  1418.         bmih.cx = bmih.cy = WinQuerySysValue( HWND_DESKTOP, SV_CXICON ) + 2;
  1419.         bmih.cPlanes = 1;
  1420.         bmih.cBitCount = 8;
  1421.         hbMem = GpiCreateBitmap( hMemPS, &bmih, 0L, NULL, NULL );
  1422.         GpiSetBitmap( hMemPS, hbMem );
  1423.  
  1424.         hmPopupMenu = WinLoadMenu( hwnd, NULLHANDLE, MNU_SW );
  1425.         hmTaskMenu = WinLoadMenu( hwnd, NULLHANDLE, MNU_SW_TSK_MENU );
  1426.         MENUITEM mi;
  1427.         WinSendMsg( hmTaskMenu, MM_QUERYITEM,
  1428.           MPFROM2SHORT( MNU_SW_EXC, TRUE ), MPFROMP( &mi ) );
  1429.         ULONG ulStyle = WinQueryWindowULong( mi.hwndSubMenu, QWL_STYLE );
  1430.         WinSetWindowULong( mi.hwndSubMenu, QWL_STYLE, ulStyle |
  1431.           MS_CONDITIONALCASCADE );
  1432.  
  1433.         WinStartTimer( hab, hwnd, TID_USERMAX + 9, 1000 );
  1434.       }
  1435.       break;
  1436.  
  1437.     case WM_MENUEND:
  1438.       bAlienMenu = 0;
  1439.       break;
  1440.  
  1441.     case WM_COMMAND:
  1442.       {
  1443.         USHORT uCommand = SHORT1FROMMP( mp1 );
  1444.         HideDescWindow();
  1445. /*
  1446.         if ( bAlienMenu )
  1447.         {
  1448.           bAlienMenu = 0;
  1449.           WinPostMsg( pTasks[iCurrTask].swctl.hwnd, WM_SYSCOMMAND,
  1450.             ( MPARAM ) uCommand, MPFROM2SHORT( CMDSRC_MENU, TRUE ) );
  1451.           iCurrTask = -1;
  1452.         }
  1453.         else
  1454. */
  1455.         switch ( uCommand )
  1456.         {
  1457.           case MNU_SW_SAVE:
  1458.             SaveOptions();
  1459.             break;
  1460.           case MNU_SW_PROPERTIES:
  1461.             WinDlgBox( HWND_DESKTOP, hwSwFrame, PropertiesDlgProc,
  1462.               hmSysBar2Dll, DLG_PROPERTIES, ( PVOID ) &DummyInit );
  1463.             break;
  1464.           case MNU_SW_CLOSE:
  1465.             WinPostMsg( hwSwFrame, WM_CLOSE, 0, 0 );
  1466.             break;
  1467.  
  1468.           case MNU_SW_NOTOP:
  1469.           case MNU_SW_TOPMOST:
  1470.           case MNU_SW_POPUP:
  1471.           case MNU_SW_POPUP2:
  1472.             iTopmost = uCommand - MNU_SW_NOTOP;
  1473.             break;
  1474.           case MNU_SW_SMALL:
  1475.           case MNU_SW_LARGE:
  1476.           case MNU_SW_FITICONS:
  1477.           case MNU_SW_CUSTOM:
  1478.             iLarge = uCommand - int ( MNU_SW_SMALL );
  1479.             if ( iLarge == 2 )
  1480.               iSwCellSize[2] = WinQuerySysValue( HWND_DESKTOP, SV_CXICON ) + 4;
  1481.             ResizeSw( iTaskCount );
  1482.             if ( iBindToCorner ) WinPostMsg( hwnd, WM_COMMAND,
  1483.               ( MPARAM ) ( MNU_SW_BIND_OFF + iBindToCorner ), 0 );
  1484.             break;
  1485.           case MNU_SW_LOCKPOSITION:
  1486.             bLockPosition ^= 1;
  1487.             break;
  1488.           case MNU_SW_SWAPBUTTONS:
  1489.             bSwap ^= 1;
  1490.             break;
  1491.           case MNU_SW_FIXED_SIZE:
  1492.             bFixedSize ^= 1;
  1493.           case MNU_SW_RESIZE:
  1494.             ResizeSw( iTaskCount );
  1495.             break;
  1496.           case MNU_SW_SWITCHLISTTITLES:
  1497.             bSwitchlistTitles ^= 1;
  1498.             break;
  1499.           case MNU_SW_BIND_OFF:
  1500.           case MNU_SW_BIND_NW:
  1501.           case MNU_SW_BIND_NE:
  1502.           case MNU_SW_BIND_SW:
  1503.           case MNU_SW_BIND_SE:
  1504.             if ( ( iBindToCorner = uCommand - MNU_SW_BIND_OFF ) > 0 )
  1505.             {
  1506.               int x = -1;
  1507.               int y = -1;
  1508.               if ( iBindToCorner == 1 || iBindToCorner == 2 )
  1509.                 y = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) -
  1510.                   iSwWHeight + 1;
  1511.               if ( iBindToCorner == 2 || iBindToCorner == 4 )
  1512.                 x = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ) -
  1513.                   iSwWWidth + 1;
  1514.               WinSetWindowPos( hwSwFrame, HWND_TOP, x, y, 0, 0, SWP_MOVE );
  1515.  
  1516.               int iNewOrientation = iOrientation;
  1517.               switch ( iBindToCorner )
  1518.               {
  1519.                 case 1:
  1520.                   iNewOrientation = iOrientation & 1;
  1521.                   break;
  1522.                 case 2:
  1523.                   iNewOrientation = ( iOrientation & 1 ) ? 1 : 2;
  1524.                   break;
  1525.                 case 3:
  1526.                   iNewOrientation = ( iOrientation & 1 ) ? 3 : 0;
  1527.                   break;
  1528.                 case 4:
  1529.                   iNewOrientation = iOrientation | 2;
  1530.                   break;
  1531.               }
  1532.               if ( iNewOrientation != iOrientation )
  1533.                 WinPostMsg( hwSwClient, WM_COMMAND,
  1534.                   ( MPARAM ) ( MNU_SW_ORNT_EAST + iNewOrientation ), 0 );
  1535.             }
  1536.             break;
  1537.  
  1538.           case MNU_SW_ORNT_EAST:
  1539.           case MNU_SW_ORNT_SOUTH:
  1540.           case MNU_SW_ORNT_WEST:
  1541.           case MNU_SW_ORNT_NORTH:
  1542.             iOrientation = int ( uCommand ) - MNU_SW_ORIENTATION - 1;
  1543.             ResizeSw( iTaskCount );
  1544.             UpdateSettingsDlg();
  1545.             if ( iBindToCorner ) WinPostMsg( hwnd, WM_COMMAND,
  1546.               ( MPARAM ) ( MNU_SW_BIND_OFF + iBindToCorner ), 0 );
  1547.             break;
  1548.  
  1549.           case MNU_SW_TSK_CLOSE:
  1550.             CloseTask( iCurrTask );
  1551.             break;
  1552.           case MNU_SW_EXC_CREATE:
  1553.             memset( &TempException, 0, sizeof ( WinFilterEntry ) );
  1554.             strcpy( TempException.szText, pTasks[iCurrTask].swctl.szSwtitle );
  1555.           case MNU_SW_EXC_EDIT:
  1556.             {
  1557.               int i = -1;
  1558.               if ( uCommand == MNU_SW_EXC_EDIT )
  1559.                 i = FindExceptionIndex( pTasks[iCurrTask].swctl.szSwtitle );
  1560.               EditException( hwnd, i );
  1561.               bForceRescan = 1;
  1562.             }
  1563.             break;
  1564.           case MNU_SW_EXC_REMOVE:
  1565.             {
  1566.               int i = FindExceptionIndex( pTasks[iCurrTask].swctl.szSwtitle );
  1567.               if ( i != -1 ) RemoveException( i );
  1568.             }
  1569.             break;
  1570. //          case MNU_SW_TSK_HIDE:
  1571. //            HideFilter.AddString( pTasks[iCurrTask].swctl.szSwtitle );
  1572. //            break;
  1573. //          case MNU_SW_TSK_SHOW:
  1574. //            ShowFilter.AddString( pTasks[iCurrTask].swctl.szSwtitle );
  1575. //            break;
  1576.           case MNU_SW_TSK_INFO:
  1577.             WinDlgBox( HWND_DESKTOP, hwSwFrame, TaskDlgProc,
  1578.               NULLHANDLE, DLG_TASK, NULL );
  1579.             break;
  1580.  
  1581.           case MNU_SW_CHECK_PID:
  1582.             bCheckPID ^= 1;
  1583.             break;
  1584.           case MNU_SW_CHECK_VIS:
  1585.             bCheckVis ^= 1;
  1586.             break;
  1587.           case MNU_SW_CHECK_JUMP:
  1588.             bCheckJump ^= 1;
  1589.             break;
  1590.  
  1591.           default:
  1592.             if ( uCommand >= MNU_SW_ALIEN0 && uCommand <= MNU_SW_ALIEN1 &&
  1593.               iCurrTask >= 0 ) WinPostMsg( pTasks[iCurrTask].swctl.hwnd,
  1594.               AlienItems[uCommand - MNU_SW_ALIEN0].bSysCommand ? WM_SYSCOMMAND :
  1595.               WM_COMMAND, ( MPARAM ) AlienItems[uCommand - MNU_SW_ALIEN0].ulID,
  1596.               MPFROM2SHORT( CMDSRC_MENU, TRUE ) );
  1597.             break;
  1598.         }
  1599.         iCurrTask = -1;
  1600.       }
  1601.       break;
  1602.  
  1603.     case WM_BUTTON1DOWN:
  1604.       {
  1605.         HideDescWindow();
  1606.         int x = SHORT1FROMMP( mp1 ),
  1607.           y = SHORT2FROMMP( mp1 );
  1608.         if ( ( x < iSwWrkLeft || x > iSwWrkRight ||
  1609.           y < iSwWrkBottom || y > iSwWrkTop || bAlienMenu ) && ! bLockPosition )
  1610.           WinPostMsg( hwSwFrame, WM_TRACKFRAME, ( MPARAM ) TF_MOVE, 0L );
  1611.         else return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  1612.       }
  1613.       break;
  1614.  
  1615.     case WM_BUTTON1UP:
  1616.     case WM_BUTTON2UP:
  1617.       if ( ulOldMsg == msg ) ulOldMsg = 0;
  1618.       else
  1619.       {
  1620.         HideDescWindow();
  1621.         short int bWhich = ( msg == WM_BUTTON2UP );
  1622.         int x = SHORT1FROMMP( mp1 ),
  1623.           y = SHORT2FROMMP( mp1 );
  1624.         if ( x >= iSwWrkLeft && x <= iSwWrkRight &&
  1625.           y >= iSwWrkBottom && y <= iSwWrkTop && ! bAlienMenu )
  1626.         {
  1627.           LONG lState = 0x8000 &
  1628.             WinGetKeyState( HWND_DESKTOP, bWhich ? VK_BUTTON1 : VK_BUTTON2 );
  1629.           if ( lState ) ulOldMsg = bWhich ? WM_BUTTON1UP : WM_BUTTON2UP;
  1630.           int iTask = DetermineTask( x, y );
  1631.           if ( bSwap ^ bWhich )
  1632.           {
  1633.             if ( lState ) MinimizeTask( iTask );
  1634.             else TaskControlDlg( iTask, x, y );
  1635.           }
  1636.           else
  1637.           {
  1638.             if ( lState ) CloseTask( iTask );
  1639.             else if ( hwLastActive == pTasks[iTask].swctl.hwnd )
  1640.             {
  1641.               MinimizeTask( iTask );
  1642.               hwLastActive = NULLHANDLE;
  1643.             }
  1644.             else SwitchToTask( iTask );
  1645.           }
  1646.         }
  1647.         else if ( bWhich ) WinPopupMenu( hwnd, hwnd, hmPopupMenu, x, y, 0,
  1648.           PU_HCONSTRAIN | PU_VCONSTRAIN | PU_NONE |
  1649.           PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2 );
  1650.       }
  1651.       break;
  1652. /*
  1653.     case WM_BUTTON2CLICK:
  1654.       {
  1655.         HideDescWindow();
  1656.         int x = SHORT1FROMMP( mp1 ),
  1657.           y = SHORT2FROMMP( mp1 );
  1658.         if ( x >= iSwWrkLeft && x <= iSwWrkRight &&
  1659.           y >= iSwWrkBottom && y <= iSwWrkTop )
  1660.         {
  1661.           if ( bSwap ) GoToTask( x, y );
  1662.           else TaskControlDlg( x, y );
  1663.         }
  1664.         else WinPopupMenu( hwnd, hwnd, hmPopupMenu, x, y, 0,
  1665.           PU_HCONSTRAIN | PU_VCONSTRAIN | PU_NONE |
  1666.           PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2 );
  1667.       }
  1668.       break;
  1669. */
  1670. /*
  1671.     case WM_BUTTON2DBLCLK:
  1672.       if ( bSwap ) MinimizeTask( mp1 );
  1673.       break;
  1674.  
  1675.     case WM_BUTTON1DBLCLK:
  1676.       if ( ! bSwap ) MinimizeTask( mp1 );
  1677.       break;
  1678. */
  1679.  
  1680.     case WM_TIMER:
  1681.       switch ( SHORT1FROMMP( mp1 ) )
  1682.       {
  1683.         case TID_USERMAX + 9:
  1684.           if ( ! bAlienMenu )
  1685.           {
  1686.             QueryTasks();
  1687.             HWND hwActive = WinQueryActiveWindow( HWND_DESKTOP );
  1688.             if ( hwActive != hwSwFrame && hwActive != hwSwClient )
  1689.               hwLastActive = hwActive;
  1690.           }
  1691.           
  1692.           {
  1693.             SWP swp;
  1694.             WinQueryWindowPos( hwSwFrame, &swp );
  1695.             POINTL ptl = { 0, 0 };
  1696.             WinQueryPointerPos( HWND_DESKTOP, &ptl );
  1697.             ptl.x -= swp.x;
  1698.             ptl.y -= swp.y;
  1699.             AdjustDescPos( ptl.x, ptl.y );
  1700.  
  1701.             short int bOnTop = iTopmost;
  1702.  
  1703.             if ( iTopmost >= 2 )
  1704.             {
  1705.               SWP swp;
  1706.               WinQueryWindowPos( hwSwFrame, &swp );
  1707.               POINTL ptl = { 0, 0 };
  1708.               WinQueryPointerPos( HWND_DESKTOP, &ptl );
  1709.               ptl.x -= swp.x;
  1710.               ptl.y -= swp.y;
  1711.               if ( ptl.x >= 0 && ptl.y >= 0 &&
  1712.                 ptl.x < iSwWWidth && ptl.y < iSwWHeight )
  1713.               {
  1714.                 if ( ! bLastVisible ) bLastVisible = bOnTop = 1;
  1715.               }
  1716.               else if ( bLastVisible )
  1717.               {
  1718.                 if ( iTopmost == 3 ) WinSetWindowPos( hwSwFrame, hwPrevWindow,
  1719.                   0L, 0L, 0L, 0L, SWP_ZORDER );
  1720.                 bLastVisible = 0;
  1721.               }
  1722.             }
  1723.     
  1724.             if ( bOnTop == 1 ) PopUpMainWindow();
  1725.           }
  1726.           break;
  1727. /*
  1728.         case TID_USERMAX + 10:
  1729.           WinStopTimer( hab, hwnd, TID_USERMAX + 10 );
  1730.           if ( iTaskToSwitch != -1 )
  1731.           {
  1732.             SwitchToTask( iTaskToSwitch );
  1733.             iTaskToSwitch = -1;
  1734.           }
  1735.           break;
  1736. */
  1737.       }
  1738.       break;
  1739.  
  1740.     case WM_ERASEBACKGROUND:
  1741.       {
  1742.         bClearIt = 1;
  1743. /*
  1744.         HPS hps = ( HPS ) ( mp1 );
  1745.         if ( iTaskCount )
  1746.         {
  1747.           SB2_Border( hps, 0, 0, iSwWWidth - 1, iSwWHeight - 1, 1, 
  1748.             SB2c_Filler, 1 );
  1749.           int x = 2, y = 2, dx = 0, dy = 0;
  1750.           switch ( iOrientation )
  1751.           {
  1752.             case 0:
  1753.               x = 10;
  1754.               dx = iSwCellSize[iLarge];
  1755.               break;
  1756.             case 1:
  1757.               y = iSwWHeight - iSwCellSize[iLarge] - 10;
  1758.               dy = -iSwCellSize[iLarge];
  1759.               break;
  1760.             case 2:
  1761.               x = iSwWWidth - iSwCellSize[iLarge] - 10;
  1762.               dx = -iSwCellSize[iLarge];
  1763.               break;
  1764.             case 3:
  1765.               y = 10;
  1766.               dy = iSwCellSize[iLarge];
  1767.               break;
  1768.           }
  1769.           for ( int i = 0; i < iTaskCount; i++ )
  1770.           {
  1771.             SB2_Border( hps, x, y, x + iSwCellSize[iLarge] - 1,
  1772.               y + iSwCellSize[iLarge] - 1, 0, CLR_BLACK );
  1773.             x += dx;
  1774.             y += dy;
  1775.           }
  1776.         }
  1777. */
  1778.       }
  1779.       break;
  1780.  
  1781.     case WM_PAINT:
  1782.       {
  1783.         HPS hps;
  1784.         RECTL rc;
  1785.         hps = WinBeginPaint( hwnd, 0L, &rc );
  1786.  
  1787.         int iColor = SB2_ColorValue( iCellColor );
  1788.         int iCount = iTasksToShow < iTaskCount ? iTasksToShow : iTaskCount;
  1789.         if ( bClearIt )
  1790.         {
  1791.           bClearIt = 0;
  1792.           SB2_Border( hps, 0, 0, iSwWWidth - 1, iSwWHeight - 1, 1,
  1793.             SB2c_Filler, 1 );
  1794.           int x = 2, y = 2, dx = 0, dy = 0;
  1795.           switch ( iOrientation )
  1796.           {
  1797.             case 0:
  1798.               x = 10;
  1799.               dx = iSwCellSize[iLarge];
  1800.               break;
  1801.             case 1:
  1802.               y = iSwWHeight - iSwCellSize[iLarge] - 10;
  1803.               dy = -iSwCellSize[iLarge];
  1804.               break;
  1805.             case 2:
  1806.               x = iSwWWidth - iSwCellSize[iLarge] - 10;
  1807.               dx = -iSwCellSize[iLarge];
  1808.               break;
  1809.             case 3:
  1810.               y = 10;
  1811.               dy = iSwCellSize[iLarge];
  1812.               break;
  1813.           }
  1814.           for ( int i = 0; i < iCount; i++ )
  1815.           {
  1816.             SB2_Border( hps, x, y, x + iSwCellSize[iLarge] - 1,
  1817.               y + iSwCellSize[iLarge] - 1, 0, iColor );
  1818.             x += dx;
  1819.             y += dy;
  1820.           }
  1821.         }
  1822.  
  1823.         int x = 3, y = 3, dx = 0, dy = 0;
  1824.         switch ( iOrientation )
  1825.         {
  1826.           case 0:
  1827.             x = 11;
  1828.             dx = iSwCellSize[iLarge];
  1829.             break;
  1830.           case 1:
  1831.             y = iSwWHeight - iSwCellSize[iLarge] - 9;
  1832.             dy = -iSwCellSize[iLarge];
  1833.             break;
  1834.           case 2:
  1835.             x = iSwWWidth - iSwCellSize[iLarge] - 9;
  1836.             dx = -iSwCellSize[iLarge];
  1837.             break;
  1838.           case 3:
  1839.             y = 11;
  1840.             dy = iSwCellSize[iLarge];
  1841.             break;
  1842.         }
  1843.         for ( int i = 0; i < iCount; i++ )
  1844.         {
  1845.           POINTL pt4[4];
  1846.           pt4[0].x = x + 1;
  1847.           pt4[0].y = y + 1;
  1848.           pt4[1].x = x + iSwCellSize[iLarge] - 3;
  1849.           pt4[1].y = y + iSwCellSize[iLarge] - 3;
  1850.  
  1851.           int iSize = WinQuerySysValue( HWND_DESKTOP, SV_CXICON );
  1852.           RECTL re = { 0, 0, iSize + 2, iSize + 2 };
  1853.           WinFillRect( hMemPS, &re, iColor );
  1854.           if ( pTasks[i].swctl.hwndIcon )
  1855.           {
  1856.             ULONG ulOption = DP_NORMAL;
  1857.             if ( ( iSwCellSize[iLarge] * 5 ) < ( iSize * 4 ) )
  1858.             {
  1859.               pt4[0].x++;
  1860.               pt4[0].y++;
  1861.               pt4[1].x--;
  1862.               pt4[1].y--;
  1863.               iSize >>= 1;
  1864.               ulOption = 0x0004;
  1865.             }
  1866.             WinDrawPointer( hMemPS, 0, 0, pTasks[i].swctl.hwndIcon, ulOption );
  1867.           }
  1868.           else
  1869.           {
  1870.             if ( iSize > iSwCellSize[iLarge] - 4 ) iSize = iSwCellSize[iLarge] - 4;
  1871.             int iOffset = ( iSize - 20 ) >> 1;
  1872.             POINTL p4[4] = { { iOffset, iOffset },
  1873.               { iOffset + 19, iOffset + 19 }, { 0, 0 }, { 20, 20 } };
  1874.             GpiWCBitBlt( hMemPS, hbQ, 4L, p4, ROP_SRCPAINT, BBO_IGNORE );
  1875.           }
  1876.           pt4[2].x = 0;
  1877.           pt4[2].y = 0;
  1878.           pt4[3].x = iSize;
  1879.           pt4[3].y = iSize;
  1880.           GpiBitBlt( hps, hMemPS, 4L, pt4, ROP_SRCCOPY, BBO_IGNORE );
  1881.           x += dx;
  1882.           y += dy;
  1883.         }
  1884.         WinEndPaint( hps );
  1885.       }
  1886.       break;
  1887.  
  1888.     case WM_CLOSE:
  1889.       HideDescWindow();
  1890.       SaveOptions();
  1891.       WinPostMsg( hwnd, WM_QUIT, 0, 0 );
  1892.       break;
  1893.  
  1894.     case WM_DESTROY:
  1895.       WinStopTimer( hab, hwnd, TID_USERMAX + 9 );
  1896.       delete pTasks;
  1897.       delete pRealTasks;
  1898.       GpiDeleteBitmap( hbQ );
  1899.       GpiDeleteBitmap( hbMem );
  1900.       GpiDestroyPS( hMemPS );
  1901.       DevCloseDC( hMemDC );
  1902.       break;
  1903.  
  1904.     case WM_MOUSEMOVE:
  1905.       if ( iTopmost >= 2 && ! bLastVisible ) PopUpMainWindow();
  1906.       AdjustDescPos( SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) );
  1907.     
  1908.     default:
  1909.       return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  1910.   }
  1911.   return ( MRESULT ) FALSE;
  1912. }
  1913.  
  1914.  
  1915. // main() :) -----------------------------------------------------------------
  1916. int main( int argc, char *argv[] )
  1917. {
  1918.   HMQ hmq;
  1919.   QMSG qmsg;
  1920.   char szClassName[] = "SysBar2SwClass";
  1921.   char szDescClassName[] = "SysBar2SwDescClass";
  1922.  
  1923.   memset( &fd, 0, sizeof ( FONTDLG ) );
  1924.   fd.cbSize = sizeof ( FONTDLG );
  1925.   fd.pszFamilyname = szFamilyname;
  1926.   fd.usFamilyBufLen = sizeof ( szFamilyname );
  1927.   fd.fl = FNTS_BITMAPONLY | FNTS_CENTER | FNTS_INITFROMFATTRS;
  1928.   fd.clrFore = CLR_WHITE;
  1929.   fd.clrBack = CLR_DARKGRAY;
  1930.  
  1931.   if ( ( hab = WinInitialize( 0 ) ) == 0L ) AbortStartup();
  1932.   if ( ( hmq = WinCreateMsgQueue( hab, 0 ) ) == 0L ) AbortStartup();
  1933.  
  1934.   hmSysBar2Dll = SB2_Init();
  1935.   iCellColor = SB2_ColorCount() - 1;
  1936.  
  1937.   if ( ! WinRegisterClass( hab, ( PSZ ) szClassName, 
  1938.     ( PFNWP ) SwWinProc, 0L, 0 ) ) AbortStartup();
  1939.   if ( ! WinRegisterClass( hab, ( PSZ ) szDescClassName,
  1940.     ( PFNWP ) SwDescWinProc, CS_SIZEREDRAW, 0 ) ) AbortStartup();
  1941.  
  1942.   if ( argc > 1 ) pszIniFile = argv[1];
  1943.   else
  1944.   {
  1945.     pszIniFile = new char[strlen( argv[0] ) + 1];
  1946.     SB2_CfgFilename( pszIniFile, argv[0] );
  1947.   }
  1948.  
  1949.   ULONG ulWinStyle = FCF_AUTOICON | FCF_ICON | FCF_NOBYTEALIGN | FCF_TASKLIST;
  1950.  
  1951.   if ( ( hwSwFrame = WinCreateStdWindow( HWND_DESKTOP, 0, &ulWinStyle,
  1952.     szClassName, 0, 0, NULLHANDLE, ICO_MAIN, &hwSwClient ) ) == 0L )
  1953.     AbortStartup();
  1954.  
  1955.   if ( ! ( pTaskDesc = new DescWindow ) ) AbortStartup();
  1956.   else if ( ! pTaskDesc->CreateWindow( szDescClassName ) ) AbortStartup();
  1957.  
  1958.   WinSetWindowText( hwSwFrame, "SysBar/2 Task Switcher" );
  1959.  
  1960.   iSwCellSize[2] = WinQuerySysValue( HWND_DESKTOP, SV_CXICON ) + 4;
  1961.  
  1962.   {
  1963.     IniFile *pCfg = new IniFile( pszIniFile );
  1964.     int x = 0, y = 0, s = 0;
  1965.     if ( pCfg && ( *pCfg )() )
  1966.     {
  1967.       x = atoi2( pCfg->Get( szSysBar2Sw, "x" ) );
  1968.       y = atoi2( pCfg->Get( szSysBar2Sw, "y" ) );
  1969.       if ( ( s = atoi2( pCfg->Get( szSysBar2Sw, "customsize" ) ) ) > 0 )
  1970.         iSwCellSize[3] = s;
  1971.       iLarge = atoi2( pCfg->Get( szSysBar2Sw, "size" ) ) & 3;
  1972.       iBindToCorner = atoi2( pCfg->Get( szSysBar2Sw, "cornerbind" ) );
  1973.       if ( iBindToCorner > 4 || iBindToCorner < 0 ) iBindToCorner = 0;
  1974.       iOrientation = atoi2( pCfg->Get( szSysBar2Sw, "orientation" ) ) & 3;
  1975.       iTopmost = atoi2( pCfg->Get( szSysBar2Sw, "topmost" ) ) & 3;
  1976.       bLockPosition = ( strcmp2(
  1977.         pCfg->Get( szSysBar2Sw, "lockposition" ), pszYesNo[1] ) == 0 );
  1978.       bSwap = ( strcmp2(
  1979.         pCfg->Get( szSysBar2Sw, "swapbuttons" ), pszYesNo[1] ) == 0 );
  1980.       bSwitchlistTitles = ( strcmp2(
  1981.         pCfg->Get( szSysBar2Sw, "switchlisttitles" ), pszYesNo[1] ) == 0 );
  1982.       bFixedSize = ( strcmp2(
  1983.         pCfg->Get( szSysBar2Sw, "fixedsize" ), pszYesNo[1] ) == 0 );
  1984.       iFixedSize = atoi2( pCfg->Get( szSysBar2Sw, "fixedcells" ) ) & 255;
  1985.       char* p = pCfg->Get( szSysBar2Sw, "cellcolor" );
  1986.       if ( p ) iCellColor = SB2_ColorA2I( p );
  1987.       LoadExceptions( pCfg );
  1988.       bCheckPID = ( strcmp2( pCfg->Get( pszOtherFltConfig[0],
  1989.         pszOtherFltConfig[1] ), pszYesNo[1], 0 ) == 0 );
  1990.       bCheckVis = ( strcmp2( pCfg->Get( pszOtherFltConfig[0],
  1991.         pszOtherFltConfig[2] ), pszYesNo[1], 0 ) == 0 );
  1992.       bCheckJump = ( strcmp2( pCfg->Get( pszOtherFltConfig[0],
  1993.         pszOtherFltConfig[3] ), pszYesNo[1], 0 ) == 0 );
  1994.     }
  1995.     SB2_LoadFontCfg( szDescFontSection, &fatDesc, pCfg );
  1996.     delete pCfg;
  1997.     fd.fAttrs = fatDesc;
  1998.     if ( ! WinSetWindowPos( hwSwFrame, HWND_TOP, x, y, 0, 0, SWP_MOVE ) )
  1999.       AbortStartup();
  2000.     else
  2001.     {
  2002.       QueryTasks();
  2003.       WinPostMsg( hwSwFrame, WM_COMMAND,
  2004.         ( MPARAM ) ( MNU_SW_BIND_OFF + iBindToCorner ), 0L );
  2005.     }
  2006.   }
  2007.  
  2008.   while( WinGetMsg( hab, &qmsg, 0L, 0, 0 ) ) WinDispatchMsg( hab, &qmsg );
  2009.  
  2010.   SB2_Over();
  2011.  
  2012.   delete pTaskDesc;
  2013.   WinDestroyWindow( hwSwFrame );
  2014.   WinDestroyMsgQueue( hmq );
  2015.   WinTerminate( hab );
  2016.  
  2017.   if ( argc == 1 ) delete pszIniFile;
  2018.  
  2019.   return 0;
  2020. }
  2021.  
  2022.