Archived

This topic is now archived and is closed to further replies.

Shannon Barber

MFC Menu not working

Recommended Posts

Shannon Barber    1681
Ok, this has been bothering me for a while... Every now and then, when I''m hacking out some in a MFC dialog test program, the menu items stop responding to the atl-<letter> hotkeys. When I hit alt the short-cut letters in the menu underline themselves - but when I hit the letter the menu doesn''t drop down. e.g. <alt>-F doesn''t work. At an eariler stage in the project the menu did work. Has anyone ever had this happen to them? Magmai Kai Holmlor "Oh, like you''ve never written buggy code" - Lee "What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO

Share this post


Link to post
Share on other sites
Stoffel    250
Never works? I know that sometimes if you hit the alt-key once, the system icon (top-left) is highlighted, and trying to hit alt-letter after that basically does nothing until you hit alt by itself again. Is this what you''re talking about, or does the menu stop working altogether in your dialog?

Share this post


Link to post
Share on other sites
Shannon Barber    1681
all together
When I hit alt the menu highlights, but when I hit a key (I keep holding down alt) nothing happens.

It''s happened to me many times; I kinda figure it''s something that I always do that no-one else ever does

I can still click them with the mouse and they work. Actually, the menu items work fine - it''s the menu itself that stops responding to short-cuts.

So, this has never happened to ya?

Magmai Kai Holmlor

"Oh, like you''ve never written buggy code" - Lee

"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO

Share this post


Link to post
Share on other sites
JonStelly    127
I''m guessing you''re handling a message somewhere incorrectly. Check WM_COMMAND / OnCommand messages, as well as your handling in PreTranslate if you''re doing any processing there. An easy answer is that you might be returning the wrong value.

Share this post


Link to post
Share on other sites
Shannon Barber    1681
Steps to Reproduce the problem:

Make an MFC Dialog App
Add a menu resource (add file-open, help-about)
Set the dialog to use the menu
Add event handle to ID_HELP_ABOUT (I do CAboutDlg().DoModal()
Goto the dialog editor, double click OK, go back and double click Cancel (get the OnOK OnCancel overrides)
compile run (everything should work)
Remove the OK and Cancel buttons
compile run - the menu is broken!
(Work around is to make the buttons invisible)

Magmai Kai Holmlor

"Oh, like you''ve never written buggy code" - Lee

"What I see is a system that _could do anything - but currently does nothing !" - Anonymous CEO

Share this post


Link to post
Share on other sites
null_pointer    289
I have had MFC projects where the compiler suddenly starts producing a bad executable, even if I comment all my code out. The problem is that whenever the executable is run, if a user moves the mouse over a menu item the executable crashes.

It is very frustrating as I have to cut+paste the source files, delete the project, create a new project, and cut+paste in the same source files. Then it works fine.

I thought you were using ATL or whatever its called.

Share this post


Link to post
Share on other sites
Gorky    122
Deleting the buttons but leaving the code is probably not a good idea.

There is still the message mapping. And this could possibly be screwing up the chances that the menu could be activated.

It''s common to just rename the buttons something else.
Or in your case, delete the code created by the class wizard.

Share this post


Link to post
Share on other sites
Stoffel    250
Menus in dialogs are extremely limited. The stuff in the MFC classes for SDI/MDI does a lot of stuff. One of the weird things is that there''s no way to do a set-check on a menu item in a dialog using the boilerplate code through updateUI.

In order to get my dialog app to work, I added this method:
  
void PromptPlayDlg::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex,
BOOL bSysMenu)
{
// doesn''t do anything (Default)

// CDialog::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);


// copied from CFrameWnd, since CDialog doesn''t support it:


if (bSysMenu)
return; // don''t support system menu


ASSERT(pPopupMenu != NULL);
// check the enabled state of various menu items


CCmdUI state;
state.m_pMenu = pPopupMenu;
ASSERT(state.m_pOther == NULL);
ASSERT(state.m_pParentMenu == NULL);

// determine if menu is popup in top-level menu and set m_pOther to

// it if so (m_pParentMenu == NULL indicates that it is secondary popup)

HMENU hParentMenu;
if (AfxGetThreadState()->m_hTrackingMenu == pPopupMenu->m_hMenu)
state.m_pParentMenu = pPopupMenu; // parent == child for tracking popup

else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL)
{
CWnd* pParent = GetTopLevelParent();
// child windows don''t have menus -- need to go to the top!

if (pParent != NULL &&
(hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
{
int nIndexMax = ::GetMenuItemCount(hParentMenu);
for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
{
if (::GetSubMenu(hParentMenu, nIndex) == pPopupMenu->m_hMenu)
{
// when popup is found, m_pParentMenu is containing menu

state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
break;
}
}
}
}

state.m_nIndexMax = pPopupMenu->GetMenuItemCount();
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
state.m_nIndex++)
{
state.m_nID = pPopupMenu->GetMenuItemID(state.m_nIndex);
if (state.m_nID == 0)
continue; // menu separator or invalid cmd - ignore it


ASSERT(state.m_pOther == NULL);
ASSERT(state.m_pMenu != NULL);
if (state.m_nID == (UINT)-1)
{
// possibly a popup menu, route to first item of that popup

state.m_pSubMenu = pPopupMenu->GetSubMenu(state.m_nIndex);
if (state.m_pSubMenu == NULL ||
(state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
state.m_nID == (UINT)-1)
{
continue; // first item of popup can''t be routed to

}
state.DoUpdate(this, FALSE); // popups are never auto disabled

}
else
{
// normal menu item

// Auto enable/disable if frame window has ''m_bAutoMenuEnable''

// set and command is _not_ a system command.

state.m_pSubMenu = NULL;

// FrameWnd has a m_bAutoMenuEnable, default is true, so:

// state.DoUpdate(this, m_bAutoMenuEnable && state.m_nID < 0xF000);

state.DoUpdate(this, state.m_nID < 0xF000);
}

// adjust for menu deletions and additions

UINT nCount = pPopupMenu->GetMenuItemCount();
if (nCount < state.m_nIndexMax)
{
state.m_nIndex -= (state.m_nIndexMax - nCount);
while (state.m_nIndex < nCount &&
pPopupMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
{
state.m_nIndex++;
}
}
state.m_nIndexMax = nCount;
}

}

Share this post


Link to post
Share on other sites