C# 为什么PostMessage WM_键关闭&;WM_KEYUP到文本框生成两个字符?

C# 为什么PostMessage WM_键关闭&;WM_KEYUP到文本框生成两个字符?,c#,C#,我有一个带有多行文本框和按钮的表单 文本框有一个向上键、向下键和按键事件,所以我可以看到当你按键时会发生什么 当我在文本框有焦点的情况下按下a键时,它会显示: Down: 65 Press: a Up: 65 使用该按钮,我将发送一条向下键和向上键消息。这样我就可以按两次键: Down : 65 Up : 65 Press : a Press : a 请帮助我理解为什么会发生这种情况 [DllImport("user32.dll")] static extern bo

我有一个带有多行文本框和按钮的表单

文本框有一个向上键、向下键和按键事件,所以我可以看到当你按键时会发生什么

当我在文本框有焦点的情况下按下
a
键时,它会显示:

Down: 65
Press: a
Up: 65
使用该按钮,我将发送一条
向下键
向上键
消息。这样我就可以按两次键:

Down : 65
Up : 65
Press : a
Press : a
请帮助我理解为什么会发生这种情况

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

    const uint WM_KEYDOWN = 0x0100;
    const uint WM_KEYUP = 0x0101;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        PostMessage(textBox1.Handle, WM_KEYDOWN, 65, 0);
        PostMessage(textBox1.Handle, WM_KEYUP, 65, 0);
    }

    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        textBox1.AppendText("Down : " + e.KeyValue.ToString() + "\r\n");
    }

    private void textBox1_KeyUp(object sender, KeyEventArgs e)
    {
        textBox1.AppendText("Up : " + e.KeyValue.ToString() + "\r\n");
    }

    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        textBox1.AppendText("Press : " + e.KeyChar.ToString() + "\r\n");
    }

当然,答案是WM_KEYDOWN和WM_keydup消息的LPRAM应该包含重复计数、扫描代码、扩展键标志、上下文代码、前一个键状态标志和键的转换状态标志

private void button1_Click(object sender, EventArgs e)
    {
        uint repeatCount = 0;
        uint scanCode = 0;
        uint extended = 0;
        uint context = 0;
        uint previousState = 0;
        uint transition = 0;

        uint lParamDown;
        uint lParamUp;

        scanCode = 65;
        lParamDown = repeatCount
            | (scanCode << 16)
            | (extended << 24)
            | (context << 29)
            | (previousState << 30)
            | (transition << 31);
        previousState = 1;
        transition = 1;
        lParamUp = repeatCount
            | (scanCode << 16)
            | (extended << 24)
            | (context << 29)
            | (previousState << 30)
            | (transition << 31);
        PostMessage(textBox1.Handle, WM_KEYDOWN, (UIntPtr)65, unchecked((IntPtr)(int)lParamDown));
        PostMessage(textBox1.Handle, WM_KEYUP, (UIntPtr)65, unchecked((IntPtr)(int)lParamUp));
    }
private void按钮1\u单击(对象发送者,事件参数e)
{
uint repeatCount=0;
uint扫描代码=0;
uint扩展=0;
uint上下文=0;
uint-previousState=0;
uint跃迁=0;
uint-lParamDown;
uint-lParamUp;
扫描码=65;
lParamDown=重复计数

|(扫描码我可以试着重新编程,但当我可以简单地编写textBox1.Text+=“a”时,它似乎毫无意义;而且不必担心其他一些事情,比如修改键处于活动状态,伪lparam值很重要,可能会混淆键盘挂钩。@HansPassant我在一个更复杂的程序中发现了这个问题,我能够在这个简单的程序中复制它,我认为这更容易理解。我想我可能已经找到了回答。