VB Postmessage发送字符串问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VB Postmessage发送字符串问题相关的知识,希望对你有一定的参考价值。

偶尔玩一下网络游戏,为了方便 就想用VB 做一个简单的打怪辅助工具。
现在的问题是:
Postmessage往游戏窗口(已知句柄)发送按键消息时 没有反映。 但是对文本窗口是有效的。
这个问题是出在哪里呢?
用VB写的
游戏是 天龙八部

任何应用程序(包括背景)发送的任何关键信息(包括普通字符键,功能键,按住Shift键/控制/ Alt键加任意组合按键的键)来自动执行特定的功能,是一种用途很广,功能很实用价值,很多人都被困在此,很难理解,我也遇到过这方面的需求,并封锁。开始查了很多的信息化解决方案和互联网用户,一些可以发挥作用,但也有许多程序的测试证明行不通的。发送移位/控制/ Alt加任何的按键组合没有找到一个可行的解决方案,例如,下面的代码就不会被发送到指定的窗口(HWND)按Ctrl + C:
PostMessage的HWND,WM_KEYDOWN WM_KEYDOWN ,VK_C H002E0001“按C键的
PostMessage的HWND VK_CONTROL,H001D0001”的按下Ctrl键
PostMessage的HWND WM_KEYUP,VK_C和HC02E0001释放C键
PostMessage的HWND WM_KEYUP VK_CONTROL, HC01D0001“释放Ctrl键
上面的例子中,只能发送一个小写字母c。
下面的代码可以模拟Ctrl + C键,但它不能被发送到指定窗口的背景:
keybd_event VK_Ctrl,0,0,0'按下Ctrl键
的keybd_event VK_C的,0 0,0,按C键
keybd_event VK_C,0,KEYEVENTF_KEYUP,“C键
keybd_event VK_Ctrl 0,KEYEVENTF_KEYUP释放,释放Ctrl键
有真的没有办法解决这个问题的方式吗?我觉得应该这样做!后来,经过反复的Windows消息机制和键盘输入系统调用数据,终于找到了一个解决方案,并成功地展示了测试。自己一度被困在这里,得到最终的解决方案,而不是排斥的,现在来了,同样需要将大部分这方面的需求的朋友,而且这个问题已不再是少数“大师”的独家秘籍。
任何应用程序窗口发送模拟的关键,必须先获得输入焦点,要接收的关键不需要激活该应用程序的窗口句柄,以便使用Windows API的查找窗口FindWindowEx,首先FindWindow顶部的应用程序(顶层)的窗口句柄,然后使用FindWindowEx得到你想要领取钥匙的子窗口或控制的句柄,因为顶层窗口的应用程序不一定是关键的是接受窗口(如记事本。exe“的记事本程序实际收到的”关键点“窗口是主窗口中的”记事本“编辑控制)的ClassID或Caption找到。已经取得了假设的目标窗口句柄(HWND),窗口,然后使用PostMessage发送消息的普通字符键直接最简单的WM_CHAR消息如下:
PostMessage的HWND,WM_CHAR,ASC(“A”;),0'字符
发送的非普通字符键如功能键,箭头键使用WM_KEYDOWN,WM_KEYUP消息如下:
PostMessage的hWndMsg WM_KEYDOWN,VK_ESCAPE&H00010001'模拟按下Esc键
的PostMessage的hWndMsg的WM_KEYUP,VK_ESCAPE HC0010001模拟电梯Esc键
最后一个参数(LPARAM)低16位(0001)表示,按键高8位00表示,C0被解除,第二个最高(01个)的扫描码键,可以使用API?? MapVirtualKey( VirtualKey,0),得到(注:在每个系统中的扫描码可能会有所不同,在这个特定的数值例子,在实际应用中MapVirtualKey)。
下一个点偏移/控制/ ALT修饰键与其他键组合如何发送,使用下面的方法(使用Shift和Control API keybd_event):
keybd_event VK_SHIFT,H2A,0,0'模拟按下SHIFT键,与H2A是扫描码VK_SHIFT BR /> PostMessage的hWndMsg,WM_KEYDOWN,VK_A,及H001E0001的模拟按下A键,SHIFT + A产生一个大写的A字
的PostMessage的hWndMsg的WM_KEYUP,VK_A HC01E0001的模拟提起的一个关键
keybd_event VK_SHIFT&H2A,KEYEVENTF_KEYUP,0'模拟电梯的SHIFT键
(扫描码2A)替换上述VK_SHIFT VK_CONTROL(扫描1D)Ctrl键组合,可以实现VK_A(扫描代码1E)可以替换为任何功能键,如VK_F4(扫描代码3E)。
ALT修饰键特殊,它是一个系统的关键使用WM_SYSKEYDOWN / WM_SYSKEYUP消息,如下:
PostMessage的hWndMsg,WM_SYSKEYDOWN,VK_F4和H003E0001或&H20000000'模拟按Alt + F4
PostMessage的hWndMsg,WM_SYSKEYUP,VK_F4,与HC03E0001或&H20000000'模拟电梯ALT + F4
'&H20000000范围内的码位,设置Alt键被按下 / a>
在这一点上,你就大功告成了!我希望你快乐!
参考技术A 你对游戏窗口发送字符串是没有用的,得发送按键消息,用sendmessage函数

