大家好,博主在这里跟大家分享一下学习MFC的经验。关于MFC的每篇帖子我都会奉上原文档下载地址(百度文库)和源代码的下载地址(CSDN),都是免金币或积分的!目的就是更加有利于与大家交流,共同进步!因为是初学,所以肯定有疏漏之处,请大家指正

SendMessage可以理解为,SendMessage函数发送消息,等待消息处理完成后,SendMessage才返回。稍微深入一点,是等待窗口处理函数返回后,SendMessage就返回了。

PostMessage可以理解为,PostMessage函数发送消息,不等待消息处理完成,立刻返回。稍微深入一点,PostMessage只管发送消息,消息有没有被送到则并不关心,只要发送了消息,便立刻返回

这里主要讲一下mfc中SendMessage的使用方法。传递消息主要分4步:

1.  在类的定义中声明消息函数:afx_msg void AAA();

2.  在相应的cpp文件中的MESSAGE_MAP区域内添加ON_MESSAGE(MESSAGE_ID,AAA),其中参数1为要传递消息的ID,参数2为刚刚声明的函数名称,不用带括号。

3.  实现消息函数:在cpp文件中添加

LRESULT 类名::AAA(WPARAM

wparam,LPARAM lparam) {

执行内容

return

0;

}

4.  发送消息:在需要发送消息的地方添加下列语句:

HWND hWnd = ::FindWindowEx( m_hWnd, NULL, NULL, WINDOW_TEXT ) ;

FromHandle(hWnd)->SendMessage(MESSAGE_ID,a,b);

其中,m_hWnd为接收消息的父窗口的句柄,WINDOW_TEXT为接收消息窗口的标题,得到的hWnd为接收消息窗口的句柄。调用该窗口的SendMessage函数,MESSAGE_ID为刚刚设定的消息ID,a和b是要传递的参数。

注:在这4个步骤中,前三个我在做的时候基本没什么障碍。问题主要出现在第4步。开始找到网上的例子给的都是FindWindow函数,怎么用都不好使。后来看到有人说FindWindow是找操作系统下打开的窗口的句柄,找窗口中子窗口要用FindWindowEx函数。我也尝试过用对话框的ID找到相应的句柄,像GetDlgItem(ID)函数一样,未果。我使用的对话框都是没有标题栏的,所以也就没有窗口的标题,当然这并不会影响我设置标题。只要在生成该窗口的区域内添加SetWindowText(“窗口标题”)就可以了。也就是说窗口标题可以设置,但是不会显示。最后一点在SendMessage()函数中,MFC默认传递的参数是WPARAM和LPARAM型(一个是UINT型,一个LONG型),如果要传递浮点类型,或者其它不是整数的类型,就可以用指针的形式传递(如果发送方只是申请一个变量并以地址的形式传递,然后接收方以指针的形式接收,如果在执行完SendMessage之后原函数体立即结束了,我不知道在接收函数体接收和使用该变量的之间的一瞬间,该内存区域会不会被占用,我觉得还是有这种可能的。所以我觉得还是在原函数体先申请一块内存,然后在接收函数使用完之后再释放该内存比较合理吧)。

在以下这个例子中是一个MFC的对话框应用程序,名字为MessageTest。它包括左边的一个发送对话框,和右边的两个接收对话框,其中发送对话框和接收对话框1分别是主对话框的子对话框,在接受对话框中有一个Tab Control,在Tab Control中有个接受对话框2。这么做的目的主要是为了理解如何找句柄的,为此我把几个对话框设置成深陷下去的便于观察。

准备工作:

1.  手动添加1个设置全局变量的头文件GlobalSetting.h,这样做的目的是让所有的地方都能知道对话框的标题和自定义的结构。

2.  在GlobalSetting.h中加入下列语句:

#define RECEIVE1_TITLE "receive1 title"

#define RECEIVE2_TITLE "receive2 title"

#define GET_INT WM_USER+1000

#define GET_DOUBLE WM_USER+1001

#define GET_STRING WM_USER+1002

