Link to home
Start Free TrialLog in
Avatar of GlennBrand
GlennBrand

asked on

Need to disable PopUp Menu items

I need to disable the menu items that are not applicable at various places in the application.
The command messages are not being routed through the OnUpdate handlers.
I have looked at a few issues that talk about this. For example using "this" on the following does not work:
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);
Attaching it to the mainframe does something but still not going through the handlers
void CEHRTreeCtrl::OnUpdatePopupPopulatenormalcase(CCmdUI* pCmdUI) 
{
	if (m_bWorkFlowTree || !IsPatientData())
		pCmdUI->Enable(false);
	else
		pCmdUI->Enable(true);
}
 
void CEHRTreeCtrl::OnContextMenu(CWnd*, CPoint point)
{
 
	// CG: This block was added by the Pop-up Menu component
	{
		if (point.x == -1 && point.y == -1){
			//keystroke invocation
			CRect rect;
			GetClientRect(rect);
			ClientToScreen(rect);
 
			point = rect.TopLeft();
			point.Offset(5, 5);
		}
 
		CMenu menu;
		VERIFY(menu.LoadMenu(CG_IDR_POPUP_EHRDECISION_TREE));
 
		CMenu* pPopup = menu.GetSubMenu(0);
		ASSERT(pPopup != NULL);
		CWnd* pWndPopupOwner = this;
 
		// this sets it for all menu items
		m_bHasChildren = IsNodeChildrenOnDemand();
		if(!m_bHasChildren)
		{
			pPopup->ModifyMenu( ID_EDIT_COPY, MF_BYCOMMAND, ID_EDIT_COPY, _T("&Copy Selected Item") );
			pPopup->ModifyMenu( ID_EDIT_CUT, MF_BYCOMMAND, ID_EDIT_CUT, _T("&Cut Selected Item") );
			CString strMenuItem = _T("&Delete Selected Item");
			if (GetSelectedCount() > 0)
			{
				 strMenuItem += _T("s");
			}
			pPopup->ModifyMenu( ID_EDIT_DELETE, MF_BYCOMMAND, ID_EDIT_DELETE, strMenuItem );
			pPopup->ModifyMenu( ID_EDIT_FIND, MF_BYCOMMAND, ID_EDIT_FIND, _T("&Find Item or Sub Tree") );
			pPopup->ModifyMenu( ID_EDIT_PASTE, MF_BYCOMMAND, ID_EDIT_PASTE, _T("&Paste Selected Item") );
		}
		
		pPopup->ModifyMenu( ID_POPUP_INSERTSUBTREE, MF_BYCOMMAND, ID_POPUP_INSERTSUBTREE, _T("&Insert Items After Selected Item") );
		
		if (!IsNodeManagementTree())
		{
			pPopup->DeleteMenu(ID_POPUP_ATTACHNODESTOSELECTEDFORM, MF_BYCOMMAND);
		}
		else if (IsFormManagementTree() || IsReportManagementTree())
		{
			pPopup->ModifyMenu( ID_POPUP_ADDSUBTREE, MF_BYCOMMAND, ID_POPUP_ADDSUBTREE, _T("&Add Multiple New Nodes") );
		}
		CWnd* pWnd = GetParent()->GetParent()->GetParent();
		pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
			this);
	}
}

Open in new window

Avatar of DanRollins
DanRollins
Flag of United States of America image

Have you seen this article:
   When Update Handlers Are Called
   http://msdn.microsoft.com/en-us/library/essk9ab2.aspx
I can't tell from your code, but... there has to be an ON_UPDATE_COMMAND_UI entry and (this is the most common oversight) there must also be an  ON_COMMAND entry somewhere with the same command ID
Also, command UI is usually in the MainFrame, so that's what you will typically used as the owning window in the TrackPopupMenu call
Instead of

                CWnd* pWnd = GetParent()->GetParent()->GetParent();
                pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
                        this);

try to use

                CWnd* pWnd = GetParentFrame();
                pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
                        pWnd);

See GetParentFrame details at
http://msdn.microsoft.com/en-us/library/6f45sskz.aspx
Avatar of GlennBrand
GlennBrand

ASKER

I tried that and a frame window is returned but when I use it all the menu items are greyed out meaning that it can't find the message handlers that are working now in the tree. The frame window is to the property dialog box that contains the tree.

My question is why can it find all the message handlers for the messages them selles but not on the OnUpdate messages. It doesn't make sense.

Is there a way to redirect whatever messages to the tree itself?
What you describe is symptomatic of having an ON_UPDATE_COMMAND_UI entry and no ON_COMMAND entry (see the article I cited, above).  
I suggest using Spy++ and watch for the WN_INITMENUPOPUP message.  A CFrameWnd-derived object should get that message and do the command U/I enabling.
Yes I had one for each one. To no avail. Even tried redirecting the message to the tree itself but no luck.
I finally found another solution.
I had to do what I did in the OnContextMenu in the code snippet attached.
Thanks for trying. I know this is a problem for many people.
		if (IsFormManagementTree() || IsReportManagementTree() || m_bWorkFlowTree)
		{
			pPopup->EnableMenuItem(ID_POPUP_POPULATENORMALCASE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_POPUP_MOVESUBTREE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_EDIT_CUT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
		}
		if (m_bWorkFlowTree || IsDecisionTree())
		{
			pPopup->EnableMenuItem(ID_POPUP_ADDSUBTREE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_POPUP_INSERTSUBTREEBEFORE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_POPUP_INSERTSUBTREE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_POPUP_SHOWEDITOR, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_POPUP_SHOWSCRIPTEDITOR, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
		}
		if (!m_bWorkFlowTree && IsDecisionTree())
		{
			pPopup->EnableMenuItem(ID_POPUP_MODIFYITEMPROPERTIES, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_POPUP_EDITITEMTEXT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_EDIT_CUT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_EDIT_COPY, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_EDIT_DELETE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_POPUP_MOVESUBTREE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_EDIT_PASTE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_POPUP_PASTEBEFORESUBTREE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
			pPopup->EnableMenuItem(ID_POPUP_PASTEAFTERSUBTREE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
		}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of DanRollins
DanRollins
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I tried using the main frame also. The menu changed completely with many greyed out options and some enabled functions. It was as if the main frame had other items it found with similar ID values. IN this case the tree is in a DLL so it is possible that some of the IDs are the same as in the main app.
But more importantly is it customary to use the main window then?
What is happening and how should I setup my handlers. None of the handlers seem to have been called in the tree class itself which currently works the way I coded it.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
My solution is the only other way from what I can tell besides what DanRollins writes.