windows第十八章 菜单、工具栏、状态栏
文章目录
- 创建框架窗口
- 菜单
- 菜单的风格
- 通过资源创建菜单
- 菜单的各种使用
- 通过代码创建菜单
- 在鼠标位置右键弹出菜单
- CMenu常用函数介绍
- 工具栏
- 方式一,从资源创建工具栏
- 方式二,代码创建
- 状态栏
- 状态栏基础
- 创建状态栏
创建框架窗口
手动创建一个空项目,仿照MFC的写法,其他文件都抄一遍,下图箭头指向的文件需要修改
- 创建一个HelloFrameWnd类继承自CFrameWnd
- App.cpp里改成如下
- 搭建成功,点击运行
- 也可以和win32一样,写注册窗口类
#include "testApp.h"
#include "HelloFrameWnd.h"
BOOL CTestApp::InitInstance()
{
//框架窗口
HelloFrameWnd* pFrame = new HelloFrameWnd;
WNDCLASS wc = { 0 };
wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);//背景色
wc.hCursor = LoadCursor(IDC_ARROW);//鼠标指针
wc.hIcon = LoadIcon(IDI_WENDI_ICON);//图标
wc.hInstance = AfxGetInstanceHandle();
wc.lpszClassName = _T("HelloFrameWndClass");
wc.lpfnWndProc = DefWindowProc;
wc.style = CS_HREDRAW | CS_VREDRAW;
AfxRegisterClass(&wc);
pFrame->Create(L"HelloFrameWndClass", _T("这是我的框架窗口"));//创建窗口,参数为窗口类名和窗口标题,注意窗口类名必须与注册的窗口类名一致
m_pMainWnd = pFrame;//设置主窗口
pFrame->UpdateWindow();
pFrame->ShowWindow(SW_SHOW);
return TRUE;
}
CTestApp theApp;
5. 简化一下上述注册窗口类
#include "testApp.h"
#include "HelloFrameWnd.h"
BOOL CTestApp::InitInstance()
{
//框架窗口
HelloFrameWnd* pFrame = new HelloFrameWnd;
//注册窗口类
LPCTSTR lpClassName = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW, LoadCursor(IDC_ARROW), CreateSolidBrush(RGB(0, 0, 255)), LoadIcon(IDI_WENDI_ICON));
pFrame->Create(lpClassName, _T("这是我的框架窗口"));//创建窗口,参数为窗口类名和窗口标题,注意窗口类名必须与注册的窗口类名一致
m_pMainWnd = pFrame;//设置主窗口
pFrame->UpdateWindow();
pFrame->ShowWindow(SW_SHOW);
return TRUE;
}
CTestApp theApp;
菜单
菜单的风格
菜单风格分为弹出式菜单和下拉式菜单两个类型
通过资源创建菜单
- 新建菜单,右键添加资源,新建Menu
- 把菜单资源加入窗口
- 使用类向导在HelloFrameWnd中添加onCreate消息
启用菜单项, 在oncreate()里添加
m_bAutoMenuEnable = FALSE;// 启用菜单项
- 右键菜单项,添加事件处理程序,类选择HelloFrameWnd
void HelloFrameWnd::OnNew()
{
MessageBox(L"New");
}
菜单的各种使用
m_bAutoMenuEnable = FALSE;// 启用菜单项
CMenu* pMenu = GetMenu();// 获取菜单
//标记菜单项
CMenu* pNewMenu = pMenu->GetSubMenu(0);// 获取第一个菜单项,即新建选项
pNewMenu->CheckMenuItem(0, MF_CHECKED | MF_BYPOSITION);// 将新建选项设置为选中状态
pNewMenu->CheckMenuItem(IDM_SAVE, MF_CHECKED);// 也可以根据Id
//设置默认项
pNewMenu->SetDefaultItem(0, TRUE);// 将新建选项设置为默认项
//给菜单项前面加图标
static CBitmap ubmp;
static CBitmap bmp;
ubmp.LoadBitmap(IDB_NOTOPEN_BITMAP);
bmp.LoadBitmap(IDB_OPEN_BITMAP);
pNewMenu->SetMenuItemBitmaps(0, MF_BYPOSITION, &ubmp, &bmp);//第三个参数是未选中的图片,第四个参数是选中的图片
pNewMenu->CheckMenuItem(0, MF_CHECKED | MF_BYPOSITION);// 将新建选项设置为选中状态
//获取默认菜单大小
int x = GetSystemMetrics(SM_CXMENUCHECK);// 获取菜单项的宽度
int y = GetSystemMetrics(SM_CYMENUCHECK);// 获取菜单项的高度
CString str;
str.Format(L"菜单项大小为%d,%d", x, y);
SetWindowText(str);
//禁用菜单
pNewMenu->EnableMenuItem(0, MF_GRAYED | MF_BYPOSITION);// 禁用新建选项
//销毁菜单
//pNewMenu->DestroyMenu();
通过代码创建菜单
//创建顶层菜单
CMenu* pTopMenu = new CMenu;
pTopMenu->CreateMenu();
pTopMenu->AppendMenu(MF_STRING, 40001, L"菜单项1");
pTopMenu->AppendMenu(MF_STRING, 40002, L"菜单项2");
pTopMenu->AppendMenu(MF_STRING, 40003, L"菜单项3");
//设置菜单到主窗口
SetMenu(pTopMenu);
//创建子菜单
CMenu* pSubMenu = new CMenu;
pSubMenu->CreatePopupMenu();
pSubMenu->AppendMenu(MF_STRING, 40004, L"子菜单项1");
pSubMenu->AppendMenu(MF_STRING, 40005, L"子菜单项2");
pSubMenu->AppendMenu(MF_STRING, 40006, L"子菜单项3");
pTopMenu->AppendMenu(MF_POPUP, (UINT_PTR)pSubMenu->m_hMenu, L"子菜单");//子菜单在顶层菜单的子菜单选项弹出
在鼠标位置右键弹出菜单
void HelloFrameWnd::OnRButtonDown(UINT nFlags, CPoint point)
{
//创建子菜单
CMenu* pSubMenu = new CMenu;
pSubMenu->CreatePopupMenu();
pSubMenu->AppendMenu(MF_STRING, 40004, L"子菜单项1");
pSubMenu->AppendMenu(MF_STRING, 40005, L"子菜单项2");
pSubMenu->AppendMenu(MF_STRING, 40006, L"子菜单项3");
//把鼠标转换成Client坐标
ClientToScreen(&point);
pSubMenu->TrackPopupMenu(TPM_LEFTALIGN, point.x, point.y, this);
CFrameWnd::OnRButtonDown(nFlags, point);
}
CMenu常用函数介绍
工具栏
方式一,从资源创建工具栏
- 定义个成员函数CToolBar m_ToolBar
- 右键资源,添加资源Toolbar,如下图,可以选择工具对按钮进行编辑
- 把工具栏按钮的ID设成要响应的菜单ID,比如我刚才新建文件的菜单项是IDM_NEW,就把这个也设为IDM_NEW
int HelloFrameWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
m_bAutoMenuEnable = FALSE;// 启用菜单项
m_ToolBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_TOP);// 创建工具栏
m_ToolBar.LoadToolBar(IDR_TOOLBAR);// 加载工具栏
m_ToolBar.EnableDocking(CBRS_ALIGN_ANY);// 允许工具栏停靠
EnableDocking(CBRS_ALIGN_ANY);// 允许框架窗口停靠
return 0;
}
方式二,代码创建
m_ToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_SIZE_DYNAMIC | CBRS_GRIPPER);
CToolBarCtrl& toolBarCtrl = m_ToolBar.GetToolBarCtrl();//获取工具栏控件
toolBarCtrl.SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);
m_ImageList.Create(24, 24, ILC_COLOR24 | ILC_MASK, 0, 1);//创建图像列表,大小为24*24,颜色为24位,带掩码 ,1个图像
CBitmap ubmp;
CBitmap bmp;
ubmp.LoadBitmap(IDB_NOTOPEN_BITMAP);//加载位图
bmp.LoadBitmap(IDB_OPEN_BITMAP);
m_ImageList.Add(&ubmp, RGB(255, 255, 255));//添加位图到图像列表
m_ImageList.Add(&bmp, RGB(255, 255, 255));
toolBarCtrl.SetImageList(&m_ImageList);//设置图像列表
UINT nID[] = { IDM_NEW, 0, IDM_EXIT };//工具栏按钮ID
m_ToolBar.SetButtons(nID, 3);//设置按钮
状态栏
状态栏基础
状态栏是位于应用程序窗口底部的一个水平区域,用于显示应用程序的当前状态信息。这些信息可以包括程序的运行状态、操作提示、鼠标位置、文档状态等。
状态栏分为两部分:左边最长的叫做提示行,右边3个窗口,主要显示caps lock, num lock 和scroll lock键状态
创建状态栏
- 定义成员变量
3.资源,添加String Table
由于改ID会莫名导致卡死,这里就不改了
- 添加代码
int HelloFrameWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
m_bAutoMenuEnable = FALSE;// 启用菜单项
//创建状态栏
m_StatusBar.Create(this);
UINT indicators[] = { ID_SEPARATOR,//分隔符
IDS_STRING107,//时间
IDS_STRING108//进度
};//状态栏指示器
m_StatusBar.SetIndicators(indicators, sizeof(indicators) / sizeof(UINT));//设置状态栏指示器
m_StatusBar.SetPaneInfo(1, IDS_STRING107, SBPS_NORMAL, 150);//设置状态栏面板信息
m_StatusBar.SetPaneInfo(2, IDS_STRING108, SBPS_NORMAL, 150);
CStatusBarCtrl& statusBarCtrl = m_StatusBar.GetStatusBarCtrl();//获取状态栏控件
statusBarCtrl.SetMinHeight(20);//设置状态栏最小高度
SetTimer(1, 1000, NULL);//设置定时器
return 0;
};
void HelloFrameWnd::OnTimer(UINT_PTR nIDEvent)
{
if (nIDEvent == 1)
{
//获取当前时间
CTime time = CTime::GetCurrentTime();
CString strTime = time.Format(L"%Y-%m-%d %H:%M:%S");
m_StatusBar.SetPaneText(1, strTime);//设置状态栏面板文本
}
CFrameWnd::OnTimer(nIDEvent);
}
void HelloFrameWnd::OnMouseMove(UINT nFlags, CPoint point)
{
CString str;
str.Format(L"鼠标位置:X=%d,Y=%d", point.x, point.y);
m_StatusBar.SetPaneText(2, str);
CFrameWnd::OnMouseMove(nFlags, point);
}