From: http://hi.baidu.com/machh03/blog/item/f320a533fd1672fe1a4cfffe.html/cmtid/f3235f24ff89713a8644f950
最近做了个播放器,用到这方面的知识挺多, 总结一下:
1,添加菜单
有多种方法
(1:在resource View中选中对话框属性的 menu 属性
(2:CMenu m_Menu;
m_Menu.LoadMenu(IDR_MAIN_MENU);
SetMenu(&m_Menu);
取消菜单 SetMenu(NULL);
2,添加状态栏
在头文件添加 /** 状态栏*/
CStatusBar m_wndStatusBar;
。CPP文件中添加
/** 状态栏*/
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT))
)
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
3.WM_MENUSELECT消息
这样手动添加的状态栏,无法接收WM_MENUSELECT消息,所以我们要自己添加
ON_WM_MENUSELECT()
响应的消息函数
/**
* 菜单栏选择
*/
void CFilePlayerDlg::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSystemMenu)
{
CString sFileName;
if(nItemID == AFX_IDS_IDLEMESSAGE)
{
sFileName = L"就绪";
SendMessage(WM_SETMESSAGESTRING, (WPARAM)0, (LPARAM)(LPCTSTR)sFileName);
return ;
}
if(nFlags & MF_SEPARATOR)
return ;
if(nFlags & (MF_SYSMENU | MF_POPUP))
return ;
CString strStatusText;
strStatusText.LoadString( nItemID);
m_wndStatusBar.SetPaneText(0, strStatusText);//
// SendMessage(WM_SETMESSAGESTRING, (WPARAM)0, (LPARAM)(LPCTSTR)strStatusText);
return ;
}
这样就获得了菜单的提示内容,m_wndStatusBar.SetPaneText(0, strStatusText); //将菜单提示显示在状态栏第一个窗格。当然自己可以指定其它窗格,
如果用 SendMessage(WM_SETMESSAGESTRING, (WPARAM)0, (LPARAM)(LPCTSTR)strStatusText);
发送 WM_SETMESSAGESTRING消息也可实现,
需要自己添加该消息的响应函数
如下:
ON_MESSAGE(WM_SETMESSAGESTRING, OnSetMessageString) // 消息宏
消息处理函数
LRESULT CFilePlayerDlg::OnSetMessageString(WPARAM wParam, LPARAM lParam)
{
LPCTSTR lpsz = NULL;
CString strMessage;
if (lParam != 0)
{
ASSERT(wParam == 0); // can't have both an ID and a string
lpsz = (LPCTSTR)lParam; // set an explicit string
}
else if (wParam != 0)
{
{
LPTSTR lpsz = strMessage.GetBuffer(255);
if (AfxLoadString(wParam, lpsz) != 0)
{
lpsz = _tcschr(lpsz, _T('\n'));
if (lpsz != NULL)
*lpsz = '\0';
}
else
{
TRACE1("Warning: no message line prompt for ID 0x%04X.\n", wParam);
}
strMessage.ReleaseBuffer();
}
lpsz = strMessage;
}
m_wndStatusBar.SetWindowText(lpsz); //显示菜单提示
return 0L;
}
4. 这样手动给对话框添加菜单,不能响应菜单更新命令,没有OnInitMenuPopup()函数,所以需要自己实现
手动添加 ON_WM_INITMENUPOPUP() // 响应菜单命令更新消息
并添加相应的消息处理函数。
// 给对话框添加处理菜单命令消息的函数 命令更新
void CFilePlayerDlg::OnInitMenuPopup(CMenu *pPopupMenu, UINT nIndex,BOOL bSysMenu)
{
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;
}
}