#define GET_STRUCT WM_USER+1003

struct SendStruct

{

int  a;

int  b;

int  c;

int  d;

};

RECEIVE1_TITLE和RECEIVE2_TITLE定义两个接收对话框的标题,后边的4个GET_是4个消息ID,WM_USER是用户自定义消息的起始ID。

3.  在各个需要使用这些内容的位置添加#include “GlobalSetting.h”。

4.  在生成两个接受对话框的位置加入SetWindowText(RECEIVE1_TITLE)和SetWindowText(RECEIVE2_TITLE)。

例1:从发送对话框发送整数到接受对话框1中。

1.  在接受对话框1的类的定义中加入

afx_msg LRESULT

GetInt(WPARAM wparam,LPARAM lparam);

2.  在对应的cpp文件中加入

ON_MESSAGE(GET_INT,Receive1Dlg::GetInt)

3.  在函数实现部分加入

LRESULT Receive1Dlg::GetInt(WPARAM wparam,LPARAM

lparam) {

CString  str; str.Format("%d %d",wparam,lparam);

CEdit*  edit1=(CEdit*)GetDlgItem(IDC_EDIT1); edit1->SetWindowText(str);

return  0;

}

4. 在发送消息的函数中加入

int a=1; int b=2;

HWND hWnd = ::FindWindowEx(

this->GetParent()->m_hWnd, NULL, NULL, RECEIVE1_TITLE);

FromHandle(hWnd)->SendMessage(GET_INT,a,b);

注:在这个部分中只是简单地传递两个整数。第3步是将得到的两个整数显示到编辑框中,wparam和lparam如果是整数可以直接使用。第4步中this->GetParent()->m_hWnd是找到了接收对话框1父窗口的句柄,将a和b的值发过去。

例2:从发送对话框发送小数到接受对话框1中。

1.  在接受对话框1的类的定义中加入

afx_msg LRESULT

GetDouble(WPARAM wparam,LPARAM lparam);

2.  在对应的cpp文件中加入

ON_MESSAGE(GET_DOUBLE,Receive1Dlg::GetDouble)

3.  在函数实现部分加入

LRESULT

Receive1Dlg::GetDouble(WPARAM wparam, LPARAM lparam)

{CString  str;

double*  a=(double*)wparam; str.Format("%lf",*a);

CEdit*

edit1=(CEdit*)GetDlgItem(IDC_EDIT1); edit1->SetWindowText(str);

delete  a; return  0;

}

4.  在发送消息的函数中加入

double *a=new  double;

*a=1.111; HWND hWnd =

::FindWindowEx( this->GetParent()->m_hWnd, NULL, NULL,

RECEIVE1_TITLE);

FromHandle(hWnd)->SendMessage(GET_DOUBLE,(WPARAM)(a),0);

注:在这个部分中是传递1个小数。第3步是将得到的小数显示到编辑框中。第4步中先为double类型的变量申请一块内存并为其负值,然后以指针的形式发送消息过去。在第3步中首先获得double型指针,最后将内存释放。

例3:从发送对话框发送字符串到接受对话框2中。

1.  在接受对话框2的类的定义中加入

afx_msg LRESULT

GetString(WPARAM wparam,LPARAM lparam);

2.  在对应的cpp文件中加入

ON_MESSAGE(GET_STRING,Receive2Dlg::GetString)

3.  在函数实现部分加入

LRESULT Receive2Dlg::GetString(WPARAM wparam,LPARAM

lparam)

{ CString  *str=(CString*)wparam;

CEdit*  edit1=(CEdit*)GetDlgItem(IDC_EDIT1); edit1->SetWindowText(*str);

delete  str;

return  0;

}

4.  在发送消息的函数中加入

CString  *p_str=new CString("Hello");

HWND hWnd =  ::FindWindowEx(this->GetParent()->m_hWnd, NULL, NULL,

RECEIVE1_TITLE);

hWnd=::FindWindowEx(FromHandle(hWnd)->GetDlgItem(IDC_TAB1)->m_hWnd,

NULL, NULL, RECEIVE2_TITLE);

