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 » MDI System menu SC_Close accelerator Collapse All
Subject Author Date
Raffaele Cappelli Feb 10, 2006 - 9:37 AM

I have noted what may be a small bug: if you let Prof-UIS CExtMenuControlBar replace both the MDI frame system menu and the MDI child frame system menu, the accelerator associated to the SC_CLOSE command (displayed in the menu) is Alt+F4 in both the menus if you open the frame menu first, or Ctrl+F4 in both if you open the child system menu first. This may be due to the fact that the two commands have the same id but different accelerators, or maybe I am doing something wrong.

Technical Support Feb 11, 2006 - 1:04 PM

Thank you for the bug report. We fixed the bug in the CExtPopupMenuWnd::_TrackPopupMenu() method (the ExtPopupMenuWnd.cpp file):

BOOL CExtPopupMenuWnd::_TrackPopupMenu(
    DWORD dwTrackFlags,
    int x,
    int y,
    LPCRECT lpRect,
    LPVOID pCbPaintCombinedCookie, // = NULL
    pCbPaintCombinedContent pCbPCC, // = NULL
    bool bCookieIsObject // = false
    )
{
    ASSERT_VALID( this );
bool bForceExpandRarelyUsed = (dwTrackFlags&TPMX_NO_HIDE_RARELY)
        ? true : false;
    if( ! g_bMenuExpanding )
        bForceExpandRarelyUsed = true;

    ASSERT( m_hWndCmdReceiver != NULL );
    ASSERT( ::IsWindow(m_hWndCmdReceiver) );

    ASSERT( GetSafeHwnd() == NULL );
CExtPopupMenuSite & _site = GetSite();
    if(        (!_FindCustomizeMode())
        &&    _site.IsTopPopup(this)
        )
    {
        ASSERT( m_bTopLevel );
        MsgPrepareMenuData_t _mpmEntireTree( this );
        _mpmEntireTree.SendMessage( m_hWndCmdReceiver, false );
        if( _mpmEntireTree.m_bMenuCanceled )
            return FALSE;
        if( _mpmEntireTree.m_bMenuChanged )
        {
            _SyncItems();
            _UpdateCmdUI();
        }
        ASSERT( m_bTopLevel );
        ASSERT( _site.IsTopPopup(this) );
    }
MsgPrepareMenuData_t _mpmOneTreeLevel( this );
    _mpmOneTreeLevel.SendMessage( m_hWndCmdReceiver, true );
    if( _mpmOneTreeLevel.m_bMenuCanceled )
        return FALSE;
    if( _mpmOneTreeLevel.m_bMenuChanged )
    {
        _SyncItems();
        _UpdateCmdUI();
    }
    if( !_FindCustomizeMode() )
    { // BLOCK: update system commands
        INT iter = 0;
        for(; iter < m_items_all.GetSize(); ++iter )
        {
            MENUITEMDATA & mi = ItemGetInfo( iter );
            if( mi.IsSeparator() )
                continue;
            UINT nCmdID = mi.GetCmdID();
            if( ! CExtCmdManager::IsSystemCommand( nCmdID ) )
                continue;
            WINDOWPLACEMENT wndpl;
            ::memset(&wndpl,0,sizeof(WINDOWPLACEMENT));
            wndpl.length = sizeof(WINDOWPLACEMENT);
            VERIFY(
                ::GetWindowPlacement(
                    mi.GetCmdReceiver(),
                    &wndpl
                    )
                );
            DWORD dwWndStyle = (DWORD)
                ::GetWindowLong(
                    mi.GetCmdReceiver(),
                    GWL_STYLE
                    );
            DWORD dwWndExStyle = (DWORD)
                ::GetWindowLong(
                    mi.GetCmdReceiver(),
                    GWL_EXSTYLE
                    );
            bool bSysCmdEnabled = false;
            switch( nCmdID )
            {
            case SC_CLOSE:
                {
                    bSysCmdEnabled = true;
                    HMENU hSysMenu = ::GetSystemMenu( mi.GetCmdReceiver(), FALSE );
                    MENUITEMINFO _mii;
                    ::memset( &_mii, 0, sizeof(MENUITEMINFO) );
                    _mii.cbSize = sizeof(MENUITEMINFO);
                    _mii.fMask = MIIM_STATE;
                    if(        hSysMenu != NULL
                        &&    ::GetMenuItemInfo(
                                hSysMenu,
                                SC_CLOSE,
                                FALSE,
                                &_mii
                                )
                        )
                    {
                        if( (_mii.fState & MFS_DISABLED) != 0 )
                            bSysCmdEnabled = false;
                    } // if( hSysMenu != NULL ...
                }
            break;
            case SC_SIZE:
            case SC_MOVE:
                if(        wndpl.showCmd != SW_SHOWMINIMIZED
                    &&    wndpl.showCmd != SW_SHOWMAXIMIZED
                    &&    !g_bFullScreenMode
                    )
                    bSysCmdEnabled = true;
            break;
            case SC_MINIMIZE:
                if(        (dwWndStyle & WS_MINIMIZEBOX) != 0
                    &&    wndpl.showCmd != SW_SHOWMINIMIZED
                    )
                    bSysCmdEnabled = true;
            break;
            case SC_MAXIMIZE:
                if(        (dwWndStyle & WS_MAXIMIZEBOX) != 0
                    &&    wndpl.showCmd != SW_SHOWMAXIMIZED
                    &&    !g_bFullScreenMode
                    )
                    bSysCmdEnabled = true;
            break;
            case SC_RESTORE:
                if(        (dwWndStyle & (WS_MINIMIZEBOX|WS_MAXIMIZEBOX)) != 0
                    &&    (    wndpl.showCmd == SW_SHOWMAXIMIZED
                        ||    wndpl.showCmd == SW_SHOWMINIMIZED
                        //||wndpl.showCmd == SW_SHOWNORMAL
                        )
                    )
                    bSysCmdEnabled = true;
            break;
            case SC_CONTEXTHELP:
                if( (dwWndExStyle & WS_EX_CONTEXTHELP) != 0 )
                    bSysCmdEnabled = true;
            break;
            case SC_HOTKEY:
            default:
                continue;
            } // switch( nCmdID )
            CExtCmdItem * pCmdItem =
                g_CmdManager->CmdGetPtr(
                    g_CmdManager->ProfileNameFromWnd( m_hWndCmdReceiver ),
                    nCmdID
                    );
            ASSERT( pCmdItem != NULL );
            pCmdItem->StateEnable( bSysCmdEnabled );
            mi.Enable( bSysCmdEnabled );
            ASSERT( CExtCmdManager::IsSystemCommand( nCmdID ) );
            HMENU hSysMenu = ::GetSystemMenu( mi.GetCmdReceiver(), FALSE );
            if( hSysMenu != NULL )
            {
                MENUITEMINFO _mii;
                ::memset( &_mii, 0, sizeof(MENUITEMINFO) );
                _mii.cbSize = sizeof(MENUITEMINFO);
                _mii.fMask =
                    MIIM_CHECKMARKS|MIIM_DATA|MIIM_ID|MIIM_STATE
                    |MIIM_SUBMENU|MIIM_TYPE;
                _mii.cch = __MAX_UI_ITEM_TEXT;
                CExtSafeString sMenuItemText;
                _mii.dwTypeData = sMenuItemText.GetBuffer( __MAX_UI_ITEM_TEXT );
                ASSERT( _mii.dwTypeData != NULL );
                if( _mii.dwTypeData != NULL )
                {
                    if(    ::GetMenuItemInfo(
                            hSysMenu,
                            nCmdID,
                            FALSE,
                            &_mii
                            )
                        )
                    {
                        sMenuItemText.ReleaseBuffer();
                        sMenuItemText.Replace( _T("\n"), _T("") );
                        sMenuItemText.Replace( _T("\r"), _T("") );
                        sMenuItemText.TrimLeft();
                        sMenuItemText.TrimRight();
                        if( ! sMenuItemText.IsEmpty() )
                        {
                            int nSep =
                                sMenuItemText.ReverseFind( _T(’\t’) );
                            if( nSep >= 0 )
                            {
                                int nLen = sMenuItemText.GetLength();
                                pCmdItem->m_sAccelText = sMenuItemText.Right( nLen - nSep );
                                pCmdItem->m_sAccelText.TrimLeft();
                                pCmdItem->m_sAccelText.TrimRight();
                                pCmdItem->m_sMenuText = sMenuItemText.Left( nSep );
                                pCmdItem->m_sMenuText.TrimLeft();
                                pCmdItem->m_sMenuText.TrimRight();
                            }
                            else
                            {
                                pCmdItem->m_sMenuText = sMenuItemText;
                                pCmdItem->m_sAccelText = _T("");
                            }
                            mi.SetPopupText( pCmdItem->m_sMenuText );
                            mi.SetAccelText( pCmdItem->m_sAccelText );
                        } // if( ! sMenuItemText.IsEmpty() )
                    }
                    else
                        sMenuItemText.ReleaseBuffer();
                } // if( _mii.dwTypeData != NULL )
                if( (_mii.fState&MFS_DEFAULT) != 0 )
                    mi.SetDefault();
            } // if( hSysMenu != NULL )
        } // for(; iter < m_items_all.end(); ++iter )
    } // BLOCK: update system commands
CWnd * pWndCmdReceiver =
        CWnd::FromHandle( m_hWndCmdReceiver );
    ASSERT_VALID( pWndCmdReceiver );
bool bOldTopLevel = m_bTopLevel;
bool bOldExpandAvailable = m_bExpandAvailable;
DWORD dwPortedTrackFlags = m_dwTrackFlags&(TPMX_PALETTE|TPMX_PALETTE_TB_BKGND);
    _Init();
    m_bTopLevel = bOldTopLevel;
    m_bExpandAvailable = bOldExpandAvailable;
    m_dwTrackFlags = dwTrackFlags | dwPortedTrackFlags;
    m_pCbPaintCombinedCookie = pCbPaintCombinedCookie;
    m_pCbPaintCombinedContent = pCbPCC;
    m_bCookieIsObject = bCookieIsObject;
    if( !m_bTopLevel )
    {
        ASSERT( m_pWndParentMenu != NULL );
        if( m_pWndParentMenu->m_bExpandWasPressed )
        {
            if( m_bExpandAvailable )
            {
                m_bExpandAvailable = false;
                m_bExpandWasPressed = true;
                _SyncItems();
            }
            else
                m_bExpandWasPressed = true;
        }
    } // if( !m_bTopLevel )
    else
    {
        if( bForceExpandRarelyUsed )
        {
            if( m_bExpandAvailable )
            {
                m_bExpandAvailable = false;
                m_bExpandWasPressed = true;
                _SyncItems();
            }
            else
                m_bExpandWasPressed = true;
        } // if( bForceExpandRarelyUsed )
        else
            _SyncItems();
    } // else from if( !m_bTopLevel )
    // adjust screen position
    m_ptTrack.x = x;
    m_ptTrack.y = y;
    if( m_ptTrack.x < 0 || m_ptTrack.y < 0 )
    {
        if( ! ::GetCursorPos(&m_ptTrack) )
            return FALSE;
    }

    if( lpRect != NULL )
    {
        m_rcExcludeArea = *lpRect;
        m_bExcludeAreaSpec = true;
    }
    else
    {
        m_bExcludeAreaSpec = false;
        m_rcExcludeArea.left = m_ptTrack.x - __EXCLUDE_AREA_GAP_DX;
        m_rcExcludeArea.right = m_ptTrack.x + __EXCLUDE_AREA_GAP_DX;
        m_rcExcludeArea.top = m_ptTrack.y - __EXCLUDE_AREA_GAP_DY;
        m_rcExcludeArea.bottom = m_ptTrack.y + __EXCLUDE_AREA_GAP_DY;
    }
    m_bCombineWithEA = false;
    if( m_bExcludeAreaSpec )
    {
        switch( (dwTrackFlags&TPMX_COMBINE_MASK) )
        {
        case TPMX_COMBINE_ANY_SUITABLE:
            m_bCombineWithEA = true;
        break;
        case TPMX_COMBINE_DEFAULT:
            m_bCombineWithEA =
                PmBridge_GetPM()->
                    IsMenuMustCombineExcludeArea();
        break;
        } // switch( (dwTrackFlags&TPMX_COMBINE_MASK) )
    } // if( m_bExcludeAreaSpec )
CSize _size = _CalcTrackSize();
bool bPointAdjusted = true;
    if( m_bExcludeAreaSpec )
    {
        bool bRTL = OnQueryLayoutRTL();
        if( bRTL && (!m_bTopLevel) )
        {
            CExtPopupMenuWnd * pTop = m_pWndParentMenu;
            for( ; pTop != NULL; pTop = pTop->m_pWndParentMenu )
            {
                if( pTop->m_bTopLevel )
                    break;
            } // for( ; pTop != NULL; pTop = pTop->m_pWndParentMenu )
            if( pTop != NULL )
            {
                switch( (pTop->m_dwTrackFlags & TPMX_ALIGN_MASK) )
                {
                case TPMX_TOPALIGN:
                case TPMX_BOTTOMALIGN:
                    m_dwTrackFlags &= ~(TPMX_ALIGN_MASK);
                    m_dwTrackFlags |= TPMX_RIGHTALIGN;
                break;
                } // switch( (pTop->m_dwTrackFlags & TPMX_ALIGN_MASK) )
            } // if( pTop != NULL )
        } // if( bRTL && (!m_bTopLevel) )
        switch( (m_dwTrackFlags & TPMX_ALIGN_MASK) )
        {
        case TPMX_LEFTALIGN:
            m_ptTrack.x = m_rcExcludeArea.right;
            m_ptTrack.y = m_rcExcludeArea.top;
        break;
        case TPMX_RIGHTALIGN:
            m_ptTrack.x = m_rcExcludeArea.left - _size.cx;
            m_ptTrack.y = m_rcExcludeArea.top;
        break;
        case TPMX_TOPALIGN:
            m_ptTrack.x = m_rcExcludeArea.left;
            m_ptTrack.y = m_rcExcludeArea.bottom;
        break;
        case TPMX_BOTTOMALIGN:
            m_ptTrack.x = m_rcExcludeArea.left;
            m_ptTrack.y = m_rcExcludeArea.top - _size.cy;
        break;
        default:
            bPointAdjusted = false;
        break;
        } // switch( (m_dwTrackFlags & TPMX_ALIGN_MASK) )
    } // if( m_bExcludeAreaSpec )
    if( ! bPointAdjusted )
    {
        if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_RIGHTALIGN )
            m_ptTrack.x -= _size.cx;
        else
        {
            if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_CENTERALIGN )
                m_ptTrack.x -= _size.cx/2;
        }
        if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_BOTTOMALIGN )
            m_ptTrack.y -= _size.cy;
        else
        {
            if( (m_dwTrackFlags & TPMX_ALIGN_MASK) == TPMX_VCENTERALIGN )
                m_ptTrack.y -= _size.cy/2;
        }
    } // if( !bPointAdjusted )
