C# PostMessage语法,尝试向另一个应用程序窗口发送WM_CHAR消息

3
public partial class Form1 : Form
{
    [return: MarshalAs(UnmanagedType.Bool)]
    [DllImport("user32.dll", SetLastError = true)]
    static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    public const Int32 WM_CHAR = 0x0102;
    public const Int32 WM_KEYDOWN = 0x0100;
    public const Int32 WM_KEYUP = 0x0101;
    public const Int32 VK_RETURN = 0x0D;

    public Form1()
    {
        InitializeComponent();
    }

    public bool working;

    private void button1_Click(object sender, EventArgs e)
    {
        Process[] proc = Process.GetProcessesByName("processname");

        if (proc[0] == null || proc.Length == 0)
        {
            Debug.WriteLine("Process not found.");
            return;
        }

        foreach (char c in textBox1.Text)
        {
            // char ascii value in decimal
            int charValue = c;

            // char ascii value in hex
            string hexValue = charValue.ToString("X");

            IntPtr val = new IntPtr(c);

            Debug.WriteLine(c + " = dec: " + charValue + ", hex: " + hexValue + ", val: " + val);

            PostMessage(proc[0].MainWindowHandle, WM_KEYDOWN, val, new IntPtr(0));
            PostMessage(proc[0].MainWindowHandle, WM_CHAR, val, new IntPtr(0));
            PostMessage(proc[0].MainWindowHandle, WM_KEYUP, val, new IntPtr(0));

            PostMessage(proc[0].MainWindowHandle, WM_KEYDOWN, new IntPtr(VK_RETURN), new IntPtr(0));
            PostMessage(proc[0].MainWindowHandle, WM_KEYUP, new IntPtr(VK_RETURN), new IntPtr(0));
        }
    } 
}

如果我设置val = char 'm'(十进制:109,十六进制:0x6D),那么当窗口接收到消息时,由于某种原因显示字符“-”(十进制:45,十六进制:0x2D)。我最初怀疑是十六进制/十进制格式问题,但我错了。 作为一个winapi新手,我的问题似乎与PostMessage()语法有关。如何发送正确的消息以使窗口显示正确的字符?

2
你对十六进制的本质存在根本误解,建议阅读彼得佐德的《Code》一书。只发送WM_CHAR消息,传递new IntPtr(charValue)。并且使用SendMessage,而不是PostMessage。 - undefined
2
如果可能的话,最好使用SendInput来发送按键输入,而不是直接发送WM_KEYDOWN/WM_KEYUP,并且更好地使用WM_KEYDOWN/WM_KEYUP而不是直接发送WM_CHAR。@HansPassant为什么你建议使用SendMessage? - user743382
2个回答

4

在C#中,0x6C和108是相同的东西,都是整数,因此...

IntPtr val = new IntPtr(0x6C)

并且

IntPtr val = new IntPtr(108)

具有相同功能。

因此在您上面的代码中,您应该能够使用:

IntPtr val = new IntPtr((Int32)c);

2
我所有困惑的根源都来自于PostMessage语法中的WM_CHAR。我假设wParam是一个标准的ASCII十六进制键码,但实际上并不是。它实际上是一个(十六进制)虚拟键码
这就解释了为什么0x6D发送负号而不是'm'!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接