WPF TextBox 在窗口窗体中的 ElementHost 中不接受输入 [英] WPF TextBox not accepting Input when in ElementHost in Window Forms

查看:24
本文介绍了WPF TextBox 在窗口窗体中的 ElementHost 中不接受输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在 WPF 中开发一个 UI 控件,以便在现有的 Windows 窗体/MFC 应用程序引擎 (Rhino 3D) 中使用.

We are developing a UI Control in WPF to be consumed within an existing Windows Forms / MFC application engine (Rhino 3D).

应用程序引擎公开了创建Dockbar"的能力,这实际上让您可以将 Windows 窗体控件放在可以停靠到引擎界面的子窗口中.

The application engine exposes the ability create a "Dockbar" which essentially lets you put Windows Forms controls inside a child window which can dock to the Engines Interface.

我正在尝试将一个简单的 WPF 文本框放入 ElementHost 控件中,该控件已添加到 Dockbar.乍一看,这似乎工作正常;但在尝试输入文本框后,只有某些序列实际显示在文本框中.DELETEBACKSPACECOPYPASTESELECTING TEXT 工作.如果您键入 A-Z、1-9 等,这些键不会显示.

I am attempting to put a simple WPF TextBox inside an ElementHost control, which is added to the Dockbar. This appears to work fine at first glance; but after attempting to type into the TextBox only certain sequences actually show up in the TextBox. The DELETE, BACKSPACE, COPY, PASTE, and SELECTING TEXT work. If you type A-Z, 1-9, etc. those keys do not show up.

我已经搜索了网络,并且听说过 ElementHost.EnableModelessKeyboardInterop() 但这仅适用于从表单创建的 WPF Windows.我只是创建 WPF 用户控件并将它们托管在 ElementHost 控件中.

I have SCOURED the net, and have heard about the ElementHost.EnableModelessKeyboardInterop() but this only applies to WPF Windows being created from the form. I am only creating WPF UserControls and hosting them in the ElementHost control.

我看到一篇关于 Dispatcher.Run() 的帖子,它有点工作,但破坏了表单的其余部分:

I saw a post which talked about the Dispatcher.Run(), and it sort of works but breaks the rest of the form:

System.Windows.Threading.Dispatcher.Run();

PreviewKeyUpPreviewKeyDownKeyUpKeyDown 事件都会在 TextBox 上触发,但可惜没有文本显示在文本框中.

The PreviewKeyUp, PreviewKeyDown, KeyUp, and KeyDown events all fire on the TextBox, but alas no text shows up in the TextBox.

我对 Windows 消息了解不多,但使用 WinSpector 我注意到没有 WM_GETTEXT 消息来自 TextBox(如果它们应该是我也不知道).

I don't know much about Windows Messages, but using WinSpector I noticed that no WM_GETTEXT messages were coming from the TextBox (if they even should be I don't know).

我还创建了一个新的 Windows 窗体项目,并在其中做了同样的事情,它工作正常,所以这一定是在 Rhino 3D 引擎中如何创建和停靠窗口的问题.

I also create a new Windows Forms project and did the same thing in there and it works fine, so it must be an issue with how the windows are created and docked within the Rhino 3D engine.

这是不起作用的示例代码:

Here is the sample code which doesn't work:

ElementHost el = new ElementHost();
System.Windows.Controls.TextBox t = new System.Windows.Controls.TextBox();
t.Width = 100;
t.Text = "TEST";
el.Child = t;
panel1.Controls.Add(el);

推荐答案

抓了2天终于弄明白了...

I finally figured it out after 2 days of head scatching...

MFC 对话框窗口正在接收 WM_CHAR 消息并阻止控件处理输入.因此,为了防止这种情况,我挂钩 HwndSource,每当我收到 WM_GETDLGCODE 消息时,我都会回复要接受的输入类型,然后将事件标记为已处理.

The MFC Dialog window was taking the WM_CHAR messages and preventing the control from handling the input. So in order to prevent this, I hook the HwndSource and whenever I receive the WM_GETDLGCODE message I respond back with the types of input to accept, and then mark the event as handled.

我创建了自己的文本框,以避免修复每个文本框(见下文):

I created my own TextBox in order to prevent having to fix every textbox (see Below):

    /// <summary>
    /// Interop Enabled TextBox : This TextBox will properly handle WM_GETDLGCODE Messages allowing Key Input
    /// </summary>
    class IOTextBox : TextBox
    {
        private const UInt32 DLGC_WANTARROWS = 0x0001;
        private const UInt32 DLGC_WANTTAB = 0x0002;
        private const UInt32 DLGC_WANTALLKEYS = 0x0004;
        private const UInt32 DLGC_HASSETSEL = 0x0008;
        private const UInt32 DLGC_WANTCHARS = 0x0080;
        private const UInt32 WM_GETDLGCODE = 0x0087;

        public IOTextBox() : base()
        {
            Loaded += delegate
                          {
                              HwndSource s = HwndSource.FromVisual(this) as HwndSource;
                              if (s != null)
                                  s.AddHook(new HwndSourceHook(ChildHwndSourceHook));
                          };
        }

        IntPtr ChildHwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_GETDLGCODE)
            {
                handled = true;
                return new IntPtr(DLGC_WANTCHARS | DLGC_WANTARROWS | DLGC_HASSETSEL);
            }
            return IntPtr.Zero;
        }
    }

这篇关于WPF TextBox 在窗口窗体中的 ElementHost 中不接受输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