bool bCreateResult =
        _CreateHelper( pWndCmdReceiver );
    if( !bCreateResult )
        return FALSE;
    if( dwTrackFlags & TPMX_SELECT_ANY )
    {
        int nItem = _GetNextItem(__NI_ANY);
        if( nItem >= 0 )
        {
            HWND hWndOwn = m_hWnd;
            _ItemFocusSet(
                nItem,
                FALSE,
                FALSE
                );
            if( ! ::IsWindow( hWndOwn ) )
                return FALSE;
        }
    }
HWND hWndOwn = m_hWnd;
    if(        (dwTrackFlags&TPMX_FORCE_NO_ANIMATION) != 0
        ||    _FindCustomizeMode()
        )
        m_AnimationType = __AT_NONE;
    else
    {
        m_AnimationType = g_DefAnimationType;
        if( CExtToolControlBar::g_bMenuTracking )
            m_AnimationType = __AT_NONE;

        m_ePlaySoundOnAnimationFinished =
            CExtSoundPlayer::__ON_MENU_POPUP_DISPLAYED;
        _StartAnimation();
        if( ! ::IsWindow( hWndOwn ) )
            return FALSE;
    } // if( _FindCustomizeMode() )
    if( m_AnimationType == __AT_NONE )
    {
        m_AnimationType = __AT_CONTENT_DISPLAY;
        _StartAnimation();
        if( ! ::IsWindow( hWndOwn ) )
            return FALSE;
        ASSERT( m_AnimationType == __AT_CONTENT_DISPLAY );
    }
    if( m_rgnWnd.GetSafeHandle() != NULL )
    {
        ASSERT( m_bExcludeAreaSpec );
        ASSERT( m_bCombineWithEA );
        ASSERT( m_eCombineAlign != __CMBA_NONE );
        CRgn rgnTmp;
        VERIFY( rgnTmp.CreateRectRgn(0,0,0,0) );
        rgnTmp.CopyRgn( &m_rgnWnd );
        ASSERT( rgnTmp.GetSafeHandle() != NULL );
        VERIFY(
            SetWindowRgn(
                (HRGN)rgnTmp.Detach(),
                FALSE
                )
            );
    } // if( m_rgnWnd.GetSafeHandle() != NULL )
    SetWindowPos(
        &CWnd::wndTopMost, 0, 0, 0, 0,
        SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE
            |SWP_SHOWWINDOW|SWP_NOZORDER
        );
    ASSERT( IsWindowVisible() );
    if( ! _FindCustomizeMode() )
        _SetCapture();
#if (!defined __EXT_MFC_NO_CUSTOMIZE)
    else
    {
        CExtCustomizeSite * pSite = _FindCustomizeSite();
        ASSERT( pSite != NULL );
        pSite->RegisterCommandDropTarget( this, this );
    }
#endif // (!defined __EXT_MFC_NO_CUSTOMIZE)
    return TRUE;
}