百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分析 > 正文

VC|API消息处理(回调函数+分支语句)与MFC中的消息映射函数

liebian365 2024-10-24 14:36 26 浏览 0 评论

Windows程序不同于控制台程序,因为输入输出不再是scanf和printf那么简单了,而是通过窗口(包括对话框和控件)作为输入、输出的界面以及键盘、鼠标的各类输入事件。

用户在操作系统中的任何操作都是一个事件,而消息是操作系统将事件传递给用户程序的数据格式,是一种传递数据的通信协议。和所有的通信协议(类型+数据)一样,消息的通信协议是由消息类型和相关数据组成。

当鼠标单击一个控件按钮时,应用程序就会接收到一个消息,消息的类型是WM_COMMAND,而数据是一个按钮的ID,应用程序根据ID可以判断用户单击的哪个按钮,这个按钮对应的事件代码就可以得到执行。

窗口消息按照消息的来源可以分为系统定义的消息和应用程序自定义的消息。系统消息编号的范围是0-WM_USER-1,也就是0-1023。常用的如WM_CLOSE、WM_MOUSEOVER等。

1 基于对话框的Windows API应用程序(回调函数+分支语句)

在Wind32程序中只要在回调函数中使用分支语句,即可接收并处理各类消息。

2 进程和线程间的消息传递

API的两个消息传递函数:

LRESULT SendMessage(

HWND hWnd,

UINT Msg,

WPARAM wParam,

LPARAM lParam

);

BOOL PostMessage(

HWND hWnd,

UINT Msg,

WPARAM wParam,

LPARAM lParam

);

SendMessage()是同步的,在同一线程内,经常使用其发送消息,速度快并能得到返回的消息处理结果;

PostMessage()是异步的,在不同线程和进程之间,使用其发送消息时,先放入目标窗口的消息队列中,然后由目标窗口通过消息循环自行派发处理。

简单的写法:

	HWND hWnd = FindWindow("NotePad",NULL);
	if(hWnd)
		PostMessage(hWnd,WM_CLOSE,0,0);

以上两个函数在MFC中也有封装,使用了默认参数,使用更简单。

LRESULT SendMessage(
 UINT Msg,
 WPARAM wParam=0,
 LPARAM lParam=0
);
BOOL PostMessage(
 UINT Msg,
 WPARAM wParam=0,
 LPARAM lParam=0
);

写法差不多:

	CWnd* pWnd = FindWindow("NotePad",NULL);
	if(pWnd)
		pWnd->PostMessage(WM_CLOSE,0,0);

3 MFC自定义消息并使用ON_MESSAGEG来关联消息映射函数

基本的步骤分为五步:

I 自定义消息(.cpp)

#define WM_TESTSEND (WM_USER + 1)
#define WM_TESTPOST (WM_USER + 2)

II 自定义消息与函数映射(.cpp)

BEGIN_MESSAGE_MAP(CTestMsgDlg, CDialog)
	ON_MESSAGE(WM_TESTSEND,OnSendMessage)
	ON_MESSAGE(WM_TESTPOST,OnSendMessage)
	//{{AFX_MSG_MAP(CTestMsgDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

III 与自定义消息映射的函数的声明

afx_msg LRESULT OnSendMsg(WPARAM wParam,LPARAM lParam);

afx_msg LRESULT OnPostMsg(WPARAM wParam,LPARAM lParam);

IV 与自定义消息映射的函数的定义

LRESULT CTestMsgDlg:: OnSendMessage(WPARAM wParam,LPARAM lParam)
{
	AfxMessageBox("接收SendMessage发来的消息");
	return wParam + lParam;
}
LRESULT CTestMsgDlg:: OnPostMessage(WPARAM wParam,LPARAM lParam)
{
	AfxMessageBox("接收PostMessage发来的消息");
	return wParam + lParam;
}

IV 可以在对话框初始化时让函数得到调用

BOOL CTestMsgDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	int nREt = SendMessage(WM_TESTSEND,15,25);
	nREt = PostMessage(WM_TESTPOST,5,10);
}

也可以是自定义消息+按钮响应SendMessage+回调函数

#define WM_MY_MESSAGE	WM_USER + 66
// 自定义消息,数据流程转换
void CMessageSendSampleDlg::OnButtonSendMymessage()
// 发送自定义消息函数
{
	SendMessage(WM_MY_MESSAGE, NULL, NULL);
// 发送自定义消息,由下面的WindowProc()处理
}
LRESULT CMessageSendSampleDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) // 程序处理函数
{
	switch (message)									// 判断消息类型
	{
	case WM_MY_MESSAGE:
		WriteLog("接收到WM_MY_MESSAGE消息");			// 接收到用户自定义消息,输出
		break;
	default:
		break;
	}
	return CDialog::WindowProc(message, wParam, lParam);
}

也可以注册并发送消息:

void CMessageSendSampleDlg::OnButtonRegmessage()				// 注册消息函数	
{
	UINT myMsg = RegisterWindowMessage("LLN's Message Test");	// 注册消息
	::SendMessage(HWND_BROADCAST, myMsg, NULL, NULL);			// 发送广播消息
}

