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 » Incorrect Toolbar & Menu behaviour when App isn't active. Collapse All
Subject Author Date
Neville Franks Oct 26, 2006 - 8:27 PM

When a Prof-UIS application isn’t the active (foreground) application and the user hovers the mouse over its menu or toolbar, menu items and buttons are highlighted and tooltips are displayed. This shouldn’t be happening.

Neville, http://www.surfulater.com

Technical Support Oct 27, 2006 - 6:32 AM

If you run any of Microsoft Office and Visual Studio applications, you can see that, if the application window is not active, toolbar buttons are not highlighted when the user hovers the mouse pointer over them. So we agree that the same functionality should be implemented in Prof-UIS. Thank you, Neville. Please update the source code for the CExtControlBar::OnMouseMove() and CExtControlBar::WindowProc() methods in the ExtControlBar.cpp file:

void CExtControlBar::OnMouseMove(UINT nFlags, CPoint point) 
{
__PROF_UIS_MANAGE_STATE;
    if( ! CExtPopupMenuWnd::TestHoverEnabledFromActiveHWND( m_hWnd ) )
        return;
    if( _OnMouseMoveMsg(nFlags,point) )
        return;
    CControlBar::OnMouseMove(nFlags,point);
}
 
LRESULT CExtControlBar::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
    switch( message )
    {
    case WM_NCMOUSEMOVE:
        {
           if( ! CExtPopupMenuWnd::TestHoverEnabledFromActiveHWND( m_hWnd ) )
                return 0;
            CExtPopupMenuTipWnd * pATTW =
                OnAdvancedPopupMenuTipWndGet();
            if( pATTW == NULL )
                return 0;
            CPoint ptScreen;
            if( ! ::GetCursorPos( &ptScreen ) )
                return 0;
            CExtBarNcAreaButton * pBtn = NULL;
            NcButtons_HitTest( ptScreen, &pBtn );
            if( pBtn != NULL )
            {
                ASSERT_VALID( pBtn );
                TOOLINFO _ti;
                ::memset( &_ti, 0, sizeof(AFX_OLDTOOLINFO) );
                _ti.cbSize = sizeof( TOOLINFO );
                _ti.hinst = ::AfxGetInstanceHandle();
                if( pBtn->OnToolHitTest( ptScreen, &_ti ) > 0 )
                {
                    if(     _ti.lpszText != NULL
                        &&  _ti.lpszText != LPSTR_TEXTCALLBACK
                        &&  _tcslen( _ti.lpszText ) > 0
                        )
                    {
                        CRect rcArea = *pBtn;
                        CRect rcDefOffsetWnd;
                        GetWindowRect( &rcDefOffsetWnd );
                        rcArea.OffsetRect( rcDefOffsetWnd.TopLeft() );
                        OnAdvancedPopupMenuTipWndDisplay(
                            *pATTW,
                            rcArea,
                            _ti.lpszText
                            );
                    }
                }
                if(     _ti.lpszText != NULL
                    &&  _ti.lpszText != LPSTR_TEXTCALLBACK
                    )
                    ::free( _ti.lpszText );
            }
        }
        break;
    case WM_PRINT:
    case WM_PRINTCLIENT:
        {
            CDC * pDC = CDC::FromHandle( (HDC) wParam );
            CRect rcRgnWnd, rcRgnClient;
            GetWindowRect( &rcRgnWnd );
            GetClientRect( &rcRgnClient );
            if( IsFloating() )
            {
                CRect rcFloatClient;
                GetParentFrame()->GetClientRect( &rcFloatClient );
                if( rcRgnClient.Width() > rcFloatClient.Width() )
                    rcRgnClient.right = rcRgnClient.left + rcFloatClient.Width();
                if( rcRgnClient.Height() > rcFloatClient.Height() )
                    rcRgnClient.bottom = rcRgnClient.top + rcFloatClient.Height();
            }
            if( (lParam&PRF_NONCLIENT) != 0 )
            {
                CRect rcWnd = rcRgnWnd, rcClient = rcRgnClient;
                ClientToScreen( &rcClient );
                rcClient.OffsetRect( -rcWnd.TopLeft() );
                rcWnd.OffsetRect( -rcWnd.TopLeft() );
                CRgn rgnWnd;
                if( rgnWnd.CreateRectRgnIndirect( &rcWnd ) )
                    pDC->SelectClipRgn( &rgnWnd );
                pDC->ExcludeClipRect( &rcClient );
                DoPaintNC( pDC );
                pDC->SelectClipRgn( NULL );
            }
            if( ( lParam & ( PRF_CLIENT | PRF_ERASEBKGND ) ) != 0 )
            {
                CPoint ptVpOffset( 0, 0 );
                if( ( lParam & PRF_NONCLIENT ) != 0 )
                {
                    CRect rcWnd = rcRgnWnd, rcClient = rcRgnClient;
                    ClientToScreen( &rcClient );
                    ptVpOffset.x = rcWnd.left - rcClient.left;
                    ptVpOffset.y = rcWnd.top - rcClient.top;
                }
                if(     ptVpOffset.x != 0
                    ||  ptVpOffset.y != 0
                    )
                    pDC->OffsetViewportOrg(
                        -ptVpOffset.x,
                        -ptVpOffset.y
                        );
                CDC dcSurface;
                CBitmap bmpSurface;
                CWindowDC dcDesktop( NULL );
                if(     dcSurface.CreateCompatibleDC( NULL )
                    &&  bmpSurface.CreateCompatibleBitmap(
                           &dcDesktop,
                           rcRgnClient.Width(),
                           rcRgnClient.Height()
                           )
                    )
                {
                    CBitmap * pOldBmp = dcSurface.SelectObject( &bmpSurface );
                    DoEraseBk( &dcSurface );
                    DoPaint( &dcSurface );
                    pDC->BitBlt(
                        0,
                        0,
                        rcRgnClient.Width(),
                        rcRgnClient.Height(),
                        &dcSurface,
                        0,
                        0,
                        SRCCOPY
                        );
                    dcSurface.SelectObject( pOldBmp );
                }
                if(     ptVpOffset.x != 0
                    ||  ptVpOffset.y != 0
                    )
                    pDC->OffsetViewportOrg(
                        ptVpOffset.x,
                        ptVpOffset.y
                        );
            }
            if( ( lParam & PRF_CHILDREN ) != 0 )
                CExtPaintManager::stat_PrintChildren(
                    m_hWnd,
                    message,
                    pDC->GetSafeHdc(),
                    lParam,
                    false
                    );
        }
        return (!0);
    case WM_TIMER:
            if( wParam == __TIMER_ID_DELAYED_UPDATE )
                return    0L;
            else if( wParam == __TIMER_ID_DRELAYED_REPAINT_FAKE )
            {
                RedrawWindow(
                    NULL,
                    NULL,
                    RDW_INVALIDATE|RDW_UPDATENOW
                        |RDW_ERASE|RDW_ERASENOW
                        |RDW_ALLCHILDREN
                        |RDW_FRAME
                    );
                return    0L;
            }
            if( AnimationSite_OnHookTimer( UINT(wParam) ) )
                return 0L;
        break;
    case WM_CLOSE:
        m_bInCustomModeUpdateCmdUI = true;
        return 0;
    case WM_DESTROY:
        AnimationSite_ClientRemove();
#if (_MFC_VER >= 0x700) && (_MFC_VER <= 0x710)
        if(     m_pDockSite != NULL
            &&  m_pDockSite->IsKindOf( RUNTIME_CLASS( CMDIChildWnd ) )
            )
        {
            CFrameWnd * pFrame = GetParentFrame();
            if( pFrame != m_pDockSite )
                m_bHelperSuppressDestruction = true;
        }
#endif
        m_bInCustomModeUpdateCmdUI = true;
        break;
    case WM_NCDESTROY:
        AnimationSite_ClientRemove();
        if( m_pDockContext != NULL )
        {
            m_pDockBar = NULL;
            delete m_pDockContext;
            m_pDockContext = NULL;
        }
        m_bInCustomModeUpdateCmdUI = true;
        NcButtons_RemoveAll();
        break;
    case WM_SETFOCUS:
        {
            LRESULT lResult =
                CControlBar::WindowProc(message, wParam, lParam);
            if( IsMinimizedOnRow() )
                MaximizeOnRow();
            if( ! IsFixedMode() )
            {
                CWnd * pWnd = GetWindow(GW_CHILD);
                if(     pWnd != NULL
                    &&  stat_QueryFocusChangingEnabled( this, pWnd->m_hWnd )
                    )
                {
                    pWnd->SetFocus();
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
                    ASSERT(
                            pWnd->GetWindow( GW_HWNDNEXT ) == NULL
                        ||  IsKindOf( RUNTIME_CLASS( CExtDynTabControlBar ) )
                        );
#else
                    ASSERT( pWnd->GetWindow( GW_HWNDNEXT ) == NULL );
#endif
                }
            }
            return lResult;
        }
    case WM_ERASEBKGND:
        if( ! m_bDoNotEraseClientBackground )
            return !0;
        CExtPaintManager::stat_ExcludeChildAreas(
            (HDC)wParam,
            *this
            );
        return CControlBar::WindowProc(message, wParam, lParam);;
    case WM_CREATE:
        {
            if( ( ! m_bPresubclassDialogMode ) && ( ! IsFixedMode() ) )
            {
                ASSERT( GetSafeHwnd() != NULL );
                ASSERT( ::IsWindow(GetSafeHwnd()) );
                HWND hWndParent = ::GetParent( GetSafeHwnd() );
                CFrameWnd * pFrame = NULL;
                do
                {
                    ASSERT( hWndParent != NULL );
                    ASSERT( ::IsWindow( hWndParent ) );
                    CWnd * pWnd = CWnd::FromHandle( hWndParent );
                    if( pWnd->IsKindOf( RUNTIME_CLASS( CFrameWnd ) ) )
                    {
                        pFrame = (CFrameWnd *)pWnd;
                        break;
                    }
                } while( pFrame == NULL );
                ASSERT( pFrame != NULL );
                ASSERT_VALID( pFrame );
                if( pFrame->IsKindOf( RUNTIME_CLASS( CMiniFrameWnd ) ) )
                {
                    pFrame = pFrame->GetParentFrame();
                    ASSERT( pFrame != NULL );
                    ASSERT_VALID( pFrame );
                    ASSERT( ! pFrame->IsKindOf( RUNTIME_CLASS( CMiniFrameWnd ) ) );
                }
                VERIFY( _FrameEnableDockingImpl( pFrame ) );
            }
        }
        break;
    case WM_SHOWWINDOW:
    case WM_SIZE:
            m_bDelelayRepaintNcButtons = true;
        break;
    case WM_WINDOWPOSCHANGED:
        {
            CExtPopupMenuTipWnd * pATTW =
                OnAdvancedPopupMenuTipWndGet();
            if( pATTW != NULL )
                pATTW->Hide();
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
            CExtCustomizeSite * pSite = NotifiedCustomizeSiteGet();
            if( pSite != NULL )
                pSite->OnBarStateChanged( this );
#endif
            if( m_pDockBar == NULL && ( ! m_bPresubclassDialogMode ) )
                break;
            LPWINDOWPOS lpWindowPos = 
                reinterpret_cast < LPWINDOWPOS > (lParam);
            ASSERT( lpWindowPos != NULL );
            if( ! IsFixedMode() )
                _UpdateVisibilityInChain();
            CExtControlBar * pBar = this;
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
            CExtDynTabControlBar * pTabBar = _GetNearestTabbedContainer();
            if( pTabBar != NULL && pTabBar != this )
                pBar = pTabBar;
#endif
            pBar->m_bDelelayRepaintNcButtons = true;
            pBar->PostMessage( WM_NCPAINT );
            if( ( lpWindowPos->flags & SWP_FRAMECHANGED ) == 0 )
                _RecalcNcArea();
            break;
        }
    case WM_WINDOWPOSCHANGING:
        {
            m_bDelelayRepaintNcButtons = true;
            if( m_pDockBar == NULL && ( ! m_bPresubclassDialogMode ) )
                break;
            LPWINDOWPOS lpWindowPos = 
                reinterpret_cast < LPWINDOWPOS > (lParam);
            ASSERT( lpWindowPos != NULL );
            lpWindowPos->flags |= SWP_FRAMECHANGED;
            break;
        }
    case WM_SETTEXT:
        {
            m_bDelelayRepaintNcButtons = true;
            LRESULT lResult = CControlBar::WindowProc(message, wParam, lParam);
            if(     (! IsFixedMode() )
                &&  (! IsKindOf( RUNTIME_CLASS( CExtDynControlBar ) ) )
                )
            {
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
                if( AutoHideModeGet() )
                {
                    CExtDynAutoHideArea * pTabs =
                        CExtDynAutoHideArea::stat_FindAreaOfBar( this );
                    if( pTabs != NULL )
                    {
                        ASSERT_VALID( pTabs );
                        pTabs->UpdateTabWnd();
                        CExtDynAutoHideSlider * pAutoHideSlider =
                            pTabs->GetAutoHideSlider();
                        if(     pAutoHideSlider->GetSafeHwnd() != NULL
                            &&  ( pAutoHideSlider->GetStyle() & WS_VISIBLE ) != 0
                            )
                            pAutoHideSlider->SendMessage( WM_NCPAINT );
                    }
                }
                else
#endif
                    if( IsVisible() )
                {
#if (!defined __EXT_MFC_NO_TAB_CONTROLBARS)
                    CWnd * pWnd = GetParent();
                    bool bRecalcThisNcArea = true;
                    if(     pWnd != NULL
                        &&  pWnd->IsKindOf( RUNTIME_CLASS( CExtDockDynTabBar ) )
                        )
                    {
                        ASSERT_VALID( pWnd );
                        pWnd = pWnd->GetParent();
                        ASSERT_VALID( pWnd );
                        CExtDynTabControlBar * pTabBar =
                            DYNAMIC_DOWNCAST(
                                CExtDynTabControlBar,
                                pWnd
                                );
                        if( pTabBar != NULL )
                        {
                            pTabBar->InvalidateSwitcher();
                            CFrameWnd * pFrame = pTabBar->GetParentFrame();
                            ASSERT_VALID( pFrame );
                            pFrame->DelayRecalcLayout();
                            pFrame->PostMessage( WM_NULL );
                            LONG nSelIdx = pTabBar->GetSwitcherSelection();
                            if( nSelIdx >= 0 )
                            {
                                CExtControlBar * pBarTest = pTabBar->GetBarAt( nSelIdx, true );
                                if( pBarTest == this )
                                {
                                    CString strText;
                                    GetWindowText( strText );
                                    pTabBar->SetWindowText( strText );
                                }
                            }
                            ((CExtControlBar*)pTabBar)->_RecalcNcArea();
                            bRecalcThisNcArea = false;
                        }
                    }
                    if( bRecalcThisNcArea )
#endif
                        _RecalcNcArea();
                }
            }
            return lResult;
        }
    }
    return CControlBar::WindowProc(message, wParam, lParam);
}


Neville Franks Oct 27, 2006 - 1:45 AM

Well I haven’t checked the Windows Guidelines, but I hope you aren’t right.

IE6 disables the Menu when it isn’t active. MS Visual Studio 6 and MS Word 2000 work as I suggested, when not active. Skype disables the Menu and doesn’t show tooltips. It does highlight buttons.

So it seems different apps behave differently. Personally I feel that if they aren’t active, the UI shouldn’t do anything on mouse over.

Neville, http://www.surfulater.com

Suhai Gyorgy Oct 27, 2006 - 1:34 AM

Even Internet Explorer works this way, except for the tooltips. So I guess it’s Windows behaviour.