FromHandle(hWnd)->SendMessage(GET_STRING,(WPARAM)(p_str),0);

注:在这个部分中是传递1个字符串。第3步是将得到的字符串显示到编辑框中。第4步中先为CString类型的变量申请一块内存并为其赋值,然后以指针的形式发送消息过去。这个我在获得对话框句柄的时候遇到了一些问题,首先一定要弄清楚各个窗口之间的父子关系,并知道对话框和控件获得句柄的方法是不同的。在这个例子中,接收对话框2的父窗口是那个Tab Control,Tab Control的父窗口是接收对话框1,接收对话框1和发送对话框拥有共同的父窗口。调理清晰了就好写了。HWND hWnd = ::FindWindowEx(this->GetParent()->m_hWnd,

NULL, NULL, RECEIVE1_TITLE);前边已经说过了,是获得了接收对话框1的句柄,下边那条语句中的FromHandle(hWnd)->GetDlgItem(IDC_TAB1)->m_hWnd是获得Tab Control的句柄,hWnd= ::FindWindowEx (FromHandle(hWnd)->

GetDlgItem(IDC_TAB1)-> m_hWnd, NULL, NULL, RECEIVE2_TITLE);就是获得接收对话框2的句柄了。

例4:从发送对话框发送结构到接受对话框2中。

1.  在接受对话框1的类的定义中加入

afx_msg LRESULT GetStruct(WPARAM wparam,LPARAM

lparam);

2. 在对应的cpp文件中加入 ON_MESSAGE(GET_STRUCT,Receive2Dlg::GetStruct)

3.  在函数实现部分加入

LRESULT Receive2Dlg::GetStruct(WPARAM wparam,LPARAM

lparam)

{ SendStruct* ss=(SendStruct*)wparam;

CString  str; str.Format("%d,%d,%d,%d",ss->a,ss->b,ss->c,ss->d);

CEdit*  edit1=(CEdit*)GetDlgItem(IDC_EDIT1); edit1->SetWindowText(str); free(ss);

return  0;

}

4.  在发送消息的函数中加入

SendStruct *ss = (SendStruct  *)malloc(sizeof(SendStruct));

ss->a=1;

ss->b=2;

ss->c=3;

ss->d=4;

HWND hWnd =

::FindWindowEx(this->GetParent()->m_hWnd, NULL, NULL,

RECEIVE1_TITLE);

hWnd = ::FindWindowEx( FromHandle(hWnd)->

GetDlgItem(IDC_TAB1)-> m_hWnd, NULL, NULL ,RECEIVE2_TITLE);

FromHandle(hWnd)->SendMessage(GET_STRUCT,(WPARAM)(ss),0);

这个就不多做解释了。

错误的情况:下面说一下我在开始使用消息时使用错误的情况(我认为这是错的)。拿例2的第4步来说:

double

a=1.1111;

HWND hWnd =

::FindWindowEx( this->GetParent()->m_hWnd, NULL, NULL,

RECEIVE1_TITLE);

FromHandle(hWnd)->SendMessage(GET_DOUBLE,(WPARAM)(&a),0);

第3步中去掉delete a;

我认为这是错的,为什么呢?很多时候在发送完成消息之后,函数体就结束了,a的内存就会被收回了,而消息接收的函数可能在很久的时间内都使用这个变量,说不定什么时候a的内存就被重新占用了。如果a是一个很庞大的对象,这种现象可能会更明显。