附实例代码:

#include "stdafx.h"
#include "resource.h"
//消息回调函数
BOOL CALLBACK dlgFunc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_COMMAND:
		switch(wParam)
		{
		case IDCANCEL:
			EndDialog(hwndDlg,IDCANCEL);
			break;
		case IDOK:
			{
				int nLeft = GetDlgItemInt(hwndDlg,IDC_LEFT,NULL,TRUE);
				int nRight = GetDlgItemInt(hwndDlg,IDC_RIGHT,NULL,TRUE);
				SetDlgItemInt(hwndDlg,IDC_RESULT,nLeft+nRight,TRUE);
			}
			break;
		}
		break;
	}
	return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInstance,
 HINSTANCE hPrevInstance,
 LPSTR lpCmdLine,
 int nCmdShow)
{
 	//MessageBox(NULL,"first program","note",0);
	DialogBox(hInstance,(LPCTSTR)IDD_FIRSTDLG,NULL,dlgFunc);
	HWND hWnd = FindWindow("NotePad",NULL);
	if(hWnd)
		PostMessage(hWnd,WM_CLOSE,0,0);
	return 0;
}
// stdafx.h 
#include <windows.h>

-End-

相关推荐

4万多吨豪华游轮遇险 竟是因为这个原因……

(观察者网讯)4.7万吨豪华游轮搁浅,竟是因为油量太低?据观察者网此前报道,挪威游轮“维京天空”号上周六(23日)在挪威近海发生引擎故障搁浅。船上载有1300多人,其中28人受伤住院。经过数天的调...

“菜鸟黑客”必用兵器之“渗透测试篇二”

"菜鸟黑客"必用兵器之"渗透测试篇二"上篇文章主要针对伙伴们对"渗透测试"应该如何学习?"渗透测试"的基本流程?本篇文章继续上次的分享,接着介绍一下黑客们常用的渗透测试工具有哪些?以及用实验环境让大家...

科幻春晚丨《震动羽翼说“Hello”》两万年星间飞行,探测器对地球的最终告白

作者|藤井太洋译者|祝力新【编者按】2021年科幻春晚的最后一篇小说,来自大家喜爱的日本科幻作家藤井太洋。小说将视角放在一颗太空探测器上,延续了他一贯的浪漫风格。...

麦子陪你做作业(二):KEGG通路数据库的正确打开姿势

作者:麦子KEGG是通路数据库中最庞大的,涵盖基因组网络信息,主要注释基因的功能和调控关系。当我们选到了合适的候选分子,单变量研究也已做完,接着研究机制的时便可使用到它。你需要了解你的分子目前已有哪些...

知存科技王绍迪:突破存储墙瓶颈,详解存算一体架构优势

智东西(公众号:zhidxcom)编辑|韦世玮智东西6月5日消息,近日,在落幕不久的GTIC2021嵌入式AI创新峰会上,知存科技CEO王绍迪博士以《存算一体AI芯片:AIoT设备的算力新选择》...

每日新闻播报(September 14)_每日新闻播报英文

AnOscarstatuestandscoveredwithplasticduringpreparationsleadinguptothe87thAcademyAward...

香港新巴城巴开放实时到站数据 供科技界研发使用

中新网3月22日电据香港《明报》报道,香港特区政府致力推动智慧城市,鼓励公私营机构开放数据,以便科技界研发使用。香港运输署21日与新巴及城巴(两巴)公司签署谅解备忘录,两巴将于2019年第3季度,开...

5款不容错过的APP: Red Bull Alert,Flipagram,WifiMapper

本周有不少非常出色的app推出,鸵鸟电台做了一个小合集。亮相本周榜单的有WifiMapper's安卓版的app,其中包含了RedBull的一款新型闹钟,还有一款可爱的怪物主题益智游戏。一起来看看我...

Qt动画效果展示_qt显示图片

今天在这篇博文中,主要实践Qt动画,做一个实例来讲解Qt动画使用,其界面如下图所示(由于没有录制为gif动画图片,所以请各位下载查看效果):该程序使用应用程序单窗口,主窗口继承于QMainWindow...

如何从0到1设计实现一门自己的脚本语言

作者:dong...

三年级语文上册 仿写句子 需要的直接下载打印吧

描写秋天的好句好段1.秋天来了,山野变成了美丽的图画。苹果露出红红的脸庞,梨树挂起金黄的灯笼,高粱举起了燃烧的火把。大雁在天空一会儿写“人”字,一会儿写“一”字。2.花园里,菊花争奇斗艳,红的似火,粉...

C++|那些一看就很简洁、优雅、经典的小代码段

目录0等概率随机洗牌:1大小写转换2字符串复制...

二年级上册语文必考句子仿写,家长打印,孩子照着练

二年级上册语文必考句子仿写,家长打印,孩子照着练。具体如下:...

一年级语文上 句子专项练习(可打印)

...

亲自上阵!C++ 大佬深度“剧透”:C++26 将如何在代码生成上对抗 Rust?

...

取消回复欢迎 发表评论: