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