MFC 两个窗口 传递值

 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则不需要。

  • 14
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值