Professional UI Solutions
Site Map   /  Register
 
 

Forum

Please Log In to post a new message or reply to an existing one. If you are not registered, please register.

NOTE: Some forums may be read-only if you are not currently subscribed to our technical support services.

Forums » Prof-UIS Tech Support » Scroll bar bug Collapse All
Subject Author Date
David Skok Jul 8, 2008 - 2:33 PM

Scroll bar controls (up,down,thumb) do not work in ScrollItemWnd children (eg. any grid control)


when the left/right mouse buttons are swapped in windows control panel.  That is, the mouse can no longer be used to drag the thumb control or clicked on the up/down in the scroll bars.  Keyboard still works of course.


 

Technical Support Jul 9, 2008 - 12:42 PM

Thank you for reporting this issue. It is fixed. Please update the source code for the following method:

void CExtScrollBar::ScrollBar_TrackMouseLButtonDown(
      MSG * pMSG
      )
{
      ASSERT_VALID( this );
      if( ! m_bCompleteRepaint )
            return;
CPoint point( short(LOWORD(DWORD(pMSG->lParam))), short(HIWORD(DWORD(pMSG->lParam))) );
CExtPopupMenuTipWnd * pATTW =
            OnAdvancedPopupMenuTipWndGet();
CExtPaintManager::PAINTSCROLLBARDATA _psbd( this );
      _psbd.AdjustHT( point );
      if(         (! m_bProcessingHover)
            ||    m_bProcessingClick
            ||    (! _psbd.m_bEnabled )
            ||    _psbd.m_eSBMHT == CExtPaintManager::__ESBMHT_NOWHERE
            )
      {
            if(         _psbd.m_eSBMHT == CExtPaintManager::__ESBMHT_NOWHERE
                  ||    (! _psbd.m_bEnabled )
                  )
            {
                  if( pATTW != NULL )
                        pATTW->Hide();
                  SendMessage( WM_CANCELMODE );
                  Invalidate();
                  UpdateWindow();
                  return;
            }
      }
      if( ! m_bPopupInactiveLightMode )
            ActivateTopParent();
bool bAnimationLocked = AnimationClient_CacheGeneratorIsLocked();
      if( ! bAnimationLocked )
      {
            AnimationClient_CacheGeneratorLock();
            AnimationClient_CacheNextStateMinInfo( false, __EAPT_BY_PRESSED_STATE_TURNED_ON );
      }
      if( m_bEnableHookSpy )
            HookSpyUnregister();
      m_nSBMHT = INT(_psbd.m_eSBMHT);
      m_bProcessingClick = m_bProcessingHover = true;
      m_bProcessingOutClick = false;
      if( ! bAnimationLocked )
      {
            AnimationClient_CacheNextStateMinInfo( true, __EAPT_BY_PRESSED_STATE_TURNED_ON );
            AnimationClient_CacheGeneratorUnlock();
      }
      Invalidate();
      UpdateWindow();
      if( pATTW != NULL )
            OnAdvancedPopupMenuTipWndDisplay( *pATTW, m_nSBMHT, true );
INT nScrollPosStart = _psbd.m_DSI.nPos, nScrollPos = _psbd.m_DSI.nPos;
      m_nHelperTrackPos = _psbd.m_DSI.nPos;
      m_bHelperHaveTrackPos = true;
CRect rcArea = _psbd.GetAreaRectHT();
const UINT nTimerID_zero_start = 401;
const UINT nTimerID_1st_slow = 402;
const UINT nTimerEllapse_1st_slow = 400;
const UINT nTimerID_2nd_fast = 403;
const UINT nTimerEllapse_2nd_fast = 100;
HWND hWndOwn = GetSafeHwnd();
      ASSERT( hWndOwn != NULL && ::IsWindow( hWndOwn ) );
HWND hWndParent = ::GetParent( hWndOwn );
bool bVirtualMode = false, bFinalNotify = true;
#if (!defined __EXT_MFC_NO_SCROLLWND)
CExtScrollWnd * pExtScrollWnd = NULL;
      if( hWndParent != NULL )
      {
            CWnd * pWndParentPermanent = CWnd::FromHandlePermanent( hWndParent );
            if( pWndParentPermanent != NULL )
            {
                  pExtScrollWnd = DYNAMIC_DOWNCAST( CExtScrollWnd, pWndParentPermanent );
#if (!defined __EXT_MFC_NO_SCROLLITEMWND)
                  if( pExtScrollWnd != NULL )
                  {
                        CExtScrollItemWnd * pExtScrollItemWnd = DYNAMIC_DOWNCAST( CExtScrollItemWnd, pWndParentPermanent );
                        if( pExtScrollItemWnd != NULL )
                        {
                              DWORD dwScrollType = __ESIW_ST_NONE;
                              if( _psbd.m_bHorzBar )
                                    dwScrollType = pExtScrollItemWnd->SiwScrollTypeHGet();
                              else
                                    dwScrollType = pExtScrollItemWnd->SiwScrollTypeVGet();
                              if( dwScrollType == __ESIW_ST_VIRTUAL )
                                    bVirtualMode = true;
                        }
                  }
#endif
            }
      }
#endif
bool bStopFlag = false;
CPoint ptCursor( point );
INT nStepSize = 0L;
bool bUpStep = false;
bool bMouseButtonsNotSwapped = ( ::GetSystemMetrics( SM_SWAPBUTTON ) != 0 ) ? false : true;
      switch( _psbd.m_eSBMHT )
      {
      case CExtPaintManager::__ESBMHT_BUTTON_UP:
            bUpStep = true;
            // continue falling here ...
      case CExtPaintManager::__ESBMHT_BUTTON_DOWN:
            nStepSize = GetStepSize();
#if (!defined __EXT_MFC_NO_SCROLLWND)
            if( pExtScrollWnd != NULL )
            {
                  int nDir = ( _psbd.m_eSBMHT == CExtPaintManager::__ESBMHT_BUTTON_DOWN ) ? (-1) : 1;
                  CSize _size = pExtScrollWnd->OnSwGetLineSize( nDir );
                  nStepSize = _psbd.m_bHorzBar ? _size.cx : _size.cy;
                  if( nStepSize <= 0L )
                        nStepSize = GetStepSize();
            }
#endif
            break;
      case CExtPaintManager::__ESBMHT_PAGE_UP:
            bUpStep = true;
            // continue falling here ...
      case CExtPaintManager::__ESBMHT_PAGE_DOWN:
            nStepSize = (INT)_psbd.m_DSI.nPage;
#if (!defined __EXT_MFC_NO_SCROLLWND)
            if( pExtScrollWnd != NULL )
            {
                  int nDir = ( _psbd.m_eSBMHT == CExtPaintManager::__ESBMHT_PAGE_DOWN ) ? (-1) : 1;
                  CSize _size = pExtScrollWnd->OnSwGetPageSize( nDir );
                  nStepSize = _psbd.m_bHorzBar ? _size.cx : _size.cy;
            }
#endif
            if( nStepSize <= 0L )
                  nStepSize = GetStepSize();
            break;
      case CExtPaintManager::__ESBMHT_THUMB:
            break;
      }
bool bMenuMode = false;
      if( CExtPopupMenuWnd::IsMenuTracking() )
      {
            CWnd * pWnd = GetParent();
            for( ; pWnd != NULL; pWnd = pWnd->GetParent() )
            {
                  if( pWnd->IsKindOf( RUNTIME_CLASS(CExtPopupMenuWnd) ) )
                  {
                        bMenuMode = true;
                        break;
                  }
                  if( (pWnd->GetStyle()&WS_CHILD) == 0 )
                        break;
            }
      }
INT nMx = INT( _psbd.m_DSI.nMax - _psbd.m_DSI.nPage + 1 );
INT nScrollLimit = _psbd.m_DSI.nMax - _psbd.m_DSI.nMin - _psbd.m_DSI.nPage + 1;
      ASSERT( nScrollLimit >= 0 );
      if( nStepSize > nScrollLimit )
            nStepSize = nScrollLimit;
CRect rcScrollable = _psbd.m_rcBar;
      if( _psbd.m_bHorzBar )
      {
            rcScrollable.left = _psbd.m_rcButtonUp.right;
            rcScrollable.right = _psbd.m_rcButtonDown.left;
      }
      else
      {
            rcScrollable.top = _psbd.m_rcButtonUp.bottom;
            rcScrollable.bottom = _psbd.m_rcButtonDown.top;
      }
      ScrollBar_CaptureSet();
      if( nStepSize != 0L )
            ::PostMessage( hWndOwn, WM_TIMER, WPARAM(nTimerID_zero_start), LPARAM(0L) );
      for( MSG msg; ::IsWindow( hWndOwn ) && (!bStopFlag); )
      {
            if( ! PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
            {
                  if( ! ::IsWindow( hWndOwn ) )
                        break;
                  ::WaitMessage();
                  continue;
            }

            bool bAnalyzeThumb = false;
            switch( msg.message )
            {
            case WM_LBUTTONDBLCLK:
            case WM_LBUTTONUP:
            case WM_RBUTTONDBLCLK:
            case WM_RBUTTONDOWN:
            case WM_RBUTTONUP:
            case WM_MBUTTONDBLCLK:
            case WM_MBUTTONDOWN:
            case WM_MBUTTONUP:
            case WM_CANCELMODE:
            case WM_ACTIVATEAPP:
            case WM_KEYDOWN:
            case WM_KEYUP:
                  bStopFlag = true;
            break;
            case WM_CAPTURECHANGED:
                  if( (HWND)msg.wParam != hWndOwn )
                        bStopFlag = true;
            break;
            case WM_MOUSEMOVE:
                  if( m_nSBMHT == INT(CExtPaintManager::__ESBMHT_THUMB) )
                  {
                        if(         ( ! CExtPopupMenuWnd::IsKeyPressed( bMouseButtonsNotSwapped ? VK_LBUTTON : VK_RBUTTON,true) )
                              ||    CExtPopupMenuWnd::IsKeyPressed( VK_MBUTTON )
                              ||    CExtPopupMenuWnd::IsKeyPressed( bMouseButtonsNotSwapped ?  VK_RBUTTON : VK_LBUTTON,true )
                              ||    ( (!bMenuMode) && CExtPopupMenuWnd::IsMenuTracking() )
                              )
                        {
                              bStopFlag = true;
                              break;
                        }
                        PeekMessage(&msg,NULL,msg.message,msg.message,PM_REMOVE);
                        bAnalyzeThumb = true;
                        ::GetCursorPos( &ptCursor );
                        ::ScreenToClient( hWndOwn, &ptCursor );
                        break;
                  }
                  if( nStepSize == 0 )
                        break;
            case WM_TIMER:
                  {
                        if(         ( ! CExtPopupMenuWnd::IsKeyPressed( bMouseButtonsNotSwapped ? VK_LBUTTON : VK_RBUTTON,true) )
                              ||    CExtPopupMenuWnd::IsKeyPressed( VK_MBUTTON )
                              ||    CExtPopupMenuWnd::IsKeyPressed( bMouseButtonsNotSwapped ? VK_RBUTTON : VK_LBUTTON,true )
                              ||    ( (!bMenuMode) && CExtPopupMenuWnd::IsMenuTracking() )
                              )
                        {
                              bStopFlag = true;
                              break;
                        }
                        if( msg.hwnd != hWndOwn )
                              break;
                        if(         msg.wParam != nTimerID_zero_start
                              &&    msg.wParam != nTimerID_1st_slow
                              &&    msg.wParam != nTimerID_2nd_fast
                              )
                              break;
                        if( msg.wParam == nTimerID_zero_start )
                              ::SetTimer( hWndOwn, nTimerID_1st_slow, nTimerEllapse_1st_slow, NULL );
                        else if( msg.wParam == nTimerID_1st_slow )
                        {
                              ::KillTimer( hWndOwn, nTimerID_1st_slow );
                              ::SetTimer( hWndOwn, nTimerID_2nd_fast, nTimerEllapse_2nd_fast, NULL );
                        }
                        ASSERT( nStepSize != 0L );
                        PeekMessage(&msg,NULL,msg.message,msg.message,PM_REMOVE);
                        ::GetCursorPos( &ptCursor );
                        ::ScreenToClient( hWndOwn, &ptCursor );
                        bool bPause = false;
                        if( ! rcArea.PtInRect( ptCursor ) )
                              bPause = true;
                        else
                        {
                              if(         m_nSBMHT == INT(CExtPaintManager::__ESBMHT_PAGE_UP)
                                    ||    m_nSBMHT == INT(CExtPaintManager::__ESBMHT_PAGE_DOWN)
                                    )
                              {
                                    CExtPaintManager::PAINTSCROLLBARDATA _psbd2( this );
                                    _psbd2.AdjustHT( ptCursor );
                                    INT nSBMHT2 = INT( _psbd.m_eSBMHT );
                                    if( nSBMHT2 != m_nSBMHT )
                                          bPause = true;
                                    else
                                    {
                                          CRect rcArea2 = _psbd2.GetAreaRectHT();
                                          if( ! rcArea2.PtInRect( ptCursor ) )
                                                bPause = true;
                                          else
                                          {
                                                if( _psbd2.m_bHorzBar )
                                                {
                                                      if( m_nSBMHT == INT(CExtPaintManager::__ESBMHT_PAGE_UP) )
                                                      {
                                                            if( ptCursor.x >= _psbd2.m_rcThumb.left )
                                                                  bPause = true;
                                                      }
                                                      else if( m_nSBMHT == INT(CExtPaintManager::__ESBMHT_PAGE_DOWN) )
                                                      {
                                                            if( ptCursor.x <= _psbd2.m_rcThumb.right )
                                                                  bPause = true;
                                                      }
                                                }
                                                else
                                                {
                                                      if( m_nSBMHT == INT(CExtPaintManager::__ESBMHT_PAGE_UP) )
                                                      {
                                                            if( ptCursor.y >= _psbd2.m_rcThumb.top )
                                                                  bPause = true;
                                                      }
                                                      else if( m_nSBMHT == INT(CExtPaintManager::__ESBMHT_PAGE_DOWN) )
                                                      {
                                                            if( ptCursor.y <= _psbd2.m_rcThumb.bottom )
                                                                  bPause = true;
                                                      }
                                                }
                                          }
                                    }
                              }
                        }
                        if( bPause )
                        {
                              if( ! m_bProcessingOutClick )
                              {
                                    m_bProcessingOutClick = true;
                                    Invalidate();
                              }
                              if( pATTW != NULL )
                                    pATTW->Hide();
                              continue;
                        }
                        if( bUpStep )
                        {
                              nScrollPos -= nStepSize;
                              if( nScrollPos < _psbd.m_DSI.nMin )
                                    nScrollPos = _psbd.m_DSI.nMin;
                        }
                        else
                        {
                              nScrollPos += nStepSize;
                              if( nScrollPos > nMx )
                                    nScrollPos = nMx;
                        }
                        if( _GetScrollPos( true ) != nScrollPos )
                        {
                              bool bSendScrollingNotification = true, bTrackPos = true;
                              if( hWndParent != NULL )
                              {
                                    switch( m_nSBMHT )
                                    {
                                    case (CExtPaintManager::__ESBMHT_BUTTON_UP):
                                          if( m_bSendActionNotifications )
                                                ::SendMessage( hWndParent, _psbd.m_bHorzBar ? WM_HSCROLL : WM_VSCROLL, MAKEWPARAM( ( _psbd.m_bHorzBar ? SB_LINELEFT : SB_LINEUP ), 0 ), LPARAM(m_hWnd) );
if( ! bVirtualMode )
      _SetScrollPos( nScrollPos, bTrackPos, true, bSendScrollingNotification );
else
      bFinalNotify = (!m_bSendActionNotifications);
                                    break;
                                    case (CExtPaintManager::__ESBMHT_BUTTON_DOWN):
                                          if( m_bSendActionNotifications )
                                                ::SendMessage( hWndParent, _psbd.m_bHorzBar ? WM_HSCROLL : WM_VSCROLL, MAKEWPARAM( ( _psbd.m_bHorzBar ? SB_LINERIGHT : SB_LINEDOWN ), 0 ), LPARAM(m_hWnd) );
if( ! bVirtualMode )
      _SetScrollPos( nScrollPos, bTrackPos, true, bSendScrollingNotification );
else
      bFinalNotify = (!m_bSendActionNotifications);
                                    break;
                                    case (CExtPaintManager::__ESBMHT_PAGE_UP):
                                          if( m_bSendActionNotifications )
                                                ::SendMessage( hWndParent, _psbd.m_bHorzBar ? WM_HSCROLL : WM_VSCROLL, MAKEWPARAM( ( _psbd.m_bHorzBar ? SB_PAGELEFT : SB_PAGEUP ), 0 ), LPARAM(m_hWnd) );
if( ! bVirtualMode )
      _SetScrollPos( nScrollPos, bTrackPos, true, bSendScrollingNotification );
else
      bFinalNotify = (!m_bSendActionNotifications);
                                    break;
                                    case (CExtPaintManager::__ESBMHT_PAGE_DOWN):
                                          if( m_bSendActionNotifications )
                                                ::SendMessage( hWndParent, _psbd.m_bHorzBar ? WM_HSCROLL : WM_VSCROLL, MAKEWPARAM( ( _psbd.m_bHorzBar ? SB_PAGERIGHT : SB_PAGEDOWN ), 0 ), LPARAM(m_hWnd) );
if( ! bVirtualMode )
      _SetScrollPos( nScrollPos, bTrackPos, true, bSendScrollingNotification );
else
      bFinalNotify = (!m_bSendActionNotifications);
                                    break;
                                    case (CExtPaintManager::__ESBMHT_THUMB):
                                          bTrackPos = true;
if( ! bVirtualMode )
      _SetScrollPos( nScrollPos, bTrackPos, true, bSendScrollingNotification );
else
      bFinalNotify = false;
                                    break;
                                    }
                              }
                              if( pATTW != NULL && ( ! bAnalyzeThumb ) )
                                    OnAdvancedPopupMenuTipWndDisplay( *pATTW, m_nSBMHT, true );
                        }
                        _psbd.AdjustHT( ptCursor );
                        bool bProcessingOutClick =
                              ( m_nSBMHT == INT(_psbd.m_eSBMHT) )
                                    ? false : true;
                        rcArea = _psbd.GetAreaRect( CExtPaintManager::e_scroll_bar_mouse_hover_type_t(m_nSBMHT) );
                        if( m_bProcessingOutClick != bProcessingOutClick )
                        {
                              bool bAnimationLocked = AnimationClient_CacheGeneratorIsLocked();
                              if( ! bAnimationLocked )
                              {
                                    AnimationClient_CacheGeneratorLock();
                                    AnimationClient_CacheNextStateMinInfo( false, __EAPT_BY_PRESSED_STATE_TURNED_OFF );
                              }
                              m_bProcessingOutClick = bProcessingOutClick;
                              if( ! bAnimationLocked )
                              {
                                    AnimationClient_CacheNextStateMinInfo( true, __EAPT_BY_PRESSED_STATE_TURNED_OFF );
                                    AnimationClient_CacheGeneratorUnlock();
                              }
                              Invalidate();
                              UpdateWindow();
                        }
                  }
            break;
            default:
            {
                  if(         ( ! CExtPopupMenuWnd::IsKeyPressed( bMouseButtonsNotSwapped ? VK_LBUTTON : VK_RBUTTON,true) )
                        ||    CExtPopupMenuWnd::IsKeyPressed( VK_MBUTTON )
                        ||    CExtPopupMenuWnd::IsKeyPressed( bMouseButtonsNotSwapped ? VK_RBUTTON : VK_LBUTTON,true )
                        ||    ( (!bMenuMode) && CExtPopupMenuWnd::IsMenuTracking() )
                        )
                        bStopFlag = true;
            }
            break;
            }
            if( bStopFlag || nScrollLimit == 0L )
                  break;
            if( bAnalyzeThumb )
            {
                  LONG nPixelOffset = _psbd.m_bHorzBar
                        ? (ptCursor.x - point.x)
                        : (ptCursor.y - point.y);
                  LONG nPixelExtent = _psbd.m_bHorzBar
                        ? (rcScrollable.Width() - _psbd.m_rcThumb.Width())
                        : (rcScrollable.Height() - _psbd.m_rcThumb.Height());
                  if( nPixelExtent <= 0 )
                  {
                        bStopFlag = true;
                        break;
                  }
                  if( abs(nPixelOffset) > nPixelExtent )
                        nPixelOffset = (nPixelOffset < 0) ? (-nPixelExtent) : nPixelExtent;
                  INT nShift = ( nPixelExtent == 0 || nPixelOffset == 0 ) ? 0 : ::MulDiv( nScrollLimit, abs(nPixelOffset), nPixelExtent );
                  nScrollPos = nScrollPosStart;
                  if( nPixelOffset < 0 )
                  {
                        nScrollPos -= nShift;
                        if( nScrollPos < _psbd.m_DSI.nMin )
                              nScrollPos = _psbd.m_DSI.nMin;
                  }
                  else
                  {
                        nScrollPos += nShift;
                        if( nScrollPos > nMx )
                              nScrollPos = nMx;
                  }
                  if( ! bVirtualMode )
                  {
                        if( _GetScrollPos( true ) != nScrollPos )
                        {
                              _SetScrollPos( nScrollPos, true );
                              if( pATTW != NULL )
                                    OnAdvancedPopupMenuTipWndDisplay( *pATTW, m_nSBMHT, true );
                        }
                        bFinalNotify = true;
                  }
                  _psbd.AdjustHT( ptCursor );
                  rcArea = _psbd.GetAreaRect( CExtPaintManager::__ESBMHT_THUMB );
                  continue;
            }
            if(         m_bPopupInactiveLightMode
                  &&    (     msg.message == WM_TIMER
                        ||    (__EXT_MFC_WM_MOUSEFIRST <= msg.message && msg.message <= __EXT_MFC_WM_MOUSELAST )
                        )
                  )
                  ::PeekMessage(&msg,NULL,msg.message,msg.message,PM_REMOVE);
            else
            if( ! AfxGetThread()->PumpMessage() )
                  break;
      }
      if( ! ::IsWindow( hWndOwn ) )
            return;
      if( nStepSize != 0L )
      {
            ::KillTimer( hWndOwn, nTimerID_1st_slow );
            ::KillTimer( hWndOwn, nTimerID_2nd_fast );
      }
      bAnimationLocked = AnimationClient_CacheGeneratorIsLocked();
      if( ! bAnimationLocked )
      {
            AnimationClient_CacheGeneratorLock();
            if( AnimationClient_StateGet(true).IsEmpty() )
                  AnimationClient_CacheNextStateMinInfo( false, __EAPT_BY_PRESSED_STATE_TURNED_OFF );
      }
      if( bFinalNotify )
      {
            bool bSendScrollingNotification = true;
            _SetScrollPos( nScrollPos, false, true, bSendScrollingNotification );
      }
      m_nSBMHT = INT(CExtPaintManager::__ESBMHT_NOWHERE);
      m_bProcessingClick
            = m_bProcessingOutClick
            = m_bProcessingHover
            = false;
      if( ! bAnimationLocked )
      {
            ::GetCursorPos( &ptCursor );
            ScreenToClient( &ptCursor );
            _psbd.AdjustHT( ptCursor );
            m_nSBMHT = INT(_psbd.m_eSBMHT);
            AnimationClient_CacheNextStateMinInfo( true, __EAPT_BY_PRESSED_STATE_TURNED_OFF );
            AnimationClient_CacheGeneratorUnlock();
      }
      Invalidate();
      UpdateWindow();
      m_nHelperTrackPos = -1;
      m_bHelperHaveTrackPos = false;
      ScrollBar_CaptureRelease();
      if( pATTW != NULL )
            OnAdvancedPopupMenuTipWndDisplay( *pATTW, INT(_psbd.m_eSBMHT), false );
      ::SendMessage( hWndParent, _psbd.m_bHorzBar ? WM_HSCROLL : WM_VSCROLL, MAKEWPARAM( SB_ENDSCROLL, 0 ), LPARAM(m_hWnd) );
      if( m_bEnableHookSpy )
            HookSpyRegister();
}