通过 PostMessage 发送/接收字符串

【中文标题】通过 PostMessage 发送/接收字符串【英文标题】:Sending/Receiving a string through PostMessage 【发布时间】:2012-05-16 13:12:04 【问题描述】:

虽然网上已经有一些资源可以解决这个粗略的话题,但我仍然没有找到适合我的答案。

我希望在我的 VB.net 进程和我的 C++ 进程之间进行充分的沟通。我希望能够从 C++ 进程向 发送一个字符串,但目前我需要实现:

C++进程发送字符串,并对其进行处理。

这造成了一些我不确定的点,但我会尽量保持简单...

VB中使用以下函数声明;

Declare Function PostMessage Lib "user32" Alias "PostMessageA" ( _
    ByVal hWnd As IntPtr, _
    ByVal Msg As UInteger, _
    ByVal wParam As IntPtr, _
    ByVal lParam As String _
) As Boolean

然后像这样发送消息;

PostMessage(hWnd, SM_PING, Nothing, "schlampe")

C++中使用以下方法声明来捕获消息;

LRESULT CALLBACK newWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

为了测试我是否可以使用;

char buffer[50];
sprintf(buffer, "Received: %s", (char *)lParam);
MsgBox(buffer);

我浏览了很多我认为不必要的细节,但请询问并提供给您。

我的问题是消息 接收并“处理”...但是 C++ 进程创建的消息框不包含我的测试消息(它显示:“已接收:”)。

那么,如何通过 PostMessage/SendMessage 将字符串从 VB 发送到 C++?




解决方案:

查看已接受的解决方案答案...但此外,这是我接收字符串的方式 (C++):

LRESULT CALLBACK newWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
    switch(uMsg) 
        case WM_COPYDATA:
            MsgBox("Received a WM_COPYDATA message");
            COPYDATASTRUCT * pcds = (COPYDATASTRUCT *)lParam;
            LPCTSTR lpszString = (LPCTSTR)(pcds->lpData);
            MsgBox(lpszString);
            return 1L;
    
    return CallWindowProc(instance->OriginalProcessor(), hwnd, uMsg, wParam, lParam);

最后,我使用了 IPC 示例 here 来发送消息。此示例使用 C# 发送消息,但我只需要这个概念(更不用说将此类代码转换为 VB 是在公园散步)。请注意,在我的 VB 实现中,我不需要以空字符终止字符串。

【问题讨论】:

使用窗口消息的要求是特定的吗?还是在进程之间传递数据是最终目标?对于后者,有better ways 来实现。 您可能应该在使用 COPYDATASTRUCT 之前对其进行一些基本验证。某些恶意应用程序可能会向您发送虚假的WM_COPYDATA 消息。 【参考方案1】:

在使用 Windows 消息时,您应该使用WM_COPYDATA 在进程之间传输字符串数据。如果您使用自定义消息 ID,则字符串数据将不会在两个不同的进程地址空间之间编组。

这就是您当前的代码失败的原因。接收进程在lParam 中传递一个指向调用进程地址空间中内存的指针。当然,这在其他过程中毫无意义。

虽然还有其他方法可以使用 Windows 消息在进程之间编组这样的数据,但WM_COPYDATA 是迄今为止最简单的。如果您的要求变得更加复杂,那么您可能需要考虑一种比 Windows 消息更全面的 IPC 方法。

【讨论】:

我必须提到做 IPC 的通用方法:管道、共享内存 + 互斥体、套接字等。 @ulidtko 我研究了其他方法,得出的结论是windows消息会给我带来更少的麻烦,但感谢您的关注。 是否需要使用OnCopyData来接收数据?需要注意的是我的 C++ DLL 被注入到另一个进程中,我不确定我是否仍然可以收到COPYDATASTRUCT 此外,我宁愿不必从我的 C++ DLL 中创建一个不可见的窗口(以接收 OnCopyData)......但如果没有其他方法,那么我会屈服。 你需要一个不可见的窗口。

以上是关于VB Postmessage发送字符串问题的主要内容,如果未能解决你的问题,请参考以下文章

在VB里面如何用postmessage函数向已知句柄的窗体发送单击鼠标的消息

vb中postmessage中怎么用组合键ctrl+c

在两个应用程序之间发送消息

vbs通过pid定位到程序后,如何使用postmessage发送F5到程序里?

用PostMessage函数向窗体发送鼠标单击消息,单击的X坐标=100 ,y坐标=200.该窗体的句柄为hand。代码怎么写

postMessage