让右键菜单(ContextMenu)也能通过响应OnUpdateCommandUI来设置状态

14 views
Skip to first unread message

LeoReis

unread,
Apr 6, 2008, 1:47:03 AM4/6/08
to 人生难得几回搏
//关键字 PopupMenu ContextMenu TrackPopupMenu OnUpdateCommandUI
// ON_WM_INITMENUPOPUP() OnInitMenuPopup

//右键弹出菜单中菜单项的状态不受OnUpdateCommandUI控制
//即右键弹出菜单在显示的时候没有Update消息,而只在点击之后才会调到OnUpdateCommandUI
//还好windows在PopupMenu弹出前会有一个WM_INITMENUPOPUP消息
//响应这个消息,将所有的菜单项调用一次Update

//让右键菜单也能通过响应OnUpdateCommandUI来设置状态
void CMonitorView::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex,
BOOL bSysMenu)
{
CTreeListView::OnInitMenuPopup(pPopupMenu, nIndex, bSysMenu);

// TODO: 在此处添加消息处理程序代码
TRACE("InitMenuPopup\n");

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 = this;
// 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, TRUE); // 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;
state.DoUpdate(this, FALSE);
}

// 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;
}
}
Reply all
Reply to author
Forward
0 new messages