Dynamic menus
Ash Williams -- ash@digitalworkshop.co.uk Tuesday, March 04, 1997 Environment: Win95;MSVC 4.2b I've got two questions, the first is where do I put code to insert menus at run time? I have several menu items which need to live as long as a document does, and I'm not using the rc file to do it. I tried putting the code in OnNewDocument, but this must be too early since the menu items didn't appear. I tried CView::OnInitialUpdate and CView::OnUpdate just because, and nothing happened. Also I tried WM_INITMENU to no avail. In the end I put the code in OnDraw which sets a flag so that the menu only gets added to the first time, but obviously this is a bit of a hack. My second problem involves handling these dynamically added menu items, well getting them to be enabled actually. In my OnDraw I called CMenu& menu = *AfxGetMainWnd()->GetMenu()->GetSubMenu( 1 ); ContractException::assert( menu.InsertMenu( 3, MF_BYPOSITION | MF_STRING, 783, "Increase number" ) ? True : False ); menu.EnableMenuItem( 2, MF_BYPOSITION | MF_ENABLED ); for example, but this still left the item greyed. Also I hope to derive a class from CCmdTarget to handle menu clicks, assuming I've managed to enable them ;), and make an instance of it, but unfortunately the destructor seems to be protected (I created it with ClassWizard) - and I find it hard to believe that I can just make it public. Hope I've explained things well (I'm tired, that's my excuse) Any light shed is greatly appreciated. Ash
Syed -- sxs296@psu.edu Thursday, March 06, 1997 [Mini-digest: 2 responses] At 08:22 AM 3/4/97 GMT, you wrote: >Environment: Win95;MSVC 4.2b > >I've got two questions, the first is where do I put code to insert >menus at run time? I have several menu items which need to live as long >as a document does, and I'm not using the rc file to do it. > >I tried putting the code in OnNewDocument, but this must be too early >since the menu items didn't appear. I tried CView::OnInitialUpdate and >CView::OnUpdate just because, and nothing happened. Also I tried >WM_INITMENU to no avail. In the end I put the code in OnDraw which sets >a flag so that the menu only gets added to the first time, but >obviously this is a bit of a hack. It's much better if you could post the code as well. Probably you didn't do it correctly. You probably need to call DrawMenuBar (member function of CFrameWnd) after changing the menu. The online-documentation says:- DrawMenuBar(); Remarks Redraws the menu bar. If a menu bar is changed after Windows has created the window, call this function to draw the changed menu bar. -----From: RomaAsh Williams wrote: > > Environment: Win95;MSVC 4.2b > > I've got two questions, the first is where do I put code to insert > menus at run time? I have several menu items which need to live as long > as a document does, and I'm not using the rc file to do it. > > I tried putting the code in OnNewDocument, but this must be too early > since the menu items didn't appear. I tried CView::OnInitialUpdate and > CView::OnUpdate just because, and nothing happened. Also I tried > WM_INITMENU to no avail. In the end I put the code in OnDraw which sets > a flag so that the menu only gets added to the first time, but > obviously this is a bit of a hack. > > My second problem involves handling these dynamically added menu items, > well getting them to be enabled actually. In my OnDraw I called [snip] > > Hope I've explained things well (I'm tired, that's my excuse) Any > light shed is greatly appreciated. > > Ash Ash, query for 'DYNAMENU' in the on-line documentation. This is MFC example which shows how to handle dynamic menus. HTH, Roma
Paul B -- Paul.B.Folbrecht@JCI.Com Thursday, March 06, 1997 [Mini-digest: 2 responses] I can answer your second question: whether or not CCmdTarget's destructor is protected or not matters not a bit. All you need to do it declare a public destructor in your derived class. But- it is declared public. I checked. (I think what you might be saying is that the problem is that the destructor in your derived class is declared protected by ClassWizard. If so, then the answer is of course you can just change it to public.) -Paul Folbrecht Compuware Corp. ______________________________ Reply Separator _________________________________ Subject: Dynamic menus Author: ash@digitalworkshop.co.uk at Mailhub Date: 3/5/97 11:18 PM Environment: Win95;MSVC 4.2b I've got two questions, the first is where do I put code to insert menus at run time? I have several menu items which need to live as long as a document does, and I'm not using the rc file to do it. I tried putting the code in OnNewDocument, but this must be too early since the menu items didn't appear. I tried CView::OnInitialUpdate and CView::OnUpdate just because, and nothing happened. Also I tried WM_INITMENU to no avail. In the end I put the code in OnDraw which sets a flag so that the menu only gets added to the first time, but obviously this is a bit of a hack. My second problem involves handling these dynamically added menu items, well getting them to be enabled actually. In my OnDraw I called CMenu& menu = *AfxGetMainWnd()->GetMenu()->GetSubMenu( 1 ); ContractException::assert( menu.InsertMenu( 3, MF_BYPOSITION | MF_STRING, 783, "Increase number" ) ? True : False ); menu.EnableMenuItem( 2, MF_BYPOSITION | MF_ENABLED ); for example, but this still left the item greyed. Also I hope to derive a class from CCmdTarget to handle menu clicks, assuming I've managed to enable them ;), and make an instance of it, but unfortunately the destructor seems to be protected (I created it with ClassWizard) - and I find it hard to believe that I can just make it public. Hope I've explained things well (I'm tired, that's my excuse) Any light shed is greatly appreciated. Ash -----From: Ash WilliamsCheers, things are working okay now - the DYNAMENU sample was particularly helpful. Here's the code I did for anyone trying to do something similar: BOOL CProjectTestDoc::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { if( m_project.tryCommandTargets( nID, nCode, pExtra, pHandlerInfo ) == FALSE ) { isHandled = CDocument::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo); } return isHandled; } and for m_project (not derived from CCmdTarget or anything else)... BOOL MyProject::handleCommand(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) { BOOL handled = FALSE; if ( pHandlerInfo == 0 ) { if ( nID == m_idMenuA ) { handled = TRUE; if ( nCode == CN_COMMAND ) { // menu item has been selected } else if ( nCode == CN_UPDATE_COMMAND_UI ) { ( ( CCmdUI* )pExtra )->Enable( /* some condition */ ); } } } return handled; } Thanks once again - Ash
Become an MFC-L member | Вернуться в корень Архива |