15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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