在运行时设置 CMenu 项提示
Set CMenu item prompt at runtime
如何在运行时设置 CMenu 项提示?我知道它可以在 VS 的资源编辑器中完成,但我没有这样的资源和动态创建菜单及其项目。
您可以使用 ModifyMenu
(https://msdn.microsoft.com/fr-fr/library/4tbfebs6.aspx)。呼叫可以是这样的:
pParentMenu->ModifyMenu(ID_MY_ITEM, MF_STRING, ID_MY_ITEM, "My new text");
pParentMenu
是指向父菜单的 CMenu
对象。 ID_MY_ITEM
是子菜单id。也可以 select 使用其索引更改菜单。
如果您使用的是 MFC Feature Pack,您将需要覆盖 MainFrame 的 OnMenuButtonToolHitTest
class:
BOOL CMainFrame::OnMenuButtonToolHitTest(CMFCToolBarButton* pButton, TOOLINFO* pTI)
{
if(!pButton)
return FALSE;
if(!pTI)
return FALSE;
if (pButton->m_nID == UINT(-1)) //not a menu-item, but an opener menu for a sub-menu
return FALSE;
// Stolen from CMFCToolBar::OnToolHitTest on file afxtoolbar.cpp
// It is not needed to do the GetMessageString part, because it already done
// on function CMFCPopupMenuBar::OnToolHitTest of afxpopupmenubar.cpp file, which
// supplies the two parts to the Tooltip Manager
CString strTipText;
TCHAR szFullText[256];
AfxLoadString(pButton->m_nID, szFullText);
AfxExtractSubString(strTipText, szFullText, 1, '\n');
pTI->lpszText = _tcsdup(strTipText);
return TRUE;
}
您必须在资源文件中定义与菜单 ID 完全相同的字符串;它们的格式是 Prompt text\nPrompt title
。我不确定,但我认为您唯一可以使用的新行是将标题与文本分开的行。
除了在使用鼠标悬停菜单时简单地显示提示之外,您可能还想做一些事情。您可以通过覆盖 MainFrame
class:
的 OnMenuSelect
来实现
void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
if (nItemID == ID_MENU_I_WANT_TO_PROCESS)
{
DoThings();
}
__super::OnMenuSelect(nItemID, nFlags, hSysMenu);
}
我建议您重写 MainFrame 上的 GetMessageString
函数 class 并在此处放置一个断点,以便您查看流程如何进行。
如何在运行时设置 CMenu 项提示?我知道它可以在 VS 的资源编辑器中完成,但我没有这样的资源和动态创建菜单及其项目。
您可以使用 ModifyMenu
(https://msdn.microsoft.com/fr-fr/library/4tbfebs6.aspx)。呼叫可以是这样的:
pParentMenu->ModifyMenu(ID_MY_ITEM, MF_STRING, ID_MY_ITEM, "My new text");
pParentMenu
是指向父菜单的 CMenu
对象。 ID_MY_ITEM
是子菜单id。也可以 select 使用其索引更改菜单。
如果您使用的是 MFC Feature Pack,您将需要覆盖 MainFrame 的 OnMenuButtonToolHitTest
class:
BOOL CMainFrame::OnMenuButtonToolHitTest(CMFCToolBarButton* pButton, TOOLINFO* pTI)
{
if(!pButton)
return FALSE;
if(!pTI)
return FALSE;
if (pButton->m_nID == UINT(-1)) //not a menu-item, but an opener menu for a sub-menu
return FALSE;
// Stolen from CMFCToolBar::OnToolHitTest on file afxtoolbar.cpp
// It is not needed to do the GetMessageString part, because it already done
// on function CMFCPopupMenuBar::OnToolHitTest of afxpopupmenubar.cpp file, which
// supplies the two parts to the Tooltip Manager
CString strTipText;
TCHAR szFullText[256];
AfxLoadString(pButton->m_nID, szFullText);
AfxExtractSubString(strTipText, szFullText, 1, '\n');
pTI->lpszText = _tcsdup(strTipText);
return TRUE;
}
您必须在资源文件中定义与菜单 ID 完全相同的字符串;它们的格式是 Prompt text\nPrompt title
。我不确定,但我认为您唯一可以使用的新行是将标题与文本分开的行。
除了在使用鼠标悬停菜单时简单地显示提示之外,您可能还想做一些事情。您可以通过覆盖 MainFrame
class:
OnMenuSelect
来实现
void CMainFrame::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
if (nItemID == ID_MENU_I_WANT_TO_PROCESS)
{
DoThings();
}
__super::OnMenuSelect(nItemID, nFlags, hSysMenu);
}
我建议您重写 MainFrame 上的 GetMessageString
函数 class 并在此处放置一个断点,以便您查看流程如何进行。