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: Roma
Ash 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 Williams
Cheers, 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
| Вернуться в корень Архива
|