基于visual studio的MFC上位机实现界面切换

MFC上位机实现界面切换

配置界面

首先按照下面的路线找到你的主对话框资源

资源视图-----Dialog-----IDD_你的工程名_DIALOG

先删除没用的控件 两个按钮控件 (确定)( 取消)

还有中间的一段描述文字

按钮文字是给人看的,ID 是给程序看的。

IDC表明是控件的ID

BTN表明是button按钮控件

最后一位一般都来描述功能语义

在属性栏更改三个按钮的ID

第一个按钮 ID:IDC_BTN_HOME

第二个按钮 ID:IDC_BTN_PARAM

第三个按钮 ID:IDC_BTN_ABOUT

下一步就是在资源视图中添加对话框资源

在资源视图中右键项目资源

选择 添加资源

选择 Dialog

点击 新建

这样会新增一个新的对话框资源。

给每个对话框资源改 ID

选中每个新对话框,在属性窗口中改它的 ID:

IDD_DLG_PAGE_HOME

IDD_DLG_PAGE_PARAM

IDD_DLG_PAGE_ABOUT

正好对应三个按钮

方便测试结果 可以先给三个子页面加上三个静态文本来描述对应页面

我这里就不赘述了 比较简单

下一步 为子页面资源创建对应类

这里开始把"资源"和"类"关联起来

1.给首页资源添加类

在资源视图中选中 IDD_DLG_PAGE_HOME 点击对话框资源

右键选择添加类名:CPageHomeDlg

基类默认就行:CDialogEx

另外两个类也是同理

创建好后应该是这种:

cpp 复制代码
// jialiDlg.h: 头文件
//

#pragma once


// CjialiDlg 对话框
class CjialiDlg : public CDialogEx
{
// 构造
public:
	CjialiDlg(CWnd* pParent = nullptr);	// 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_JIALI_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
};

这是我们默认的主对话框文件 还没有进行编写代码 我们可以通过

cpp 复制代码
class CjialiDlg : public CDialogEx

了解到CjialiDlg是主对话框类名

现在我们将在.h文件中进行编写代码

cpp 复制代码
private:
	enum PAGE_INDEX
	{
		PAGE_HOME = 0,
		PAGE_PARAM,
		PAGE_ABOUT
	};//先定义这几个页面的编号
cpp 复制代码
private:
	CPageHomeDlg  m_pageHome;
	CPageParamDlg m_pageParam;
	CPageAboutDlg m_pageAbout;

这里简单插一句

你在CPageHomeDlg.h文件能看到定义的类名CPageHomeDlg

cpp 复制代码
class CPageHomeDlg : public CDialogEx
{
}

然后你用CPageHomeDlg 去定义一个对象叫m_pageHome

这里和C语言中结构体去定义变量思路类似

定义的m_pageHome 是主界面控制首页页面的入口

后面对首页的一切操作,都会通过 m_pageHome 完成

继续编写.h代码

cpp 复制代码
void InitPages();

专门负责页面初始化,获取页面显示区域位置,创建三个子页面

独封装成函数

如果把这些代码全放进 OnInitDialog(),后面不好维护

cpp 复制代码
void SwitchPage(int nPage);//页面切换

还有三个按钮的响应函数

cpp 复制代码
afx_msg void OnBnClickedBtnHome();
afx_msg void OnBnClickedBtnParam();
afx_msg void OnBnClickedBtnAbout();

修改完的.h文件结构应该如下:

cpp 复制代码
// jialiDlg.h: 头文件
//

#pragma once

#include "CPageAboutDlg.h"
#include "CPageHomeDlg.h"
#include "CPageParamDlg.h"

// CjialiDlg 对话框
class CjialiDlg : public CDialogEx
{
// 构造
public:
	CjialiDlg(CWnd* pParent = nullptr);	// 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_JIALI_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()

private:
	enum PAGE_INDEX
	{
		PAGE_HOME = 0,
		PAGE_PARAM,
		PAGE_ABOUT
	};

private:
	CPageHomeDlg  m_pageHome;
	CPageParamDlg m_pageParam;
	CPageAboutDlg m_pageAbout;

private:
	void InitPages();
	void SwitchPage(int nPage);

public:
	afx_msg void OnBnClickedBtnHome();
	afx_msg void OnBnClickedBtnParam();
	afx_msg void OnBnClickedBtnAbout();
};

现在进行.c文件的编写

