热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

VB.net进程通信中FindWindow、FindWindowEX、SendMessage函数的理解

目录一、代码背景二、主要工具三、函数解析1、FindWindow:2、FindWindowEx:3、SendMessage:

目录

一、代码背景

二、主要工具

三、函数解析

1、FindWindow:

2、 FindWindowEx:

3、SendMessage:

四、具体代码示例:

 1、第一部分功能:

A、接收端:

B、发送端

C、运行测试

2.第二部分功能:

A、接收端

B、发送端

C、运行测试




一、代码背景

 针对复杂的多进程软件的编写,各进程间的通信能够保证任务的并行处理,而非多线程的伪并行。针对VB.net进程通信,本文所采用的是调用USER32内的Windows API函数。


二、主要工具

主要包括FindWindow、Fin的WindowEX、SendMessage函数。主要用到的工具为Visual Studio 和SPY++,SPY++自行百度下载。


三、函数解析


1、FindWindow:

根据标题名和窗体类别查找父窗体,并返回窗体的句柄数。声明过程如下:

    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer

lpClassName:窗体类的名字,具体窗体类的名字可以通过SPY++查看;

lpWindowName:窗体标题名字,具体窗体标题名字可以通过SPY++查看。


2、 FindWindowEx:

根据父窗体的句柄,和上一个子窗体的句柄及待查找的子窗体类名和窗体标题名字来查找待查找窗体的句柄。声明过程如下:

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Integer, ByVal hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As Integer

hWnd1:父窗体句柄;

hWnd2:子窗体索引序号,为0则根据Z序列检索左下角满足要求的窗体,将得到的左下角窗体句柄赋给此参数,则根据Z序列检索左下角窗体下一个窗体的句柄。

关于Z序列的解释:子窗体在VB Form中的排序按照Z序列排序,所谓Z序列是指在XY坐标系的第一象限根据Z的笔顺来排序的,而由于电脑窗体的XY的方向是水平向右为X,竖直向下为Y,故与现实生活中的XY坐标系沿着X轴进行镜像,如下图所示。

 依次检索上图右侧①②③④即可索引到对应位置窗体的句柄。

lpsz1:子窗体类的名字,具体窗体类的名字可以通过SPY++查看;

lpsz2:子窗体标题的名字,具体窗体标题的名字可以通过SPY++查看; 

关于lpsz2这个参数,笔者尝试TextBox、RichTextBox、Label等控件的Text属性均未检索成功,故采用VbNullString作为检索,即不考虑窗体标题名字,最终定位到每个句柄均依靠Z序列来实现。


3、SendMessage:

根据提供的句柄和消息类型及其余两个参数来实现进程间的通信。声明如下:

 Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As String) As Integer

hwnd:窗体的句柄;

wMsg:消息类型;

这个可以去看另一篇博主的文章,讲解wMsg参数常量值的。本文引用几处。

wMsg参数常量值:
  #DeFine WM_CREATE 0x01
  创建一个窗口
  #DeFine WM_DESTROY 0x02
  当一个窗口被破坏时发送
  #DeFine WM_MOVE 0x03
  移动一个窗口
  #DeFine WM_SIZE 0x05
  改变一个窗口的大小
  #DeFine WM_ACTIVATE 0x06
  一个窗口被激活或失去激活状态
  #DeFine WM_SETFOCUS 0x07
  一个窗口获得焦点
  #DeFine WM_KILLFOCUS 0x08
  一个窗口失去焦点
  #DeFine WM_ENABLE 0x0A
  一个窗口改变成Enable状态
  #DeFine WM_SETREDRAW 0x0B
  设置窗口是否能重画
  #DeFine WM_SETTEXT 0x0C
  应用程序发送此消息来设置一个窗口的文本
————————————————
版权声明:本文为CSDN博主「物联网小镇」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41476542/article/details/106708127

其中  #DeFine WM_SETTEXT 0x0C

是本文代码使用的常量,十进制为12,在VB.net中可以用十进制12表示,或者&HC来表示16进制的12。表示的意思为发送此消息来设置一个窗口的文本。

