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 » MRU menu issues Collapse All
Subject Author Date
Thomas Fuchs Mar 23, 2005 - 12:16 PM

Hello there,


I have some troubles on displaying the MRU menu text. My application uses an overwritten CRecentFileList in CWinApp. Command routing works fine, however, I cannot update the popup menu text of the last used documents the way CRecentFileList::UpdateMenu() does.

When I call MyRecentFileList->UpdateMenu(), the pCmdUI->m_pMenu is NULL and thus the function terminates.

I’ve checked the forum on similar issues (for instance, "MRU menu not updated correctly" by Andrey Del Pozo, April 17, 2004 or "Changing frame’s main menu" by Mirco Alexis, Feb. 11, 2004) and understood that Prof-UIS replaces the standard MFC menus, but this did not really help.

So, could you please provide a simple example on how to use the MRU menu in the way CRecentFileList::UpdateMenu() does?


Thanks,
Thomas

Technical Support Mar 23, 2005 - 12:48 PM

Dear Tomas,

The Prof-UIS pop-up menus are really not based on standard Windows menus so you should not use the CRecentFileList::UpdateMenu() method at all. Our pop-up menu uses the CRecentFileList::GetDisplayName() non virtual method for accessing all MRU file items. So, if you simply fill the CRecentFileList::m_arrNames array, then the Prof-UIS menu will automatically display it.

If this is not what you need, please let us know and we will find an appropriate solution for you.

Thomas Fuchs Mar 25, 2005 - 8:03 AM

Dear Alex,


Thanks for your prompt help, I fixed it. Actually it was my fault, since I used the wrong command IDs for the MRU list... :-(


However, I am not very happy about the way you access CWinApp::m_pRecentFileList in CExtPopupMenuWnd using your little "dirty hack" of InternalFriendlyWinApp, even though I fully understand why you do it this way.


The reason is because I would like to implement 2 different MRU list in my File menu (for instance, the way VS 2003 does for "Last used Files" and "Last used Projects"), for which I did not initialize CWinApp::m_pRecentFileList rather than using my own private version of this class, which then has caused the troubles I’ve had.


Anyway, after studying CExtPopupMenuWnd::_BuildItems() I have no clue how to implement 2 different MRU lists. My first thought was to re-assign CWinApp::m_pRecentFileList by my private pointers, which works fine as long as I use only one MRU list. However, since _BuildItems() is called recursively and because it builds up the MRU command list always starting with ID_FILE_MRU_FIRST, I am afraid it won’t work this way.


Any suggestions is highly appreciated.


Thanks and best regards,
Thomas

Technical Support Mar 25, 2005 - 10:12 AM

To implement multiple MRU lists in Prof-UIS pop-up menus, you need to follow an absolutely different approach. Each MRU list can be represented as a menu item with a unique command identifier in the menu resource of your application. The main frame window should handle the CExtPopupMenuWnd::g_nMsgPrepareMenu registered windows message and replace all the initial MRU command items with real MRU commands. This message is sent for each menu tree every time immediately before is appears on the screen. So, your function should be recursive. Here is the source code for the message handler:

 
    // declaration in the class scope
    afx_msg LRESULT OnExtMenuPrepare(
        WPARAM wParam, LPARAM lParam );
    //  message map’s entry
    ON_REGISTERED_MESSAGE(
        CExtPopupMenuWnd::g_nMsgPrepareMenu,
        OnExtMenuPrepare
        )
    // implementation
    LRESULT CMainFrame::OnExtMenuPrepare(
        WPARAM wParam, LPARAM lParam )
    {
        lParam;
        CExtPopupMenuWnd::MsgPrepareMenuData_t * pData =
            reinterpret_cast
            < CExtPopupMenuWnd::MsgPrepareMenuData_t * >
            ( wParam );
        ASSERT( pData != NULL );
        CExtPopupMenuWnd * pPopup = pData->m_pPopup;
        ASSERT( pPopup != NULL );
        pData->m_bMenuChanged = 
            My_Walk_Menu_Tree_Recursive( pPopup );
        return TRUE; 
    }

Here is a sample implementation of the My_Walk_Menu_Tree_Recursive() method which returns true if any sub menu has been modified:
 
    bool CMainFrame::My_Walk_Menu_Tree_Recursive(
        CExtPopupMenuWnd * pPopup
        )
    {
        ASSERT_VALID( pPopup );
        bool bRetVal = false;
        int nItemCount = pPopup->ItemGetCount();
        for( int nItemIndex = 0; nItemIndex < nItemCount; )
        {
            CExtPopupMenuWnd::MENUITEMDATA & _mii =
               pPopup->ItemGetInfo( nItemIndex );
            if( _mii.IsSeparator() )
            {
                nItemIndex ++;
                continue;
            }
            if( _mii.IsPopup() )
            {
                bRetVal ||= 
                    My_Walk_Menu_Tree_Recursive(
                        _mii.GetPopup()
                        );
                nItemIndex ++;
                continue;
            }
            switch( _mii.GetCmdID() )
            {
            case ID_MY_FIRST_MRU_MARKER:
                bRetVal = true; // menu will be modified
                // remove marker item
                VERIFY( pPopup->ItemRemove( nItemIndex ) );
                nItemCount --;
                // insert 3 real MRU commands without
                // any reference to the command manager
                VERIFY(
                    pPopup->ItemInsertCommand(
                        ID_MY_FIRST_MRU_FILE1,
                        nItemIndex ++,
                        _T("Solution file 1"))
                        )
                    );
                nItemCount ++;
                VERIFY(
                    pPopup->ItemInsertCommand(
                        ID_MY_FIRST_MRU_FILE1,
                        nItemIndex ++,
                        _T("Solution file 3"))
                        )
                    );
                nItemCount ++;
                VERIFY(
                    pPopup->ItemInsertCommand(
                        ID_MY_FIRST_MRU_FILE3,
                        nItemIndex ++,
                        _T("Solution file 3"))
                        )
                    );
                nItemCount ++;
            break;
 
            . . .
 
            default:
                nItemIndex ++;
            break;
            }
        }
        return false;
    }  

So, you can implement an unlimited number of MRU file lists and each of them is not limited to 16 items.

Thomas Fuchs Mar 26, 2005 - 7:37 AM

... for your continued and prompt support!


With your help my MRU list implementation now works perfectly well and even more flexible as the standard MFC stuff!


Best regards,
Thomas