cpp 复制代码
BOOL CjialiDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 初始化....
	
	InitPages();//添加
	
	return TRUE;
}
cpp 复制代码
void CjialiDlg::InitPages()
{
	CRect rect;

	GetDlgItem(IDC_STATIC_PAGE_AREA)->GetWindowRect(&rect);
	ScreenToClient(&rect);

	m_pageHome.Create(IDD_DLG_PAGE_HOME, this);
	m_pageParam.Create(IDD_DLG_PAGE_PARAM, this);
	m_pageAbout.Create(IDD_DLG_PAGE_ABOUT, this);

	m_pageHome.MoveWindow(&rect);
	m_pageParam.MoveWindow(&rect);
	m_pageAbout.MoveWindow(&rect);

	m_pageHome.ShowWindow(SW_HIDE);
	m_pageParam.ShowWindow(SW_HIDE);
	m_pageAbout.ShowWindow(SW_HIDE);
}

我们现在的方案并不是

点首页就创建首页

点参数就销毁首页再创建参数

而是:

启动时

把 3 个页面都创建出来,摆在同一个位置。

选择谁显示 然后让其他两个页面隐藏

详细讲解一下 InitPages() 这个函数

cpp 复制代码
CRect rect;

CRect 是 MFC 里表示矩形区域的一个类。

它本质上描述一个矩形框的位置。

通常包含 4 个值:

left

top

right

bottom

这 4 个值是什么意思

left = 100

top = 50

right = 500

bottom = 350

那它表示一个矩形:

左边界在 x=100

上边界在 y=50

右边界在 x=500

下边界在 y=350

所以这个例子里:

宽 = 500 - 100 = 400

高 = 350 - 50 = 300

因为我们需要一个变量,来保存:

页面显示区域的位置和大小

后面三个页面都要用它来定位。

cpp 复制代码
GetDlgItem(IDC_STATIC_PAGE_AREA)->GetWindowRect(&rect);
ScreenToClient(&rect);

IDC_STATIC_PAGE_AREA 是我们当时在主页面添加的静态文字

但是他现在就是一个占位框的

以后所有子页面都摆到这块区域里

不写死坐标是因为将来维护的时候 界面有布局有大变化的话会很麻烦

GetDlgItem(IDC_STATIC_PAGE_AREA)

在当前主对话框里,找到 ID 为 IDC_STATIC_PAGE_AREA 的那个控件

返回的是一个控件指针 CWnd*

然后获取这个占位控件在屏幕上的矩形坐标,保存到 rect

ScreenToClient(&rect);

是坐标切换 因为GetWindowRect拿到的是整个屏幕的坐标

需要切换成对话框内的坐标

补全剩下的函数在,c文件中

cpp 复制代码
void CjialiDlg::SwitchPage(int nPage)
{
	m_pageHome.ShowWindow(SW_HIDE);
	m_pageParam.ShowWindow(SW_HIDE);
	m_pageAbout.ShowWindow(SW_HIDE);

	switch (nPage)
	{
	case PAGE_HOME:
		m_pageHome.ShowWindow(SW_SHOW);
		break;

	case PAGE_PARAM:
		m_pageParam.ShowWindow(SW_SHOW);
		break;

	case PAGE_ABOUT:
		m_pageAbout.ShowWindow(SW_SHOW);
		break;

	default:
		m_pageHome.ShowWindow(SW_SHOW);
		break;
	}
}

void CjialiDlg::OnBnClickedBtnHome()
{
	SwitchPage(PAGE_HOME);
}

void CjialiDlg::OnBnClickedBtnParam()
{
	SwitchPage(PAGE_PARAM);
}

void CjialiDlg::OnBnClickedBtnAbout()
{
	SwitchPage(PAGE_ABOUT);
}

实现效果 三个按钮可以换出三个子页面

后面会继续更新MFC的相关简单应用

相关推荐
视图猿人2 小时前
ROS2 JAZZY+Gazebo harmonic小车机器人建模、激光雷达使用、图像传感器使用、构建导航地图、SLAM自动导航仿真
c++·机器人
玖玥拾2 小时前
C/C++ 基础笔记(一)
c语言·c++·笔记
逆向命运2 小时前
PC企微搜索手机号窗口绕过
c语言·汇编·c++·飞书·企业微信
.千余2 小时前
【C++】C++核心语法:函数重载与缺省参数原理与避坑
c语言·开发语言·c++·经验分享·笔记·git·学习
fpcc3 小时前
C++编程实践——提高缓存的命中
c++·缓存
小张成长计划..3 小时前
【C++】37:IO库(扩展)
c++
Cx330❀3 小时前
【Qt 核心机制篇】深度解析 Qt 信号与槽(Signals & Slots)机制:从底层原理、实战演练到 Lambda 进阶
linux·开发语言·c++·人工智能·qt·ubuntu
学习,学习,在学习3 小时前
Modbus TCP同步通信方式实现异步级效率
网络·c++·qt·网络协议·tcp/ip·qt5
Cx330❀3 小时前
【Linux网络】从零构建高性能UDP服务器:从Echo到英译汉业务级实现
大数据·linux·服务器·开发语言·网络·c++·udp