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
另外两个类也是同理 创建好后应该是这种: 
// 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()
};
这是我们默认的主对话框文件 还没有进行编写代码 我们可以通过
class CjialiDlg : public CDialogEx
了解到CjialiDlg是主对话框类名
现在我们将在.h文件中进行编写代码
private:
enum PAGE_INDEX
{
PAGE_HOME = 0,
PAGE_PARAM,
PAGE_ABOUT
};//先定义这几个页面的编号
private:
CPageHomeDlg m_pageHome;
CPageParamDlg m_pageParam;
CPageAboutDlg m_pageAbout;
这里简单插一句 你在CPageHomeDlg.h文件能看到定义的类名CPageHomeDlg
class CPageHomeDlg : public CDialogEx
{
}
然后你用CPageHomeDlg 去定义一个对象叫m_pageHome 这里和C语言中结构体去定义变量思路类似 定义的m_pageHome 是主界面控制首页页面的入口 后面对首页的一切操作,都会通过 m_pageHome 完成
继续编写.h代码
void InitPages();
专门负责页面初始化,获取页面显示区域位置,创建三个子页面 独封装成函数 如果把这些代码全放进 OnInitDialog(),后面不好维护
void SwitchPage(int nPage);//页面切换
还有三个按钮的响应函数
afx_msg void OnBnClickedBtnHome();
afx_msg void OnBnClickedBtnParam();
afx_msg void OnBnClickedBtnAbout();
修改完的.h文件结构应该如下:
// 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文件的编写
BOOL CjialiDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 初始化….
InitPages();//添加
return TRUE;
}
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() 这个函数
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
因为我们需要一个变量,来保存: 页面显示区域的位置和大小 后面三个页面都要用它来定位。
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文件中
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的相关简单应用


