Qt开发:Windows 下进程间通信的可行桥梁:窗体消息

注:窗体消息仅适用于有窗口的进程,如果没有窗口是无法收到窗体消息的(哪怕是隐形的都可以),比如Qt中如果需要使用WindowsMessage只需要类继承QWidget或者QMainWindow等窗口即可。

在说起如何使用Qt窗体消息,我们先要说说窗体消息到底是什么。

如果你有看过一本书叫做Windows高级编程,那下面的内容应该都不用看了,我这里就简单概述一下窗体消息。

在Windows下的应用程序中,其实我们可以很简单地发现,一般的应用程序都是点开之后有一个窗口,然后可以对窗口进行一些操作,或者对一些控件,进行一点比如点击、拖拽、双击等操作。如果你是一名开发,你会很自然地注意到Qt中有一些比如enterEvent,leaveEvent,clickEvent类似的函数。你有没有想过,为什么你的点击事件会在Qt中获得一个触发呢?难道是一种魔法吗?

当然不是的,其实这一切都是来自于Windows自带的窗体消息,如果你想更进一步了解关于Windows是如何定义窗口类的,欢迎你自己去看MSDN窗口类(窗口和消息),这里有更详尽的说明。我在这里简单地说:就是Windows底层会有一个消息机制,当你对这个窗口做比如点击、拖动、双击、右键等操作,这个窗口的指定函数都会接收到特定的窗体消息信号。

我们可以来看一下这个函数

LRESULT SendMessage(
[in] HWND hWnd, //指定的窗口句柄,这个是窗口的唯一标识
[in] UINT Msg, //发送的消息类型,通过一个int值来进行区分
[in] WPARAM wParam, //指定附加的消息特定的信息。
[in] LPARAM lParam //指定附加的消息特定的信息。一般的来说自定义消息wPram和lParam自己定义就好,不做强制要求
);

也就是说,一般情况下,一个窗体消息都包括以上四个参数。我们可以看到,不同的事件通过这个Msg来区分,让我们来看一下Windows内常用的内部指令有哪些

//Msg常用值

#DeFine WM_LBUTTONDOWN 0x201 按下鼠标左键  

#DeFine WM_LBUTTONUP 0x202 释放鼠标左键  

#DeFine WM_LBUTTONDBLCLK 0x203 双击鼠标左键  

#DeFine WM_RBUTTONDOWN 0x204 按下鼠标右键  

#DeFine WM_RBUTTONUP 0x205 释放鼠标右键  

#DeFine WM_RBUTTONDBLCLK 0x206 双击鼠标右键  

#DeFine WM_MBUTTONDOWN 0x207 按下鼠标中键  

#DeFine WM_MBUTTONUP 0x208 释放鼠标中键  

#DeFine WM_MBUTTONDBLCLK 0x209 双击鼠标中键

怎么样?这样就懂了吧,大部分窗体的信号传递都是通过Windows提供的这个窗体消息来实现的,比如你现在想让这个窗体被按下鼠标左键,你就给他发这个

#DeFine WM_LBUTTONDOWN 0x201

消息就行了,它就会知道,哦现在我要被点击了,然后根据事件自动地触发一些你的函数。

那问题来了,这个窗体消息和我们的进程间通信有什么关系呢?

其实聪明的你发现了,这个窗体消息既然可以传递事件,那是不是也可以用来传递信息呢?它真的好温柔,甚至还给了wParam和lParam来给我放信息。

其实每个窗口都有一个接受窗体消息的虚函数,从父类继承的,在Qt中就是从QWidget或者QMainWindow继承的

nativeEvent(const QByteArray &eventType, void *message, long *result)

在这个函数中处理有关windows窗体消息。这个窗口接收到的每个窗体消息都会进入到nativeEvent函数体内,然后我们可以根据接收到的Msg来区分不同消息码的类型。

比如我要区分这个事件是来自进程A的,那个事件是来自进程B的,我想要把他们区分出来不同消息吗不同处理,避免混淆,我们可以来给出一个实例

//注意,所有的自定义消息码都应该从 WM_USER = 0x400开始,所有小于0x400的消息码都是Windows的系统消息,如果要占用的话可能会导致一些意料之外的错误

const int qint32 WM_EVENT_A = WM_USER + 1024; //A的事件的消息码
const int qint32 WM_EVENT_B = WM_USER + 1025; //B的事件的消息码
bool OpenGLWidget::nativeEvent(const QByteArray &eventType, void *message, long *result){
qQ_UNUSED(eventType);
MSG *msg = static_cast<MSG*>(message); //类型转换
if (eventType == "windows_generic_MSG") //windows平台
{
MSG* msg = reinterpret_cast<MSG*>(message); // if(msg->message == WM_EVENT_A)//来自A进程的消息
{
function_about_a();
}else if(msg->message == WM_EVENT_B) //来自B进程的消息
{
function_about_b();
}
}
return QWidget::nativeEvent(eventType, message, result);//交给Qt处理
}

这样你应该明白什么是窗体消息了吧,明白了什么是窗体消息,那么发送消息想必对你来说也非常简单了吧,我这里简单给出一个实例:

::SendMessage(m_wnd, WM_COPYDATA, (WPARAM)wid, (LPARAM)&data);
::PostMessage(m_wnd, WM_COPYDATA, (WPARAM)wid, (LPARAM)&data);

最后提一嘴,在Qt中如果需要知道窗口句柄,是通过winId()来执行的,比如我现在想知道我当前这个类指代的窗口的句柄,就通过this->winId()来获得,某个窗口就用某个窗口指针的这个函数就可以返回了。