wParam:表示于常量有关的常量值,这个参数笔者没搞懂,但是默认0是好用的。

lParam:发送的字符串信息。


四、具体代码示例:


 1、第一部分功能:

发送端检索接收端四个Textbox窗口的句柄信息,并通过msgbox显示出来。


A、接收端:

不用添加任何代码,绘制四个Textbox,修改窗体Text属性为Receive,如下图所示。

运行接收端,使用SPY++查看TextBox文本框的类名 。


 B、发送端

绘制一个按钮 

 添加代码:

Public Class Form1Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntegerPrivate Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Integer, ByVal hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntegerPrivate Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As String) As Int32Dim myhwnd As Integer '主窗口句柄Dim sub_1Hwnd As Integer '子窗口1句柄Dim sub_2Hwnd As Integer '子窗口2句柄Dim sub_3Hwnd As Integer '子窗口3句柄Dim sub_4Hwnd As Integer '子窗口4句柄Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Clickmyhwnd = FindWindow("WindowsForms10.Window.8.app.0.141b42a_r7_ad1", "Receive") ’检索主窗体句柄sub_1Hwnd = FindWindowEx(myhwnd, 0, "WindowsForms10.EDIT.app.0.141b42a_r7_ad1", vbNullString) ’检索子窗口1句柄sub_2Hwnd = FindWindowEx(myhwnd, sub_1Hwnd, "WindowsForms10.EDIT.app.0.141b42a_r7_ad1", vbNullString) ’检索子窗口2句柄sub_3Hwnd = FindWindowEx(myhwnd, sub_2Hwnd, "WindowsForms10.EDIT.app.0.141b42a_r7_ad1", vbNullString) ’检索子窗口3句柄sub_4Hwnd = FindWindowEx(myhwnd, sub_3Hwnd, "WindowsForms10.EDIT.app.0.141b42a_r7_ad1", vbNullString) ’检索子窗口4句柄MsgBox(Hex(sub_1Hwnd) + " " + Hex(sub_2Hwnd) + " " + Hex(sub_3Hwnd) + " " + Hex(sub_4Hwnd)) ’以16进制字符串显示句柄信息End Sub
End Class

C、运行测试

先运行接收端,再运行发送端并单击Button1测试:

弹出对话框,得出如下16进制句柄:

210EE6、171014、210604、191022

再次使用SPY++查找各个窗口的句柄

 

 

 满足我们推算的Z序列。


2.第二部分功能:

验证SendMessage通信,本代码Z序列中第2个窗口为例。


A、接收端

窗体控件不动,添加代码

Public Class Form1Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.LoadTextBox3.Text &#61; "窗口2"End SubPrivate Sub TextBox3_TextChanged(sender As Object, e As EventArgs) Handles TextBox3.TextChanged &#39;Texebox3窗口内容改变If TextBox3.Text <> "窗口2" Then &#39;Texebox3窗口内容不等于窗口2MsgBox("收到数据&#xff1a;" &#43; TextBox3.Text) &#39;弹出收到数据&#xff1a;对话框End IfTextBox3.Text &#61; "窗口2" &#39;恢复默认值窗口2End Sub
End Class

B、发送端

窗体增加Textbox控件作为发送信息的文本载体&#xff0c;如图

代码修改如下,增加SendMessage函数的调用:

