Hi,

Recently one of our customers reported bug in Terminal software. After tracing it down it seems that the actuall problem lays in xHarbour/Harbour implementation of the hb_gt_win_SetMode() / gtwin.c

SetConsoleWindow API function cannot set console window larger then current screen buffer SetConsoleScreenBufferSize API function cannot set screen buffer smaller than the current console window size

Due to this limitations, in current implementation SetMode() is unable to change console size if one ot the new dimentions is larger then the previous one and at the same time the other one is smaller then the previous one. For instance, having console 25 X 80, SetMode( 23, 85 ) will fail.

Below my suggested fix for this problem. I have no access to CVS, so would be nice if somebody familiar with gtwin.c review and implement the solution.

Regards,
Jacek

/* fixed version */
static BOOL hb_gt_win_SetMode( PHB_GT pGT, int iRows, int iCols )
{
 BOOL fRet = FALSE;

HB_TRACE(HB_TR_DEBUG, ("hb_gt_win_SetMode(%p,%d,%d)", pGT, iRows, iCols));

 if( s_HOutput != INVALID_HANDLE_VALUE && iRows > 0 && iCols > 0 )
 {
    SMALL_RECT srWin;
    COORD coBuf;

    coBuf = GetLargestConsoleWindowSize( s_HOutput );

    if( iRows > coBuf.Y )
       iRows = coBuf.Y;
    else
       coBuf.Y = ( SHORT ) iRows;

    if( iCols > coBuf.X )
       iCols = coBuf.X;
    else
       coBuf.X = ( SHORT ) iCols;

    /* new console window size and scroll position */
    srWin.Top    = srWin.Left = 0;
    srWin.Bottom = ( SHORT ) ( iRows - 1 );
    srWin.Right  = ( SHORT ) ( iCols - 1 );

    /* if the current buffer is larger than what we want, resize the */
    /* console window first, then the buffer */
if( (DWORD)_GetScreenWidth() >= (DWORD)iCols && (DWORD)_GetScreenHeight() >= (DWORD)iRows )
    {
       if( SetConsoleWindowInfo( s_HOutput, TRUE, &srWin ) )
       {
          SetConsoleScreenBufferSize( s_HOutput, coBuf );
          fRet = TRUE;
       }
    }
    else
    /* if the current buffer is smaller than what we want, enlarge the */
    /* buffer first, then adjust the console window  */
if( (DWORD)_GetScreenWidth() <= (DWORD)iCols && (DWORD)_GetScreenHeight() <= (DWORD)iRows )
    {
       if( SetConsoleScreenBufferSize( s_HOutput, coBuf ) )
       {
          SetConsoleWindowInfo( s_HOutput, TRUE, &srWin );
          fRet = TRUE;
       }
    }
    else
    {
/* if one buffer dimention has changed to smaller and second to larger we need three steps: */ /* 1) Make console window as small as possible (so that new buffer dimention is not smaller) */ /* 2) Set the right console buffer size (it will be not smaller then console window set in step 1.*/
      /* 3) Adjust the console window to match screen buffer size */

      SMALL_RECT srWin;
      srTemp.Top    = srTemp.Left = 0;
srTemp.Bottom = ( SHORT ) ((DWORD)iRows < (DWORD)_GetScreenHeight() ? iRows : _GetScreenHeight()) - 1; srTemp.Right = ( SHORT ) ( (DWORD)iCols < (DWORD)_GetScreenWidth() ? iCols : _GetScreenWidth()) - 1;
      if( SetConsoleWindowInfo( s_HOutput, TRUE, &srTemp ) )
      {
          if( SetConsoleScreenBufferSize( s_HOutput, coBuf ) )
          {
              SetConsoleWindowInfo( s_HOutput, TRUE, &srWin );
              fRet = TRUE;
          }
      }
    }

    if( fRet )
       hb_gt_win_xInitScreenParam( pGT );
 }

 return fRet;
}


_______________________________________________
Harbour mailing list (attachment size limit: 40KB)
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to