一、MFC菜单
1.相关问题
WIN32 - HMENU 代表一个菜单
MFC - CMenu 类的对象代表一个菜单
2.相关类
CMenu - 封装了关于菜单操作的各种API函数,还封装了一个非常重要的变成m_hMenu(保存了菜单句柄)
3.菜单的使用
(1)添加菜单资源
(2)设置菜单方法
a.在调用Create函数创建主框架窗口时
pFrame->Create( NULL, L"MFCMenu", WS_OVERLAPPEDWINDOW,
CFrameWnd::rectDefault, NULL, MAKEINTRESOURCE( IDR_MENU1 ) );
b.在床架窗口的WM_CREATE消息处理中
CMenu menu;
menu.LoadMenu( IDR_MENU1 ); - 加载菜单并获取菜单句柄,将菜单句柄和CMenu类的对象建立一对一的绑定关系
CFrameWnd::SetMenu( &menu );
(3)命令消息(WM_COMMAND)处理
ON_COMMAND
(4)设置菜单项状态
ON_WM_INITMENUPOPUP - 菜单被激活还没显示
::CheckMenuItem / CMenu::CheckMenuItem
::EnableMenuItem / CMenu::EnableMenuItem
(5)命令消息(WM_COMMAND)的处理顺序
Frame --> App(CFrameWnd::OnCmdMsg函数内部代码执行先后顺序决定的)
(6)上下文(右键)菜单
WM_CONTEXTMENU - 专门处理上下文菜单的消息
::TrackPopupMenu / CMenu::TrackPopupMenu - 显示弹出式菜单
::GetSubMenu / CMenu::GetSubMenu - 获取某个顶层菜单项的下拉菜单(弹出式菜单)
相关代码:

#include "stdafx.h" class CMyFrameWnd :public CFrameWnd { DECLARE_MESSAGE_MAP() public: afx_msg int OnCreate(LPCREATESTRUCT pcs); afx_msg void OnNew(); afx_msg void OnInitMenuPopup(CMenu* pPopup, UINT nPos, BOOL i); afx_msg void OnContextMenu(CWnd* pWnd, CPoint pos); }; BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd) ON_WM_CONTEXTMENU() ON_WM_INITMENUPOPUP() //ON_COMMAND(ID_NEW, OnNew) ON_WM_CREATE() END_MESSAGE_MAP() void CMyFrameWnd::OnContextMenu(CWnd* pWnd, CPoint pos) { CMenu menu; menu.LoadMenuW(IDR_MENU1); //顶层菜单和下拉菜单都加载 CMenu *pPopup = menu.GetSubMenu(1); //获得下拉菜单句柄 //::TrackPopupMenu(pPopup->m_hMenu, TPM_CENTERALIGN | TPM_VCENTERALIGN, pos.x, pos.y, 0, pWnd->m_hWnd, NULL); pPopup->TrackPopupMenu(TPM_CENTERALIGN | TPM_VCENTERALIGN, pos.x, pos.y, this, NULL); } void CMyFrameWnd::OnInitMenuPopup(CMenu* pPopup, UINT nPos, BOOL i) { //::CheckMenuItem(pPopup->m_hMenu, ID_NEW, MF_BYCOMMAND|MF_CHECKED); pPopup->CheckMenuItem(ID_NEW, MF_BYCOMMAND | MF_CHECKED); } void CMyFrameWnd::OnNew() { AfxMessageBox(L"框架类处理了新建被点击"); } int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs) { CMenu menu; menu.LoadMenuW(IDR_MENU1); SetMenu(&menu); return CFrameWnd::OnCreate(pcs); } class CMyWinApp :public CWinApp { DECLARE_MESSAGE_MAP() public: virtual BOOL InitInstance(); public: afx_msg void OnNew(); }; BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp) ON_COMMAND(ID_NEW, OnNew) END_MESSAGE_MAP() CMyWinApp theApp; void CMyWinApp::OnNew() { AfxMessageBox(L"应用程序类处理了新建被点击"); } BOOL CMyWinApp::InitInstance() { CMyFrameWnd *pFrame = new CMyFrameWnd; m_pMainWnd = pFrame; pFrame->Create(NULL, L"MFCMenu"); //pFrame->Create(NULL, L"MFCMenu", WS_OVERLAPPEDWINDOW, // CFrameWnd::rectDefault, NULL, MAKEINTRESOURCE(IDR_MENU1)); pFrame->ShowWindow(SW_SHOW); pFrame->UpdateWindow(); return TRUE; }
运行结果:
二、工具栏
1.相关类
CToolBarCtrl - 父类CWnd,封装了关于工具栏控件的操作
CToolBar - 父类CControlBar,封装了工具栏的各种操作以及工具栏和框架窗口之间的关系
2.工具栏的使用
(1)添加工具栏资源
(2)创建工具栏
CToolBar::CreateEx / CToolBar::Create
(3)加载工具栏
CToolBar::LoadToolBar
(4)工具栏的停靠(船坞化)
a.工具栏准备停靠的位置
void CToolBar::EnableDocking( DWORD dwStyle );
b.框架窗口允许停靠的位置
void CFrameWnd::EnableDocking( DWORD dwStyle );
c.框架窗口确定临时停靠的位置
void CFrameWnd::DockControlBar( CControlBar *pBar, //工具栏对象地址
UINT nDockBarID = 0, //临时停靠的位置
LPCRECT *lpRect = NULL ); //没用
(5)工具栏的显示和隐藏
a.切换工具栏的显示和隐藏状态
void CFrameWnd::ShowControlBar( CControlBar *pBar, //工具栏对象地址
BOOL bShow, //TURE-显示,FALSE-隐藏
BOOL bDelay ); //是否延迟,FALSE-不延迟,TRUE-延迟
b.判断窗口是否处理显示状态
BOOL CWnd::IsWindowVisible( );
(6)工具栏风格
CBRS_GRIPPER - 把手夹子风格
CBRS_SIZE_DYNAMIC - 工具栏可变形
CBRS_TOOLTIPS - 工具栏可以显示标签
TBSTYLE_FLAT - 工具栏按钮平滑
TBSTYLE_TRANSPARENT - 工具栏按钮凸起
相关代码:

