disableing menu items - mfc

Started by
6 comments, last by crazy_andy 19 years, 1 month ago
I have an MFC program with: CMenu menu1; menu1.LoadMenu(IDR_MENU1); SetMenu(&menu1); now this loads a menu perfectly fine. When I cleck file new (ID_FILE_NEW) I want to disable it, so it cant be pressed again. Im trying: menu1.EnableMenuItem(ID_FILE_NEW,MF_BYCOMAND|MF_GRAYED); now this returns -1 suggesting the menu item doesn't exist, but when I click on the new button in the resource editor, it says ID ID_FILE_NEW so what am I doing wrong? I have been googleing for ages but no success
www.stickskate.com -> check it out, some gnarly stick skating movies
Advertisement
Try this:

CMenu* mmenu = GetMenu();
CMenu* submenu = mmenu->GetSubMenu(0);
submenu->EnableMenuItem(ID_FILE_NEW, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
nope, it just displayed the menu as normal.

here is my code:

class MFC_Tutorial_Window :public CFrameWnd{	CMenu menu1;   // dedines my menu	public:	HANDLE tThread;    MFC_Tutorial_Window()    {        Create(NULL,"Countdown - ALPHA V 0.2");  // creates window		menu1.LoadMenu(IDR_MENU1);  // sets up menu		SetMenu(&menu1);	//	UINT t = menu1.EnableMenuItem   // here I want to grey out the new button.(ID_FILE_NEW,MF_BYCOMMAND|MF_GRAYED);	}	void OnClickNew();		// defines function for when the new button is clicked	void OnClickStatusT1();	void OnClickExitApp();	void OnClickAbout();	int OnCreate(LPCREATESTRUCT lpCreateStruct);	void OnClose();    DECLARE_MESSAGE_MAP()       // sets up a message map, for message handling};

www.stickskate.com -> check it out, some gnarly stick skating movies
OK, ive still not had any luck, It just doesn't grey out. should I try creating the menu at runtime rather than as a resource?
www.stickskate.com -> check it out, some gnarly stick skating movies
I haven't touched MFC in ages, but I think this is the cause. Before displaying a menu MFC updates each menu item automatically. If it's missing an ON_COMMAND entry in a message map somewhere the menu item is automatically disabled, otherwise it's automatically enabled. CWinApp might have an update handler for ID_FILE_NEW by default, which is what is enabling the menu again.

This page describes a way to disable this. In your constructor for MFC_Tutorial_Window try adding this:
MFC_Tutorial_Window(){  m_bAutoMenuEnable = false;}
Ideally you'd have a message map entry to handle ID_FILE_NEW, and then you could simply add ON_UPDATE_COMMAND_UI(ID_FILE_NEW, OnUpdateFileNew) and call pCmdUI->Enable(false) from OnUpdateFileNew(CCmdUI* pCmdUI). How does your message map look like?

Update: Fixed incorrect information.

ok, I tried that but I'm getting an unresolved external. heres my message map

class MFC_Tutorial_Window :public CFrameWnd{	CMenu menu1;   // dedines my menu	public:	HANDLE tThread;    MFC_Tutorial_Window()    {        m_bAutoMenuEnable = false;        Create(NULL,"Countdown - ALPHA V 0.2");  // creates window		menu1.LoadMenu(IDR_MENU1);  // sets up menu		SetMenu(&menu1);//		UINT t = menu1.EnableMenuItem(ID_FILE_NEW,MF_BYCOMMAND|MF_GRAYED);	}	void OnClickNew();		// defines function for when the new button is clicked	void OnClickStatusT1();	void OnClickExitApp();	void OnClickAbout();	int OnCreate(LPCREATESTRUCT lpCreateStruct);	void OnClose();	void OnUpdateFileNew(CCmdUI* pCmdUI);    DECLARE_MESSAGE_MAP()       // sets up a message map, for message handling};BEGIN_MESSAGE_MAP( MFC_Tutorial_Window, CFrameWnd)     // begining of message map	ON_WM_CREATE()	ON_WM_CLOSE()	ON_COMMAND(ID_FILE_NEW,OnClickNew)               // when new is clicked do function OnClickNew()	ON_COMMAND(ID_HELP_ABOUT,OnClickAbout)	ON_COMMAND(ID_STATUS_TIMER1,OnClickStatusT1)	ON_COMMAND(IDEXIT,OnClickExitApp)	ON_UPDATE_COMMAND_UI(ID_FILE_NEW,OnUpdateFileNew)  // unresolved external hereEND_MESSAGE_MAP()										// end of message mapvoid OnUpdateFileNew(CCmdUI* pCmdUI){	pCmdUI->Enable(false);}void MFC_Tutorial_Window::OnClickNew()					// what to do when new is clicked{	newDialog dlg;									//defines dialog box	dlg.DoModal();}...
www.stickskate.com -> check it out, some gnarly stick skating movies
Oh, I probably should've worded things clearer.

Solution 1: Add the m_bAutoMenuEnable line. I don't know if this works.

Solution 2: Add ON_UPDATE_COMMAND_UI, this is probably the preferred solution since it integrates into MFC's message map, command updating framework. Ahh I wrote out a bunch of stuff describing how to implement it. Turns out you're just missing one thing.

void OnUpdateFileNew(CCmdUI* pCmdUI)// should bevoid MFC_Tutorial_Window::OnUpdateFileNew(CCmdUI* pCmdUI)


Of course now you won't be able to click the ID_FILE_NEW menuitem since it'll always be disabled. If you want to disable it after one click, try this:

class MFC_Tutorial_Window : public CFrameWnd{  bool m_bEnableFileNew;  MFC_Tutorial_Window()  {    m_bEnableFileNew = true;    // ...  }  // ...}void OnUpdateFileNew(CCmdUI* pCmdUI){  // the nice thing about this is that it'll also disable toolbar buttons that  // have an ID of ID_FILE_NEW  pCmdUI->Enable(m_bEnableFileNew);}void MFC_Tutorial_Window::OnClickNew(){  // disable file new. next time the menu displays MFC will call OnUpdateFileNew,  // which will disable the menu item.  m_bEnableFileNew = false;  newDialog dlg;	  dlg.DoModal();}// ...

thanks allot, that works great.
www.stickskate.com -> check it out, some gnarly stick skating movies

This topic is closed to new replies.

Advertisement