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

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


CMenu: Disabling/Dimmint a Menu Item

Peter Ingraham -- ingraham@vci.com
Tuesday, November 26, 1996

Environment: VC++ 4.2-flat, NT 4.0

I am trying to disable and dim menu items using CMenu::EnableMenuItem,
but I am not having any success.  The simple example below
illustrates the problem:

	CMenu* pMnuMain = GetMenu();
	CMenu mnuMain;
	mnuMain.Attach(pMnuMain->m_hMenu);
	mnuMain.EnableMenuItem(ID_SHOW_FILES, MF_BYCOMMAND | MF_GRAYED);
	mnuMain.Detach();

The result is that the menu item is neither dimmed not disabled.
To test the code, I replaced the "EnableMenuItem" line with:

	mnuMain.CheckMenuItem(ID_SHOW_FILES, MF_BYCOMMAND | MF_CHECKED);

from which I got the expected result (the item was checked).

It has been suggested that I use the ON_UPDATE_COMMAND_UI interface,
but the menu items I'm trying to control reside on nested pop-up
menus that are dynamically created during program initialization
from information in a database.  The item command IDs are dynamically
assigned during that time, and I need to control the items
"by command", so that I don't have to keep track of which item
position on which nested pop-up menu (a bookkeeping nightmare).

The code above is a simple illustration of the problem. If I can get
that to work, I have no problem with the rest.  Why doesn't this
code work?



Randy Taylor -- randy_taylor@ebt.com
Wednesday, November 27, 1996

Try handling the WM_INITMENUPOPUP in your frame class.
There is a macro for it: ON_INITMENUPOPUP

Then the function in your frame class can look something like this:

void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL
bSysMenu) 
{   
   // Note: the nIndex is the zero based popup menu inclusive of the popups
   //       that you see when the main menu pops become visible. In other
   //       words, you count the cascading menus to get right index.

   CMenu *open;
   if (nIndex == ITEM_MENU_INDEX
      && pPopupMenu->GetMenuItemID(ITEM_MENU_1ST_NON_POPUP_INDEX)
                                   == ID_ITEM_IMPORT)
   {

      // Get the "Open" popup menu
      open = pPopupMenu->GetSubMenu(ITEM_MENU_OPEN_INDEX);
      ASSERT(open != NULL);

    // ... more code sniped from here. But this is where your enablment
code
   // can go!
}


Also, just because your menu's are dynamically created does NOT
mean that you can not use ON_UPDATE_COMMAND_UI handlers
for them: you probably know the range of ID's that you be dynamically
adding,
and you just create a single handler for the whole range in
your message map, like this:

ON_COMMAND_UPDATE_UI_RANGE(YOUR_FIRST_DYNAMENUID,
                                                        
YOUR_LAST_DYNAMENUID,
                        yourFunctionWhichHandlesTheWholeRange)

Then in yourFunction you can use CWnd::GetLastMessage to get the message
and pull the exact ID out of the WPARAM value of the message.

Have Fun,
Randy Taylor
randy_taylor@ebt.com



----------
> From: Peter Ingraham 
> To: mfc-l@netcom.com
> Subject: CMenu: Disabling/Dimmint a Menu Item
> Date: Tuesday, November 26, 1996 4:45 PM
> 
> Environment: VC++ 4.2-flat, NT 4.0
> 
> I am trying to disable and dim menu items using CMenu::EnableMenuItem,
> but I am not having any success.  The simple example below
> illustrates the problem:
> 
> 	CMenu* pMnuMain = GetMenu();
> 	CMenu mnuMain;
> 	mnuMain.Attach(pMnuMain->m_hMenu);
> 	mnuMain.EnableMenuItem(ID_SHOW_FILES, MF_BYCOMMAND | MF_GRAYED);
> 	mnuMain.Detach();
> 
> The result is that the menu item is neither dimmed not disabled.
> To test the code, I replaced the "EnableMenuItem" line with:
> 
> 	mnuMain.CheckMenuItem(ID_SHOW_FILES, MF_BYCOMMAND | MF_CHECKED);
> 
> from which I got the expected result (the item was checked).
> 
> It has been suggested that I use the ON_UPDATE_COMMAND_UI interface,
> but the menu items I'm trying to control reside on nested pop-up
> menus that are dynamically created during program initialization
> from information in a database.  The item command IDs are dynamically
> assigned during that time, and I need to control the items
> "by command", so that I don't have to keep track of which item
> position on which nested pop-up menu (a bookkeeping nightmare).
> 
> The code above is a simple illustration of the problem. If I can get
> that to work, I have no problem with the rest.  Why doesn't this
> code work?



Jim Lawson Williams -- jimlw@mail.ccur.com.au
Friday, November 29, 1996

I think you need something like

m_pApplication->m_pMainWnd->DrawMenuBar();

Regards,
Jim LW




Dong Chen -- d_chen@ix.netcom.com
Thursday, November 28, 1996

>
>The code above is a simple illustration of the problem. If I can get
>that to work, I have no problem with the rest.  Why doesn't this
>code work?
>
>

It is because you have the m_bAutoMenuEnable set as TRUE by default. There
is nothing wrong in your code. Simply add m_bAutoMenuEnable = FALSE in your
mainframe constructor, you will be happy. You need to take care of your
enable/disable funcitonality yourself though.
If the flag is set to true, in the call of OnInitMenuPopup by the framework,
it disable and enable a menu item according to if there exists a message
handler for that menu item. And this function is called every time the drop
down menu is about to be shown. But the framework doesn't care about the
check mark, so that's why the CheckMenuItem function works.




Mihir Dalal -- m_dalal@ECE.concordia.CA
Saturday, November 30, 1996


               Environment: VC++ 4.2-flat, NT 4.0
> > 
> > I am trying to disable and dim menu items using CMenu::EnableMenuItem,
> > but I am not having any success.  The simple example below
> > illustrates the problem:
> > 
> > 	CMenu* pMnuMain = GetMenu();
> > 	CMenu mnuMain;
> > 	mnuMain.Attach(pMnuMain->m_hMenu);
> > 	mnuMain.EnableMenuItem(ID_SHOW_FILES, MF_BYCOMMAND | MF_GRAYED);
> > 	mnuMain.Detach();
> > 
> > The result is that the menu item is neither dimmed not disabled.
> > To test the code, I replaced the "EnableMenuItem" line with:
> > 
> > 	mnuMain.CheckMenuItem(ID_SHOW_FILES, MF_BYCOMMAND | MF_CHECKED);
> > 
> > from which I got the expected result (the item was checked).
> > 
> > It has been suggested that I use the ON_UPDATE_COMMAND_UI interface,
> > but the menu items I'm trying to control reside on nested pop-up
> > menus that are dynamically created during program initialization
> > from information in a database.  The item command IDs are dynamically
> > assigned during that time, and I need to control the items
> > "by command", so that I don't have to keep track of which item
> > position on which nested pop-up menu (a bookkeeping nightmare).
> > 
> > The code above is a simple illustration of the problem. If I can get
> > that to work, I have no problem with the rest.  Why doesn't this
> > code work?


I have a piece of code here specifically written for enabling/disabling 
menu items. I hope it serves your purpose.

void CUnitrackView::OnUpdateBtnOn(CCmdUI* pCmdUI)
{
	if(Auto_Answer == 1)
	   pCmdUI->Enable(FALSE); // Disable the menu item
	else
	   pCmdUI->Enable(TRUE);  // Enable  the menu item
}

Note that I am intercepting the menu message in the view class. You could 
intercept in any other class you like. 

The Auto_Answer flag is set in the command handler for the same menu item 
like this:

void CUnitrackView::OnBtnOn()
{
    Auto_Answer = 1; 
    ::PostMessage(HWND_BROADCAST, WM_USER+5,0,0); // For Comm Window 
    .....
    .....
    .....
}

You could set this flag in any other message handler you like.
A similar pair for the menu item "BtnOff" which sets the Auto_Answer flag 
to 0 makes the BtnOn  & BtnOff menu items toggle their state, which 
means only one of the two remains enabled at a time. If set to BtnOn it 
is disabled by the OnUpdateBtnOn handler, & similarly for the BtnOff

Mihir Dalal
(University Researcher)

----------------------------------------------------------------------
 Mihir Dalal                        phone : 1-514-274-4430
 M.Engg(Electrical) Student         fax   : 1-514-421-1166
 Concordia University               emails: m_dalal@ece.concordia.ca
 1455, De Masseuneuve Blvd.   ///             dalal@vlsi.concordia.ca
 Montreal QC CANADA          (o o)          m_dalal@alcor.concordia.ca
--------------------------ooO-(_)-Ooo---------------------------------
   





| Вернуться в корень Архива |