#include "stdafx.h" class CMyFrameWnd :public CFrameWnd { DECLARE_MESSAGE_MAP() public: afx_msg int OnCreate(LPCREATESTRUCT pcs); afx_msg void OnNew(); afx_msg void OnSet(); afx_msg void OnInitMenuPopup(CMenu* pPopup, UINT nPos, BOOL i); afx_msg void OnTool(); private: CToolBar toolbar; }; BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd) ON_COMMAND(ID_TOOL, OnTool) ON_WM_INITMENUPOPUP() ON_COMMAND(ID_SET, OnSet) ON_COMMAND(ID_NEW, OnNew) ON_WM_CREATE() END_MESSAGE_MAP() void CMyFrameWnd::OnTool() { if (!toolbar.IsWindowVisible()) //工具栏是隐藏状态 { this->ShowControlBar(&toolbar, TRUE, FALSE);//显示工具栏 } else //工具栏是显示状态 { this->ShowControlBar(&toolbar, FALSE, FALSE);//隐藏工具栏 } } void CMyFrameWnd::OnInitMenuPopup(CMenu* pPopup, UINT nPos, BOOL i) { if (!toolbar.IsWindowVisible()) { pPopup->CheckMenuItem(ID_TOOL, MF_UNCHECKED);//设置为非勾选状态 } else { pPopup->CheckMenuItem(ID_TOOL, MF_CHECKED);//设置为勾选状态 } } void CMyFrameWnd::OnSet() { AfxMessageBox(L"绿色按钮被点击"); } void CMyFrameWnd::OnNew() { AfxMessageBox(L"新建被点击"); } int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs) { toolbar.CreateEx(this, TBSTYLE_FLAT, //工具栏中按钮的风格 WS_CHILD|WS_VISIBLE|CBRS_ALIGN_TOP| CBRS_GRIPPER| //工具栏把手风格 CBRS_SIZE_DYNAMIC| //工具栏动态改变形状风格 CBRS_TOOLTIPS| //提示信息风格 CBRS_FLYBY); toolbar.LoadToolBar(IDR_TOOLBAR1); //工具栏准备停靠任何位置 toolbar.EnableDocking(CBRS_ALIGN_ANY); //框架允许停靠任何位置 this->toolbar.EnableDocking(CBRS_ALIGN_ANY); //框架最终确定工具栏停靠位置 this->DockControlBar(&toolbar, AFX_IDW_DOCKBAR_TOP); //设置工具栏标题 toolbar.SetWindowTextW(L""); return CFrameWnd::OnCreate(pcs); } class CMyWinApp :public CWinApp { public: virtual BOOL InitInstance(); }; CMyWinApp theApp; BOOL CMyWinApp::InitInstance() { CMyFrameWnd *pFrame = new CMyFrameWnd; m_pMainWnd = pFrame; pFrame->Create(NULL, L"MFCToolBar", WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault, NULL, MAKEINTRESOURCE(IDR_MENU1)); pFrame->ShowWindow(SW_SHOW); pFrame->UpdateWindow(); return TRUE; }
三、状态栏
1.相关类
CStatusBar - 父类CControlBar,封装了关于状态栏的各种操作
2.状态栏使用
(1)创建状态栏
CStatusBar::CreateEx / CStatusBar::Create
(2)设置状态栏指示器
BOOL CStatusBar::SetIndicators( const UINT lplDArray, //指示器的ID数组
int nlDCount); //指示器的个数
(3)设置指示器的宽度和风格
void CStatusBar::SetPannelInfo( int nIndex, //缩影
UINT nID, //ID
UINT nStyle, //风格
int cxWidth ); //宽度
(4)设置指示器的文本内容
BOOL CStatusBar::SetPaneText( int nIndex,
LPCTSTR lpNewText,
BOOL bUpdate = TRUE );
相关代码:

#include "stdafx.h" UINT g_hIndicator[] = { 0, IDS_TIME, IDS_POS }; class CMyFrameWnd :public CFrameWnd { DECLARE_MESSAGE_MAP() public: afx_msg int OnCreate(LPCREATESTRUCT pcs); afx_msg void OnTimer(UINT nIDEvent); afx_msg void OnMouseMove(UINT nFlags, CPoint point); private: CStatusBar statusbar; }; BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd) ON_WM_MOUSEMOVE() ON_WM_TIMER() ON_WM_CREATE() END_MESSAGE_MAP() void CMyFrameWnd::OnMouseMove(UINT nFlags, CPoint point) { CString strPos; strPos.Format(L"(%d,%d)", point.x, point.y); statusbar.SetPaneText(2, strPos); } void CMyFrameWnd::OnTimer(UINT nIDEvent) { SYSTEMTIME st = { 0 }; //获得当前系统时间 ::GetLocalTime(&st); CString strTime; strTime.Format(L"%d-%d-%d %d:%d:%d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); //设置状态栏内容 statusbar.SetPaneText(1, strTime); } int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs) { //创建状态栏 statusbar.CreateEx(this); //设置指示器 statusbar.SetIndicators(g_hIndicator, 3); //设置指示器的风格和宽度 statusbar.SetPaneInfo(1, IDS_TIME, SBPS_POPOUT, 200); statusbar.SetPaneInfo(2, IDS_POS, SBPS_NORMAL, 200); //设置定时器 ::SetTimer(this->m_hWnd, 1, 1000, NULL); return CFrameWnd::OnCreate(pcs); } class CMyWinApp :public CWinApp { public: virtual BOOL InitInstance(); }; CMyWinApp theApp; BOOL CMyWinApp::InitInstance() { CMyFrameWnd *pFrame = new CMyFrameWnd; m_pMainWnd = pFrame; pFrame->Create(NULL, L"MFCMenu"); pFrame->ShowWindow(SW_SHOW); pFrame->UpdateWindow(); return TRUE; }
运行结果: