使用 PostMessage() 或 SendMessage() 发送大写字母

Posted

技术标签:

【中文标题】使用 PostMessage() 或 SendMessage() 发送大写字母【英文标题】:Using PostMessage() or SendMessage() to send uppercase letters 【发布时间】:2020-09-20 07:19:39 【问题描述】:

我正在尝试使用 PostMessage() 函数发送大写字母或符号(!@# 等):

[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

我尝试同时发送班次和我想发送的大写字母,但它似乎不起作用:

        public const uint WM_KEYUP = 0x0101;
        public const uint WM_KEYDOWN = 0x100;

        void function()
        
            Keys key = Keys.A;
            Keys shift = Keys.ShiftKey;

            PostMessage(process.MainWindowHandle, WM_KEYDOWN, (IntPtr)shift, IntPtr.Zero);
            PostMessage(process.MainWindowHandle, WM_KEYDOWN, (IntPtr)key, IntPtr.Zero);
            PostMessage(process.MainWindowHandle, WM_KEYUP, (IntPtr)shift, IntPtr.Zero);
            PostMessage(process.MainWindowHandle, WM_KEYUP, (IntPtr)key, IntPtr.Zero);
        

编辑:对于那些想知道的人:我最终使用 SendInput() 发送 shift 键按下,因为显然许多游戏检测到 shift 键按下的方式与它们检测其他按键的方式不同,这就是它没有检测到的原因当我尝试使用 PostMessage() 发送时按下 shift 键,您也可以使用 keybd_event() 和 SendKeys()。注意:这些方法不会将密钥发送到特定进程。

【问题讨论】:

你看过SendKeys吗?它在 Windows 窗体中支持 .NET,但您可以使用 P/Invoke 否则 是的,我研究了 SendKeys,但我需要专门使用 PostMessage() 和 SendMessage(),因为我想将输入发送到特定进程。你能举个例子说明如何使用请调用。 你有一个问题,因为你的修饰键堆叠在物理键盘状态的顶部。您发送“SHIFT (keyup)”。如果 SHIFT 键实际上按下了怎么办?现在你混淆了程序。或者,如果 CTRL 键(您没有为其生成任何事件)按下了怎么办?现在程序认为输入了“SHIFT+CTRL+A”。 另外,IntPtr.Zero 不适合 lParam。阅读the documentation 以了解必须发送的内容。 【参考方案1】:

试试这个,而不是使用 WM_KEYDOWN 和 WM_KEYUP:

        public const uint WM_CHAR = 0x0102;

            ...

            PostMessage(process.MainWindowHandle, WM_CHAR, (IntPtr)'A', IntPtr.Zero);

完整解决方案:创建一个 C# 控制台应用程序(我的是 .NET Framework 4.7.2)

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace PostMessageTest

    class Program
    
        [DllImport("user32.dll")]
        public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
        public const uint WM_CHAR = 0x0102;

        public static void function()
        
            IntPtr handle = Process.GetCurrentProcess().MainWindowHandle;
            Console.WriteLine("Sending Keys...");
            PostMessage(handle, WM_CHAR, (IntPtr)'A', IntPtr.Zero); // 0x41
        

        static void Main(string[] args)
        
            function();
            Console.Read();
        
    


【讨论】:

它应该可以工作。我已经用完整的解决方案更新了我的答案,我在给你答案之前运行了这个解决方案。试试看。

以上是关于使用 PostMessage() 或 SendMessage() 发送大写字母的主要内容,如果未能解决你的问题,请参考以下文章

调用 User32 PostMessage 时过程调用或参数无效(错误 5)

postMessage的使用

如何在 ATL DLL 中获取 HWND(用于 SendMessage 或 PostMessage)

C# 使用 PostMessage

SendMessage和PostMessage的异同

SendMessage, postmessage模拟鼠标左键