博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MFC——子窗口之间传递参数和调用函数
阅读量:4137 次
发布时间:2019-05-25

本文共 2509 字,大约阅读时间需要 8 分钟。

这几天在用MFC做ui的时候遇到一个看起来很简单的问题,但是折腾了好久,最后在同门和老师的帮助下解决了这个问题,对MFC有了更深的理解,特此记录一下。

一、功能简介

在这里插入图片描述

实现功能:右边添加车型对话框可以选择车型,不同车型有不同的坡度(车型属性)。单击选择键,实现左边视图窗口车型改变为左边选择的车型,同时将坡度属性也传递到左边的视图类。

说明

  1. 左边车辆信息基类为CFormView,右边选择车型窗口基类为CDialogEx类(对话框类和视图类差别还是挺大的,后面会具体说明)
  2. 跨类之间传输数据:右侧窗口的车型名称和坡度传输到左侧窗口。利用单文档Doc类存放数据,实现多个类共享数据互相调用。
public:	double slope;	CString vehiclename;

二、问题描述

方法1:MFC消息映射机制

消息映射机制:把指定的消息交给指定的函数进行处理的方法,这样就形成了一个<消息,处理函数>对。消息映射可以在本类中实现,也可以跨类实现。

下面是是将消息映射添加到一个类中所做的全部工作:

  1. 所操作类中,声明消息映射宏。
  2. 通过放置标识消息的宏来执行消息映射,相应的类将在对BEGIN_MESSAGE_MAP和END_MESSAGE_MAP的调用之间处理消息。
    在这里插入图片描述
  3. 对应消息处理函数分别在类中声明,类外定义:
    在这里插入图片描述

本类和跨类的区别在于跨类需要一个投递消息的函数,如PostMessage()或者SendMessage(),函数投递出去的消息由消息响应函数接收。::PostMessage()函数参数:

BOOL PostMessage(          	HWND hWnd,    UINT Msg,    WPARAM wParam,    LPARAM lParam);

思路

  1. 类向导添加自定义消息和消息处理程序

    在这里插入图片描述

  2. 获取车辆信息视图窗口(左)的句柄;

  3. 利用::PostMessage()函数发送消息,由左侧视图窗口类的OnAddVehicle()函数响应。注:m_vehicle为左侧窗口里的Group Box控件的变量,SetWindowText()改变车型名字;

afx_msg LRESULT VehicleFormView::OnAddVehicle(WPARAM wParam, LPARAM lParam){
//CImageGridDoc* m_pDoc = (CImageGridDoc*)GetDocument(); pDoc = (CImageGridDoc*)GetDocument(); m_vehicle.SetWindowText(pDoc->vehiclename); return 0;}

错误

调试后没有出现错误,点击选择按钮没有任何变化,消息响应函数没有被调用。Debug后发现获取句柄出错,并没有获取到窗口的句柄。

方法二:跨类调用函数

思路

两个类互相包含头文件,在添加车型窗口里面new一个车辆信息的对象,利用成员函数实现改变。
错误
此方法出现了各种内存错误,没有一次通过编译。本人能力有限,并没有解决这些问题,而且感觉这个方法也不太好,随即放弃了这条路。

方法三:利用Doc类

参考博客:
此博客提供了一个很好的方法,但是中间还是遇到了问题。

问题

对话框窗口类没有m_pDocument成员变量,无法直接获取Doc类的指针。中间想把对话框改为CFormView模拟对话框,但是老师给我提供了 一个新的方法,后面会详细说明。

三、解决方案

方法一

CMainFrame *pMwnd = (CMainFrame*)AfxGetMainWnd();	VehicleFormView *vehicle =(VehicleFormView*)pMwnd->m_treespliter.GetPane(1, 0);	//CWnd *pGroupBox = vehicle->GetDlgItem(IDC_STATIC_VEHICLE);	//pGroupBox->SetWindowTextW(vechiclename);	::PostMessage(vehicle->GetSafeHwnd(), WM_ADDVEHICLE, (WPARAM)WM_ADDVEHICLE, (LPARAM)0);

此方法利用了主窗口的指针作为中介,找到之前划分窗口得到的指针,用CSplitterWnd类的CWnd* GetPane( int row, int col )函数获取窗口指针,再用GetSafeHwnd()获取句柄。

此方法奏效后,又尝试直接在对话框类(右)直接设置视图窗口(左)控件名字,方法是利用GetDlgItem()获取控件的指针,然后直接使用SetWindowText()函数,代码为注释掉的那部分。

方法二

未解决

方法三

还是利用MainFrame作为中介,获取Doc类的指针

参考

CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd();	//获取MAIN指针	CImageGridDoc* pDoc = (CImageGridDoc*)pMainFrame->GetActiveDocument();	int index = m_combo.GetCurSel();	m_combo.GetLBText(index, pDoc->vehiclename);	//获取车型	pDoc->slope = m_slope;							//获取坡度

具体如何调用函数的,在走通了方法一后,我没有再去尝试了。后面解决这个问题为的是可以实现数据在Doc类中共享。

四、总结

通过解决这些问题,对MFC有了更深些的理解。总结下来:

  1. 如何获取指针句柄很重要,参考
  2. CMainFrame类永远的核心,遇事不决,就找Main,找它做中转。AfxGetMainWnd是全局方法,什么地方都能用
  3. Doc类是很好的存储数据的地方
  4. 理清楚

感谢老师和同门对我的帮助,第一次些博客,如有错误,请多多指导!

转载地址:http://wcavi.baihongyu.com/

你可能感兴趣的文章
802.11ac and 802.11ad
查看>>
IEEE 802 LAN/MAN Standards Committee
查看>>
AES算法分析与实现
查看>>
802.11 Four-way handshake Messages
查看>>
TI DaVinci(达芬奇)入门
查看>>
There's Much More than Intel/AMD Inside
查看>>
what is difference between IRQ and FRQ
查看>>
使用 SCons 轻松建造程序
查看>>
dash 和 bash
查看>>
调频 预加重 和 去加重 (FM Pre-emphasis/De-emphasis)
查看>>
windows 环境下 scons 交叉编译 (RVCT4.1)
查看>>
P4 使用
查看>>
Setting up a GCC Development Environment for the Cortex M0/M3
查看>>
ARM GCC linker 脚本介绍
查看>>
stack type, full-ascending, full-descending, empty-ascending, empty-descending
查看>>
Android Trusty TEE 2.启动分析
查看>>
Android Trusty TEE 1.简介
查看>>
Git工具应用
查看>>
聊聊同步、异步、阻塞与非阻塞
查看>>
Linux select/poll机制原理分析
查看>>