2018年3月4日20:42:54
好久没摸过MFC了
身边的小伙伴又有人入坑MFC ,(我都已经 好久不碰这玩意儿了)今天问我怎么在两个窗口之间传值。接着上次,做一次总结(也是怕自己今后忘了,万一哪天需要,又拿起MFC了 )
/ ---- 2018年3月4日20:01:08 更新=====================
前提:使用VS + MFC 基于对话框 项目
继续接着本文主题:两个窗体之间传值。
比如:
有窗口A, 窗口B,问题:窗口A 需要窗口B 界面上的值
总结一下,我知道的方法有:
1、窗口B 发一个消息,调用函数 PostMessage,然后在窗口A上接收并处理该消息
2、窗口B的类中定义一个变量,该变量访问类型为 private, 窗口B同时增加一个 共有的接口,接口的目的是取出 窗口B 中改变量。
3、窗口B的类中定义一个变量,该变量访问类型为 public
A、
先说第二种把。比较简单
代码:
#pragma once
// CdoubleDlgDlg 对话框
class CdoubleDlgDlg : public CDialogEx
{
// 构造
public:
CdoubleDlgDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_DOUBLEDLG_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
private:
// 2018年3月4日20:12:36
// 我这里演示举例,传一个int
int m_IntVal;
// 实现
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()
public:
afx_msg void OnBnClickedButton1();
};
我这里演示的是 传一个int,新增代码:
// 2018年3月4日20:12:36
// 我这里演示举例,传一个int
int m_IntVal;
接着在 CdoubleDlgDlg 类中定义了个函数,函数的访问类型是 public,方外部调用,函数原型如下:
// 函数功能:返回保存的 int
int GetIntVal();
// 函数功能:返回保存的 int
void GetIntVal(int &outIntVal);
做了函数重载,功能都是一样的。函数实现如下:
// 函数功能:返回保存的 int
int CdoubleDlgDlg::GetIntVal()
{
// 返回保存的int类型的缓冲区
return m_IntVal;
}
// 函数功能:返回保存的 int
void CdoubleDlgDlg::GetIntVal(int &outIntVal)
{
outIntVal = m_IntVal;
}
外部直接调用该函数即可
B、
第三种传值
很简单,外部直接调用即可,比如,我在类中定义了 int m_IntVal, 同样的,直接使用 X.m_IntVal就能取到值, X 表示该窗体的一个实例化对象
C、
最后说说第一种,
步骤如下:
1、定义一个消息标识,该消息标识,放在 窗体A与窗体B 都能 访问到的 地方(可以自定义头文件,定义各种消息标识,方法还有很多,仅供参考):
// 自定义消息标识 WM_GET_DIALOG_INT_VAL
#define WM_GET_DIALOG_INT_VAL (WM_USER + 200)
窗体B中,当需要传值时,使用 函数 PostMessage,
// 传值
// 可以用 WPARAM参数或者 LPARAM参数,我这里用的是Wparam 参数
// 第一个参为窗体的句柄
// 第二个参数为消息类型
// 第三个参数为 W 参数
// 第四个参数为 L 参数
::PostMessage(NULL, WM_GET_DIALOG_INT_VAL, m_IntVal, 0);
在窗体A中增加消息处理函数,处理函数原型
// 自定义消息处理函数
LRESULT DisposeVal(WPARAM w, LPARAM l);
在窗体A的cpp中,
BEGIN_MESSAGE_MAP(CdoubleDlgDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CdoubleDlgDlg::OnBnClickedButton1)
// !!!! 在消息map中,关联到消息处理函数
ON_MESSAGE(WM_GET_DIALOG_INT_VAL, DisposeVal)
END_MESSAGE_MAP()
新增的是这句:
// !!!! 在消息map中,关联到消息处理函数
ON_MESSAGE(WM_GET_DIALOG_INT_VAL, DisposeVal)
消息处理函数 实现:
// 自定义消息处理函数
LRESULT CdoubleDlgDlg::DisposeVal(WPARAM w, LPARAM l)
{
// 保存 消息中传过来的值,我这里用的是W参数,根据PostMessage传过来的用的是何种方式,这里就用对应的方式接收值
int val = (int)w;
}
-------------------------------完--------------------------------------------
如题,简单来说, 就是在 B中定义一个方法 Func, 用来获取B中输入的结果, 同时,在A 中,调用 B 的Func , 就OK。
核心代码如下:
SafeDataDlg dlg;
if (dlg.DoModal() == IDOK)
{
// ----------关键代码
mDemo = dlg.GetDemo();
EDIT_TEXT.SetWindowText(mDemo.name);
}
--------------------------------------------------------------------------------------------------------------------------
1、问题描述
窗口A要使用窗口B输入的值。
窗口B:
窗口A:
A中的123 不是 默认设置的。
这里,A中显示B中传过来的 值。
2、解决方案之一
建好一个MFC 窗口应用程序,基于对话框的。
A、新建一个结构体,我用来保存输入的数据:
struct demo
{
CString name;
};
B、在资源管理器中,打开资源文件.rc,找到 Dialog, 新建一个 dialog。 并添加好如下的控件 (Edit control + button):
C、双击刚刚新建的这个Dialog, 添加对应的类名:
D、对步骤 B 中的控件 设置好属性: ID, 和 控件变量。
E、 在刚刚新建的dialog 添加的类中 添加 结构体 属性:
包含 结构所在文件:
#include "typedef.h"
比如,我 在步骤 C中添加的类是 dialog1, 就找到这个类。 添加下面的属性:
private:
demo mDemo;
同时,在这个类中,我还添加了个方法。 用来获取属性值:
demo GetDemo();
我对这个函数是这样实现的:
return mDemo;
对, 就这一句。
F、回到刚刚新建的 dialog 中, 咱们不是新建了一个 按钮嘛。 双击它, 添加 在其事件中添加如下代码:
CString tmp;
EDIT_TEXT.GetWindowText(tmp);
if (tmp.GetLength()> 0)
{
mDemo.name = tmp;
}
CDialogEx::OnOK();
G、回到主对话框所在的资源文件 , 就是工程创建时对应的那个默认对话框, 找到其资源文件,添加如下控件, 添加好控件变量:
H、找到 主对话框 对应的 .cpp ,在文件顶部 包含 窗口 B所在头文件:
#include "Dialog1.h"
I、同样的,找到 主对话框所在的 .cpp , 找到函数 OnInitDialog () :添加如下 自定义代码:
CDialogEx::OnInitDialog();
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
//---------------- 自定义代码---------------------
SafeDataDlg dlg;
if (dlg.DoModal() == IDOK)
{
mDemo = dlg.GetDemo();
EDIT_TEXT.SetWindowText(mDemo.name);
}
3、 结果:
好久没摸过MFC了
身边的小伙伴又有人入坑MFC ,(我都已经 好久不碰这玩意儿了)今天问我怎么在两个窗口之间传值。接着上次,做一次总结(也是怕自己今后忘了,万一哪天需要,又拿起MFC了 )
/ ---- 2018年3月4日20:01:08 更新=====================
前提:使用VS + MFC 基于对话框 项目
继续接着本文主题:两个窗体之间传值。
比如:
有窗口A, 窗口B,问题:窗口A 需要窗口B 界面上的值
总结一下,我知道的方法有:
1、窗口B 发一个消息,调用函数 PostMessage,然后在窗口A上接收并处理该消息
2、窗口B的类中定义一个变量,该变量访问类型为 private, 窗口B同时增加一个 共有的接口,接口的目的是取出 窗口B 中改变量。
3、窗口B的类中定义一个变量,该变量访问类型为 public
A、
先说第二种把。比较简单
代码:
#pragma once
// CdoubleDlgDlg 对话框
class CdoubleDlgDlg : public CDialogEx
{
// 构造
public:
CdoubleDlgDlg(CWnd* pParent = NULL); // 标准构造函数
// 对话框数据
enum { IDD = IDD_DOUBLEDLG_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
private:
// 2018年3月4日20:12:36
// 我这里演示举例,传一个int
int m_IntVal;
// 实现
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()
public:
afx_msg void OnBnClickedButton1();
};
我这里演示的是 传一个int,新增代码:
// 2018年3月4日20:12:36
// 我这里演示举例,传一个int
int m_IntVal;
接着在 CdoubleDlgDlg 类中定义了个函数,函数的访问类型是 public,方外部调用,函数原型如下:
// 函数功能:返回保存的 int
int GetIntVal();
// 函数功能:返回保存的 int
void GetIntVal(int &outIntVal);
做了函数重载,功能都是一样的。函数实现如下:
// 函数功能:返回保存的 int
int CdoubleDlgDlg::GetIntVal()
{
// 返回保存的int类型的缓冲区
return m_IntVal;
}
// 函数功能:返回保存的 int
void CdoubleDlgDlg::GetIntVal(int &outIntVal)
{
outIntVal = m_IntVal;
}
外部直接调用该函数即可
B、
第三种传值
很简单,外部直接调用即可,比如,我在类中定义了 int m_IntVal, 同样的,直接使用 X.m_IntVal就能取到值, X 表示该窗体的一个实例化对象
C、
最后说说第一种,
步骤如下:
1、定义一个消息标识,该消息标识,放在 窗体A与窗体B 都能 访问到的 地方(可以自定义头文件,定义各种消息标识,方法还有很多,仅供参考):
// 自定义消息标识 WM_GET_DIALOG_INT_VAL
#define WM_GET_DIALOG_INT_VAL (WM_USER + 200)
窗体B中,当需要传值时,使用 函数 PostMessage,
// 传值
// 可以用 WPARAM参数或者 LPARAM参数,我这里用的是Wparam 参数
// 第一个参为窗体的句柄
// 第二个参数为消息类型
// 第三个参数为 W 参数
// 第四个参数为 L 参数
::PostMessage(NULL, WM_GET_DIALOG_INT_VAL, m_IntVal, 0);
在窗体A中增加消息处理函数,处理函数原型
// 自定义消息处理函数
LRESULT DisposeVal(WPARAM w, LPARAM l);
在窗体A的cpp中,
BEGIN_MESSAGE_MAP(CdoubleDlgDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON1, &CdoubleDlgDlg::OnBnClickedButton1)
// !!!! 在消息map中,关联到消息处理函数
ON_MESSAGE(WM_GET_DIALOG_INT_VAL, DisposeVal)
END_MESSAGE_MAP()
新增的是这句:
// !!!! 在消息map中,关联到消息处理函数
ON_MESSAGE(WM_GET_DIALOG_INT_VAL, DisposeVal)
消息处理函数 实现:
// 自定义消息处理函数
LRESULT CdoubleDlgDlg::DisposeVal(WPARAM w, LPARAM l)
{
// 保存 消息中传过来的值,我这里用的是W参数,根据PostMessage传过来的用的是何种方式,这里就用对应的方式接收值
int val = (int)w;
}
-------------------------------完--------------------------------------------
2019-3-13 22:51 更新
补充方法:
1、socket通信。窗体A与窗体B互相传指,可以采用socket通信的方式,建议使用udp,收到消息解析即可,当然,需要按照约定的协议传递,比如,约定的格式为:AA 66 01 00 01。AA 和 66 为帧头,01的位置传递值的位置, 00为帧计数,01为校验和(可以指定某些位置相加)。收到数据后,解析指定帧位置上的值,然后更新到缓冲区即可。
2、串口通信。使用软件模拟物理串口,窗体A与窗体B使用配对的串口,比如 配置11 与21是配对的串口,A使用11,那么B必须使用21,这样才能达成配对,数据通过串口到达彼此。串口也需要指定通信的固定帧格式,A与B按照相同的格式解析即可。串口收数比网络udp收数相对麻烦一点,方便理解,串口是流式数据,需要手动寻找帧头与帧尾,udp则不需要。