Public Class Form1Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntegerPrivate Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Integer, ByVal hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntegerPrivate Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As String) As Int32Dim myhwnd As Integer &#39;主窗口句柄Dim sub_1Hwnd As Integer &#39;子窗口1句柄Dim sub_2Hwnd As Integer &#39;子窗口2句柄Dim sub_3Hwnd As Integer &#39;子窗口3句柄Dim sub_4Hwnd As Integer &#39;子窗口4句柄Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Clickmyhwnd &#61; FindWindow("WindowsForms10.Window.8.app.0.141b42a_r7_ad1", "Receive") ’检索主窗体句柄sub_1Hwnd &#61; FindWindowEx(myhwnd, 0, "WindowsForms10.EDIT.app.0.141b42a_r7_ad1", vbNullString) ’检索子窗口1句柄sub_2Hwnd &#61; FindWindowEx(myhwnd, sub_1Hwnd, "WindowsForms10.EDIT.app.0.141b42a_r7_ad1", vbNullString) ’检索子窗口2句柄sub_3Hwnd &#61; FindWindowEx(myhwnd, sub_2Hwnd, "WindowsForms10.EDIT.app.0.141b42a_r7_ad1", vbNullString) ’检索子窗口3句柄sub_4Hwnd &#61; FindWindowEx(myhwnd, sub_3Hwnd, "WindowsForms10.EDIT.app.0.141b42a_r7_ad1", vbNullString) ’检索子窗口4句柄&#39;MsgBox(Hex(sub_1Hwnd) &#43; " " &#43; Hex(sub_2Hwnd) &#43; " " &#43; Hex(sub_3Hwnd) &#43; " " &#43; Hex(sub_4Hwnd)) ’以16进制字符串显示句柄信息SendMessage(sub_2Hwnd, 12, 0, TextBox1.Text)TextBox1.Text &#61; ""End Sub
End Class


C、运行测试

先运行接收端&#xff0c;再运行发送端&#xff0c;待发送窗口填写"Hello World"。并单击Button1&#xff08;发送数据&#xff09;测试&#xff0c;如接收端弹出&#xff1a;"接收数据&#xff1a;Hello World"。则测试成功

运行结果如图

 笔者水平有限&#xff0c;如有不足之处&#xff0c;评论区欢迎指教。

源码如

https://download.csdn.net/download/qq835128030/21700002?spm&#61;1001.2014.3001.5503

注&#xff1a;Z序列理解有误&#xff0c;经过实践&#xff0c;笔者所推论的Z序列的理论属于巧合&#xff0c;sub_1Hwnd、sub_2Hwnd、sub_3Hwnd、sub_4Hwnd的值无论接收窗口文本框如何排列&#xff0c;均依次等于Textbox4、Textbox3、、Textbox2、、Textbox1的句柄。即文本框窗口的句柄检索排序按照放置的先后顺序的逆序&#xff0c;先放后检索。后放先检索。作如上修订。2021/08/30 23:19


推荐阅读
  • 本文详细介绍了中央电视台电影频道的节目预告,并通过专业工具分析了其加载方式,确保用户能够获取最准确的电视节目信息。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 本文探讨了 Objective-C 中的一些重要语法特性,包括 goto 语句、块(block)的使用、访问修饰符以及属性管理等。通过实例代码和详细解释,帮助开发者更好地理解和应用这些特性。 ... [详细]
  • 本文探讨了如何优化和正确配置Kafka Streams应用程序以确保准确的状态存储查询。通过调整配置参数和代码逻辑,可以有效解决数据不一致的问题。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 本文详细介绍了Java中的访问器(getter)和修改器(setter),探讨了它们在保护数据完整性、增强代码可维护性方面的重要作用。通过具体示例,展示了如何正确使用这些方法来控制类属性的访问和更新。 ... [详细]
  • 本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ... [详细]
  • 本文介绍如何使用JPA Criteria API创建带有多个可选参数的动态查询方法。当某些参数为空时,这些参数不会影响最终查询结果。 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 本文探讨了在Java多线程环境下,如何确保具有相同key值的线程能够互斥执行并按顺序输出结果。通过优化代码结构和使用线程安全的数据结构,我们解决了线程同步问题,并实现了预期的并发行为。 ... [详细]
  • 本文总结了Java程序设计第一周的学习内容,涵盖语言基础、编译解释过程及基本数据类型等核心知识点。 ... [详细]
  • 本文详细介绍了Grand Central Dispatch (GCD) 的核心概念和使用方法,探讨了任务队列、同步与异步执行以及常见的死锁问题。通过具体示例和代码片段,帮助开发者更好地理解和应用GCD进行多线程开发。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
author-avatar
棒棒冰
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有