Qt开发:Windows 下进程间通信的可行桥梁:窗体消息SendMessage的更多相关文章

  1. 【应用笔记】【AN005】Qt开发环境下基于RS485的4-20mA电流采集

    简介 4-20mA电流环具有广泛的应用前景,在许多行业中都发挥着重要作用.本文主要介绍在Qt开发环境下基于RS485实现4-20mA电流采集,实现WINDOWS平台对数据的采集.分析及显示. 系统组成 ...

  2. QT在windows下的安装与配置

    先了解Qt: Qt一直以来,分为商业.开源两个版本,商业版本为用户提供了二级制的动态库,直接安装既可以使用,但是需要花钱购买license,而开源版本则遵守GPL协议,提供了源码,用户需要自行编译,才 ...

  3. qt在windows下的udp通信(最简单)

    qt编程:windows下的udp通信 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:win7 开发环境:qt 功能: 用udp进行收发 ...

  4. 【Qt开发】Qt在Windows下的三种编程环境搭建

    从QT官网可以得知其支持的平台.编译器和调试器的信息如图所示: http://qt-project.org/doc/qtcreator-3.0/creator-debugger-engines.htm ...

  5. 【QT开发】QT在windows下的exe应用程序如何在别人的电脑上直接运行

     当你利用QT编译了一个可执行程序,需要将这个可执行程序拷贝到别人的电脑上运行,这个时候除了这个可执行程序外,还需要支持的库才可用运行.一般来说通过下面的方法可以实现.     首先,需要看你用的是什 ...

  6. windows下进程间通信(转)

    摘 要 随着人们对应用程序的要求越来越高,单进程应用在许多场合已不能满足人们的要求.编写多进程/多线程程序成为现代程序设计的一个重要特点,在多进程程序设计中,进程间的通信是不可避免的.Microsof ...

  7. windows下进程间通信的(13种方法)

    转自:http://blog.csdn.NET/shiqz/article/details/5862936 摘 要 随着人们对应用程序的要求越来越高,单进程应用在许多场合已不能满足人们的要求.编写多进 ...

  8. windows下进程间通信方法

    摘 要 随着人们对应用程序的要求越来越高,单进程应用在许多场合已不能满足人们的要求.编写多进程/多线程程序成为现代程序设计的一个重要特点,在多进程程序设计中,进程间的通信是不可避免的.Microsof ...

  9. Windows下进程间通信及数据共享

    进程是装入内存并准备执行的程序,每个进程都有私有的虚拟地址空间,由代码.数据以及它可利用的系统资源(如文件.管道等)组成. 多进程/多线程是Windows操作系统的一个基本特征.Microsoft W ...

  10. Qt在Windows下的三种编程环境搭建

    尊重作者,支持原创,如需转载,请附上原地址:http://blog.csdn.net/libaineu2004/article/details/17363165 从QT官网可以得知其支持的平台.编译器 ...

随机推荐

  1. Beats:使用 Elastic Stack 记录 Python 应用日志

    文章转载自:https://elasticstack.blog.csdn.net/article/details/112259500 日志记录实际上是每个应用程序都必须具备的功能.无论你选择基于哪种技 ...

  2. 使用FastDFS打造一款高可用的分布式文件系统

    FastDFS 介绍 参考: http://www.oschina.net/p/fastdfs FastDFS 是一个开源的分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文 ...

  3. Intellij IDEA个人常用快捷键

    分享一下个人常用快捷键. 说明:字母排序规则遵循字母表(a->z) 快捷键 介绍 ctrl+b 快速打开当前光标处的类或方法 ctrl+d 复制当前光标所在行至下一行 ctrl+e 打开最近的文 ...

  4. 掌控(control) 方法记录

    掌控(control) 题面描述 公元\(2044\)年,人类进入了宇宙纪元.L国有\(n\)个星球,分别编号为\(1\)到\(n\),每一星球上有一个球长.有些球长十分强大,可以管理或掌控其他星球的 ...

  5. core3商城DDD实战(一)建模

    我所在学校部门的一个校园商城项目(学生售卖二手物品与发布悬赏求助等,在线上确认,校园内线下交易) 我们使用DDD的软件开发方法,这是我们进入编程世界上手的第二个项目,从创建仓库到现在已经过去二十多天, ...

  6. Java一次返回中国所有省市区三级树形级联+前端vue展示【200ms内】

    一.前言 中国省市区还是不少的,省有34个,市有391个,区有1101个,这是以小编的库里的,可能不是最新的,但是个数也差不了多少. 当一次返回所有的数据,并且还要组装成一个三级树,一般的for,会循 ...

  7. esp32把玩记-④ 星星点灯 (点亮led)

    注意 全程使用Micropython,不会安装看我第一篇文章感谢 正式开始 用Thonny烧录(运行)以下代码 import time from machine import Pin led=Pin( ...

  8. 驱动开发:内核枚举进程与线程ObCall回调

    在笔者上一篇文章<驱动开发:内核枚举Registry注册表回调>中我们通过特征码定位实现了对注册表回调的枚举,本篇文章LyShark将教大家如何枚举系统中的ProcessObCall进程回 ...

  9. LcdToos如何实现PX01自动调Flicker及VCOM烧录

    准备工作: LcdTools+PX01点亮需调Flicker的屏:F118 Flicker探头,用于自动Flicker校准测量,F118连接PX01上电后,探头屏会提示零点校准,此时需盖住探头窗口再按 ...

  10. 5.websocket原理

      websocket协议原理 1.WebSocket协议是基于TCP的一种新的协议.WebSocket最初在HTML5规范中被引用为TCP连接,作为基于TCP的套接字API的占位符.它实现了浏览器与 ...