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.
Subject |
Author |
Date |
|
ven rag
|
Dec 21, 2005 - 5:03 AM
|
Hi ppl, I have created a Dynamic menu for MDI Application. I load my Dynamic menu When I open a New Document.This works fine in in the MDI Application. The problem that I got now is that When I add " ProfUIS" for my MDI Application I could not use that Dynamic Menu. What Happens is that the Menu that I give in the DocTemplate Adds to the ChildFrame. While using "ProfUIS" I think some where the menu that is added to the Child Frame is Registered.So I could not remove the menu and add my Own Dynamic Menu.Can any one have solution for this.
|
|
ven rag
|
Dec 26, 2005 - 12:19 AM
|
Hi Tect support, Sorry. Now I got ur code in correct format. The Pop Up is working fine. Now the code that I need to Do is that I need to overwrite CExtMenuControlBar::_UpdateMenuBar() internal virtual method.So that I can load my Dynamic Menu instead of the Menu that is there in Resource. How to Over Write CExtMenuControlBar::_UpdateMenuBar() funtion. ////////////////////////////// I have Derived in the CMainFrame Class like this class CMainFrame : public CMDIFrameWnd , public CExtDynamicBarSite { protected: // control bar embedded members CExtMenuControlBar m_wndMenuBar; } I think I have to Overwrite the function in the CMainFrame. "How to Dynamically create the MenuBar and add PopMenu in that Dynamically Created MenuBar and How to overwrite CExtMenuControlBar::_UpdateMenuBar() " Thank u.
|
|
Technical Support
|
Dec 26, 2005 - 7:15 AM
|
You should use your CExtMenuControlBar -derived class like as follows: class CMyMenuBar : CExtMenuControlBar
{
public:
virtual BOOL _UpdateMenuBar(
BOOL bDoRecalcLayout = TRUE
);
}; The _UpdateMenuBar() method implementation should be coped from original method with adding your custom menu bar buttons into required locations: BOOL CMyMenuBar::_UpdateMenuBar(
BOOL bDoRecalcLayout // = TRUE
)
{
SetButtons(); // remove all buttons
// remove all previously allocated command identifiers
// for menu buttons
VERIFY(
g_CmdManager->CmdRemoveByMask(
g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() ),
(DWORD)CExtCmdItem::STATE_MENUBAR_TMP
)
);
CMenu * pMenu = GetMenu();
if( pMenu->GetSafeHmenu() != NULL )
{
bool bRevertRTL = OnQueryRevertRTL();
UINT nMenuItemCount = pMenu->GetMenuItemCount();
for( UINT nMenuItemIndex = 0; nMenuItemIndex < nMenuItemCount; nMenuItemIndex++ )
{
UINT nInsertButtonLocation =
bRevertRTL
? 0
: nMenuItemIndex
;
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 sText;
mii.dwTypeData =
sText.GetBuffer( __MAX_UI_ITEM_TEXT );
ASSERT( mii.dwTypeData != NULL );
if( mii.dwTypeData == NULL )
{
ASSERT( FALSE );
return FALSE;
}
if( ! pMenu->GetMenuItemInfo(
nMenuItemIndex,
&mii,
TRUE
)
)
{
sText.ReleaseBuffer();
ASSERT( FALSE );
return false;
}
sText.ReleaseBuffer();
BOOL bAppendMdiWindowsMenu = FALSE;
UINT nCmdID = 0;
CExtCmdItem * pCmdItem = NULL;
if( mii.hSubMenu == NULL )
{
nCmdID = mii.wID;
if( nCmdID == ID_SEPARATOR )
{
if( ! InsertButton(
nInsertButtonLocation,
nCmdID,
FALSE
)
)
{
ASSERT( FALSE );
return FALSE;
}
continue;
} // if( nCmdID == ID_SEPARATOR )
ASSERT( CExtCmdManager::IsCommand(nCmdID) );
pCmdItem =
g_CmdManager->CmdGetPtr(
g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() ),
nCmdID
);
ASSERT( pCmdItem != NULL );
} // if( mii.hSubMenu == NULL )
else
{
pCmdItem =
g_CmdManager->CmdAllocPtr(
g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() )
);
if( pCmdItem == NULL )
{
ASSERT( FALSE );
return FALSE;
} // if( pCmdItem == NULL )
nCmdID = pCmdItem->m_nCmdID;
ASSERT( CExtCmdManager::IsCommand(nCmdID) );
pCmdItem->StateSetMenubarTemp();
pCmdItem->StateSetBasic();
if( _IsMdiApp() && (! m_sMdiWindowPopupName.IsEmpty() ) )
{
CExtSafeString _sText(sText);
_sText.TrimLeft();
_sText.TrimRight();
while( _sText.Replace(_T("&"),_T("")) > 0 )
{
_sText.TrimLeft();
_sText.TrimRight();
} // while( _sText.Replace(_T("&"),_T("")) > 0 )
if( _sText == m_sMdiWindowPopupName )
bAppendMdiWindowsMenu = TRUE;
} // if( _IsMdiApp() && (! m_sMdiWindowPopupName.IsEmpty() ) )
} // else from if( mii.hSubMenu == NULL )
ASSERT( pCmdItem != NULL );
if( pCmdItem->m_sToolbarText.IsEmpty() )
pCmdItem->m_sToolbarText = sText;
if( pCmdItem->m_sMenuText.IsEmpty() )
pCmdItem->m_sMenuText = sText;
if( ! InsertButton(
nInsertButtonLocation,
nCmdID,
FALSE
)
)
{
ASSERT( FALSE );
return FALSE;
}
if( mii.hSubMenu != NULL )
{
ASSERT( ::IsMenu(mii.hSubMenu) );
SetButtonMenu(
nInsertButtonLocation,
mii.hSubMenu,
FALSE,
FALSE,
FALSE
);
} // if( mii.hSubMenu != NULL )
if( bAppendMdiWindowsMenu )
{
VERIFY(
MarkButtonAsMdiWindowsMenu(
nInsertButtonLocation,
TRUE
)
);
} // if( bAppendMdiWindowsMenu )
} // for( UINT nMenuItemIndex = 0; nMenuItemIndex < nMenuItemCount; nMenuItemIndex++ )
ASSERT( m_pRightBtn == NULL );
m_pRightBtn = OnCreateBarRightBtn();
if( m_pRightBtn != NULL )
{
ASSERT_VALID( m_pRightBtn );
ASSERT_KINDOF( CExtBarContentExpandButton, m_pRightBtn );
m_buttons.Add( m_pRightBtn );
} // if( m_pRightBtn != NULL )
} // if( pMenu->GetSafeHmenu() != NULL )
/////////////////////////////////////////////////////
//
// TO DO:
// insert custom menu bar’s buttons here
//
/////////////////////////////////////////////////////
if( _IsMdiApp() )
{
if( !IsOleIpObjActive() )
if( _InstallMdiDocButtons( FALSE ) )
bDoRecalcLayout = TRUE;
VERIFY( _SyncActiveMdiChild() );
}
if( bDoRecalcLayout )
{
Invalidate();
_RecalcLayoutImpl();
UpdateWindow();
if( m_pDockSite != NULL )
{
CFrameWnd * pFrame = GetParentFrame();
ASSERT_VALID( pFrame );
if( pFrame->IsKindOf(RUNTIME_CLASS(CExtMiniDockFrameWnd)) )
pFrame->SetWindowPos(
NULL, 0, 0, 0, 0,
SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE
|SWP_NOZORDER|SWP_NOOWNERZORDER
|SWP_FRAMECHANGED
);
} // if( m_pDockSite != NULL )
} // if( bDoRecalcLayout )
return TRUE;
} Please note each button requires a unique command identifier. You should allocate it in the command manager as the method above performs for each popup sub-menu button: CExtCmdItem * pCmdItem =
g_CmdManager->CmdAllocPtr(
g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() )
);
if( pCmdItem == NULL )
{
ASSERT( FALSE );
return FALSE;
} // if( pCmdItem == NULL )
pCmdItem->StateSetMenubarTemp();
pCmdItem->StateSetBasic(); After that you can use the allocated command identifier to crate the button in menu bar: INT nInsertButtonPosition = . . .
LPCTSTR sText = _T("Button name");
pCmdItem->m_sToolbarText = sText;
pCmdItem->m_sMenuText = sText;
if( ! InsertButton(
nInsertButtonPosition,
pCmdItem->nCmdID,
FALSE
)
)
{
ASSERT( FALSE );
return FALSE;
} Finally, you can assign HMENU to inserted button: HMENU hMenu = . . .
SetButtonMenu(
nInsertButtonLocation,
hMenu,
FALSE,
FALSE,
FALSE
);
|
|
ven rag
|
Dec 27, 2005 - 6:52 AM
|
Iam calling the _UpdateMenuBar(TRUE); from CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) function This is How I call. CExtCmdItem * pCmdItem = g_CmdManager->CmdAllocPtr(g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() ) ); if( pCmdItem == NULL ) { ASSERT( FALSE ); return FALSE; } // if( pCmdItem == NULL ) pCmdItem->StateSetMenubarTemp(); pCmdItem->StateSetBasic(); CMyMenuBar m_menubar; m_menubar._UpdateMenuBar(TRUE); After this I get the Error as ExtCmdManager.cpp Line :2589 When I Ignore the Program is running .But no change in the Menu Bar Ater Calling _UpdateMenuBar(TRUE) I am inserting as u have said INT nInsertButtonPosition = 1; LPCTSTR sText = _T("File"); pCmdItem->m_sToolbarText = sText; pCmdItem->m_sMenuText = sText; if( ! InsertButton( nInsertButtonPosition, pCmdItem->nCmdID, FALSE ) ) { ASSERT( FALSE ); return FALSE; } I get an error as InsertButton undeclared identifier nCmdID is not the member of CExtCmdItem. How to solve these problem.Also I want to know that Whether I can Create the Menu that I want to create Dynamically in the Menu bar. Suppose I want the Menu Bar to contain ///////////////////////////// File View------------------------>Root Menu in the Menu bar New Large--------------------------------->Sub Menu Under the Root. Open Small Exit ////////////////////////////// How to do these things Dynamically. If I want to "File"(in the Menu) to there it as to be added in the Dynamic Menu and All the SubMenu Menu under the File(New,Open,Exit) should. Suppose I don’t File to be not to be added it should not be added and also the SubMenu shold not be added. Suppose I don’t want to add a particular SubMenu(for eg: New under File)then I should remove it. This is what I like to do. "I did solve this problem using MFC".But now I want to do it using PRO-UIS. How to solve this problem? Thank u
|
|
Technical Support
|
Dec 27, 2005 - 9:34 AM
|
You did not follow what described earlier. Your code allocates a command identifier marked as the command which is used internally by the menu bar by calling the pCmdItem->StateSetMenuBarTemp() code, invokes the CExtMenuControlBar::_UpdateMenuBar() method where all the marked commands are removed from the command manager and finally tries to use the command identifier (which is not available in the command manager) to create the menu bar button. Please re-arrange these steps: 1) invoke _UpdateMenuBar() 2) allocate a command item as you did 3) create a button in the menu bar as you did
|
|
ven rag
|
Dec 27, 2005 - 11:18 PM
|
VERIFY( g_CmdManager->CmdRemoveByMask( g_CmdManager->ProfileNameFromWnd( GetSafeHwnd() ), (DWORD)CExtCmdItem::STATE_MENUBAR_TMP ));--------------------->Error in this line.This code comes inside _UpdateMenuBar(). Assertion Error comes after this line.(HOW TO SOLVE THIS ERROR) The Error is in ExtCmdManager.cpp file. By the way I followed the steps that u have told me.Please read the errors that I mentioned in the Last Message also. Thank u.
|
|
ven rag
|
Dec 24, 2005 - 1:41 AM
|
"The Problem with the code that u have sent." The problem with this is that it insert the item in the existing Menu. for eg:I have the Menu like this.(IDR_MDIMENTYPE ) In this Menu I have the Following Menu File Edit View ------------------->Root Menu Open Draw Large-------------------->Sub Menu Under each Root New Paste Small Exit This the Menu that is Created in the Resourse //////////////////////////////////// nItemPos = pPopup->ItemFindPosForCmdID( __ID_MDIWND_DLGWINDOWS ); pPopup->ItemInsertCommand( ID_APP_ABOUT, nNewPos, "About (1)" ); ////////////////////////////// After Adding this code the About Box is Added to All the Root Menu .The Out put is given below. File Edit View ------------------->Root Menu Open Draw Large-------------------->Sub Menu Under each Root New Paste Small About(1) About(1) About(1) Exit ////////////////////////////// What I want to Do is .I don’t want the Default Menu that is (IDR_MDIMENTYPE ) which I added in the Resource. ================================================ I don’t want this Menu to be added in the Menu File Edit View ------------------->Root Menu Open Draw Large-------------------->Sub Menu Under each Root New Paste Small About(1) About(1) About(1) Exit =================================================== The Below Menu is the One That I need to add Dynamically in the Menu Bar while I Open a New Document. Shape Help-------------------------------->Root Menu Circle About------------------------------>Sub Menu under the Root Rect Square How Solve this Problem.Hope this time I am clear.
|
|
Technical Support
|
Dec 24, 2005 - 11:10 AM
|
It seems you did not follow exactly what we’d described in our message. Here is the code from your message: nItemPos = pPopup->ItemFindPosForCmdID( __ID_MDIWND_DLGWINDOWS );
pPopup->ItemInsertCommand( ID_APP_ABOUT, nNewPos, "About (1)" ); The first line searches for the __ID_MDIWND_DLGWINDOWS command in the popup menu being displayed. The search result is not analyzed in your code. The nItemPos variable is -1 if the __ID_MDIWND_DLGWINDOWS command is not found. Your code ignores this and simply adds the ID_APP_ABOUT command regardless of any conditions. Your code should look like as follows: nItemPos = pPopup->ItemFindPosForCmdID( __ID_MDIWND_DLGWINDOWS );
if( nItemPos >= 0 )
{
pPopup->ItemRemove( nItemPos );
int nNewPos = nItemPos;
pPopup->ItemInsertCommand( ID_APP_ABOUT, nNewPos, "About (1)" );
}
|
|
ven rag
|
Dec 23, 2005 - 3:41 AM
|
//The Menu IDR_MDIMENUTYPE is the Menu that is added in the Childframe. pDocTemplate = new CMultiDocTemplate( IDR_MDIMENTYPE,//The Menu that Will be added whenever I open a New Document RUNTIME_CLASS(CMDIMENUDoc), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CMDIMENUView)); //This is how I add the Dynamic Menu CMenu m_MenuMain; CMenu *m_pMainMenu; CMenu m_menuPopup; CMenu m_submenu; m_MenuMain.CreateMenu(); m_menuPopup.CreatePopupMenu(); m_menuPopup.AppendMenu (MF_STRING, 12, "E&xit"); m_MenuMain.AppendMenu (MF_POPUP,(UINT)m_menuPopup.Detach (),"&File"); m_menuPopup.CreatePopupMenu (); m_submenu.CreateMenu(); m_submenu.AppendMenu (MF_STRING,(UINT)m_menuPopup.m_hMenu,"&Square\tF9"); m_submenu.AppendMenu (MF_STRING, (UINT)m_menuPopup.m_hMenu, "&Rectangle\tF10"); m_submenu.AppendMenu (MF_STRING, (UINT)m_menuPopup.m_hMenu, "&Circle\tF12"); m_menuPopup.AppendMenu (MF_POPUP, (UINT) m_submenu.Detach(),"&Shapes"); m_MenuMain.AppendMenu (MF_POPUP,(UINT) m_menuPopup.Detach (),"&Options"); AfxGetMainWnd()->SetMenu(&m_MenuMain); AfxGetMainWnd()->DrawMenuBar(); After I add the Dynamic menu the Menu that I was added in the Resource will not be there. The Menu that I added in Dynamically will be added. This works fine in my MFC MDI Applcation. Now I add "ProfUIS" to my MFC MDI Application.The Menu(IDR_MDIMENTYPE) is displayed always.I could not add my Dynamic menu. I want Prof UIS and also the Dynamic menu. I want to add the Dynamic menu in place of IDR_MDIMENTYPE and add ProUIS to it How to rectify this problem.
|
|
Technical Support
|
Dec 23, 2005 - 12:15 PM
|
We explained you how to modify popup menus on-the-fly in our previous message. The top level menu line is controlled by the CExtMenuControlBar window which is a kind of the CExtToolControlBar toolbar window. The top level menu is a set of toolbar buttons which are instances of the CExtBarButton objects. The CExtMenuControlBar::UpdateMenuBar() method tells the menu bar to rebuilt its buttons. This method invokes the CExtMenuControlBar::_UpdateMenuBar() internal virtual method which does this work. You can override the CExtMenuControlBar::_UpdateMenuBar() internal virtual method in your own CExtMenuControlBar -derived class. In this method please invoke the parent method and insert any dynamically created buttons into any location you need. This can be done easier if the menu resource contains all the "dynamic" popup sub menus and your _UpdateMenuBar() method just removes them when they are redundant.
|
|
ven rag
|
Dec 21, 2005 - 9:36 PM
|
I want my menu to be in ProfUIS fromat only. How to create "CExtMenuControlBar" Menu "Dynamically".
|
|
Technical Support
|
Dec 22, 2005 - 12:46 PM
|
Please open the menu resource which is used for the Prof-UIS menu bar and insert some ID_MY_MENU_MARKER command in some popup menu. The menu item text and tip text properties of this item are not important. This command item in menu will be used for replacing it with a set of dynamic menu items on-the-fly immediately before the menu appears on the screen. Now, we need to handle the CExtPopupBaseWnd::g_nMsgPrepareOneMenuLevel registered windows message in your application. The message handler function, which should be added to the main frame or dialog window, will search for the ID_MY_MENU_MARKER menu item in each displayed sub menu. If this menu item is found successfully, then the handler method removes this menu item and inserts some items instead. Here is the method declaration, message map’s entry and implementation: afx_msg LRESULT OnExtMenuPrepareOneLevel(WPARAM wParam, LPARAM lParam);
ON_REGISTERED_MESSAGE(
CExtPopupBaseWnd::g_nMsgPrepareOneMenuLevel,
OnExtMenuPrepareOneLevel
)
LRESULT CPageButtons::OnExtMenuPrepareOneLevel(WPARAM wParam, LPARAM lParam)
{
lParam; // unused parameter
CExtPopupMenuWnd::MsgPrepareMenuData_t * pData =
reinterpret_cast
< CExtPopupMenuWnd::MsgPrepareMenuData_t * >
( wParam );
ASSERT( pData != NULL );
CExtPopupMenuWnd * pPopup = pData->m_pPopup;
ASSERT( pPopup != NULL );
INT nReplacePos =
pPopup->ItemFindPosForCmdID( ID_MY_MENU_MARKER );
if( nReplacePos < 0 )
return 0;
VERIFY( pPopup->ItemRemove(nReplacePos) );
// insert one command
pPopup->ItemInsertCommand(
ID_APP_ABOUT,
nReplacePos,
"About (1)"
);
// insert one more command
pPopup->ItemInsertCommand(
ID_APP_ABOUT,
nReplacePos + 1,
"About (2)"
);
// and insert one more command
pPopup->ItemInsertCommand(
ID_APP_ABOUT,
nReplacePos + 2,
"About (3)"
);
return ( ! 0 );
} Now please compile and run your program, open the menu bar’s menu which contains the ID_MY_MENU_MARKER command item. You should see three "About" commands instead of the ID_MY_MENU_MARKER command.
|
|
Technical Support
|
Dec 21, 2005 - 10:38 AM
|
The CExtMenuControlBar window kills the standard menu line in the main frame window and builds its buttons with sub menus to emulate the standard menu line. So, you cannot access the HMENU /CMenu of the main frame window. Please let us know which menu you wish to build dynamically and we will provide you with a solution.
|
|