python sendmessage_用户自定义消息SendMessage的使用相关推荐

  1. python管理系统-基于Python实现用户管理系统

    基于Python的用户管理小系统,包含文件读写操作,实现了用户信息注册和登录的简单功能. class userLogReg: """ Created on 2018.11 ...

  2. python写管理系统-基于Python实现用户管理系统

    基于Python的用户管理小系统,包含文件读写操作,实现了用户信息注册和登录的简单功能. class userLogReg: """ Created on 2018.11 ...

  3. Python与用户的交互 ,格式化输出的三种方式

    目录 Python与用户的交互 1.为什么交互? 格式化输出的三种方式 1.占位符 format格式化 f-String格式化 基本运算符 流程控制之if判断 1.语法 1.1 if 1.2 if.. ...

  4. python编辑用户登录界面_python编辑用户登入界面的实现代码

    1.需求分析 登入界面需要达到以下要求: 系统要有登入和注册两个选项可供选择 系统要能够实现登入出错提示,比如账户密码错误等,用户信息保存在user_info.txt文件夹中 系统要能够进行登入错误次 ...

  5. python加密敏感信息_仅需10行代码,使用python加密用户敏感数据

    原标题:仅需10行代码,使用python加密用户敏感数据 数据分析师必须要遵守的一个规则就是数据保密,但在跨部门沟通的时候,难免会有数据泄露的情况,所以,对于用户的姓名.手机号.地址等敏感信息,一般需 ...

  6. python如何定义i_如何在Python中使用自定义消息引发相同的Exception?

    如何在Python中使用自定义消息引发相同的Exception? 我的代码中有这个ValueError块: try: do_something_that_might_raise_an_exceptio ...

  7. Python基于用户协同过滤算法电影推荐的一个小改进

    之前曾经推送过这个问题的一个实现,详见:Python基于用户协同过滤算法的电影推荐代码demo 在当时的代码中没有考虑一种情况,如果选出来的最相似用户和待测用户完全一样,就没法推荐电影了.所以,在实际 ...

  8. python等待用户输入_Python等待时间,等待用户输入

    python等待用户输入 Sometimes we want our python program to wait for a specific time before executing the n ...

  9. 【Python例】利用 python 进行用户画像词云图的生成 --- wordcloud

    [Python例]利用 python 进行用户画像词云图的生成 - wordcloud 本文主要用于记录,并使用 python 脚本进行用户画像的词云图的生成. 前言 对于词云图来说,是一个用户画像数 ...

最新文章

  1. 下载、安装、配置 java jdk1.8
  2. python映射类型-Python中字典映射类型的学习教程
  3. jdk中一些常见命令
  4. [jQuery]10 Things I Learned from the jQuery Source
  5. 基于@RabbitListener声明LazyQueue
  6. 如何编写Java代理
  7. Android programming on Mac 之安装Eclipse
  8. PAT 1153 Decode Registration Card of PAT (25 分)- 甲级
  9. 关于使用XLSTransformer.transformXLS导出Excel表格中遇到的问题
  10. 软件质量保障之代码走查
  11. linux宝塔面板下安装mindoc参考
  12. android assets绝对路径,Android获取assets文件路径
  13. 第一集 DLNA 白話文介紹
  14. python tableau_Tableau集成Python机器学习实践(下)
  15. vs2019开发android应用,VS 2019开发APP(一)界面和代码
  16. 数据库冗余存储设计对读取性能影响的测试
  17. 共鸣(resonance)
  18. 程序员一定会有35岁危机吗?三分天注定,七分靠打拼
  19. mybatis自动建表oracle,利用mybatis-generator自动生成代码 - 菩提树下的杨过 - 博客园...
  20. 已完美解决:小米手机报告Google屡次停止运行

热门文章

  1. 邮件群发服务器是什么?邮件可以群发么?
  2. oppo人岗匹配测评_在测试中使用匹配器
  3. DPOS——回归中本聪
  4. html谷歌浏览器自动播放视频,谷歌浏览器怎么才能绕过视频自动播放的限制呢?大家有没有什么好办法...
  5. 高中计算机教师考试专业知识,教师考试大纲《信息技术学科知识与教学能力》(高中)...
  6. python之PIL 大图拆分成小图
  7. MACOM观点:5G网络形势下的光通讯需求有哪些?
  8. linux自动重复数据,Permabit推出针对Linux的重复数据删除软件
  9. Linux用户与内核空间交互—sysfs
  10. 龙芯处理器发展的思考