如何处理WPF文本框的WndProc消息?

时间:2017-04-14 04:56:45

标签: c# wpf

我想知道我是否在wpf文本框中填写了输入词,但即使我输入了IME输入,TextChanged事件也会触发。因此,我尝试区分WM_IME_CHARWM_CHAR消息(就像我在c ++窗体中所做的那样)。我可以使用this method获取WPF窗口的窗口消息,但是如何专门为WPF窗口中的文本框获取消息?

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    HwndSource hwndSource = PresentationSource.FromVisual(myTextbox) as HwndSource;
    if (hwndSource != null)
    {
        hwndSource.AddHook(WndProc);
    }
}

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    const int WM_CHAR = 0x0102;
    const int WM_IME_CHAR = 0x0286;
    switch(msg)
    {
        case WM_CHAR
            Console.WriteLine("WM_CHAR:" + wParam);
            //this is for testing
        case WM_IME_CHAR
            Console.WriteLine("WM_IME_CHAR" + wParam);
            //do something if myTextbox receive an IME char...
            break;
    }
    return IntPtr.Zero;
}

我的上述代码无法获取文本框的任何消息。我做错了什么?

编辑:

我在Windows 10上使用VS2015。

如果我专注于Window并输入英文内容,我可以收到WM_CHAR条消息和正确的wParam

如果我点击TextBox,我就无法收到任何WM_CHAR消息。

如果我专注于WindowTextBox并在中文输入法中输入内容,我就无法收到任何消息。

2 个答案:

答案 0 :(得分:0)

google游戏结束后,我发现了一篇文章:imeで変換状態中でもtextbox-textchangedが発生する

简单地说,我注册了三个事件:

TextCompositionManager.AddPreviewTextInputHandler(textBox1, OnPreviewTextInput);
TextCompositionManager.AddPreviewTextInputStartHandler(textBox1, OnPreviewTextInputStart);
TextCompositionManager.AddPreviewTextInputUpdateHandler(textBox1, OnPreviewTextInputUpdate)

因此我可以知道在WM_IME_CHAR事件被触发时键入了PreviewTextInputStart。当PreviewTextInput事件被触发时,我可以知道一个单词已经完成。

答案 1 :(得分:0)

我在另一个问题的答案中找到了另一种方式:https://stackoverflow.com/a/33105412/5665980

ComponentDispatcher.ThreadPreprocessMessage += (ref MSG m, ref bool handled) => {
        //check if WM_KEYDOWN, print some message to test it
        if (m.message == 0x100)
        {
            System.Diagnostics.Debug.Print("Key down!");
        }
    };

应注意,此技术将从使用当前调度程序的每个窗口接收消息,但是您可以按hwnd进行过滤。