WPF TextBox not accepting Input when in ElementHost in Window Forms

前端 未结 4 966
北海茫月
北海茫月 2020-12-05 00:45

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

The application engine exposes the ability

相关标签:
4条回答
  • 2020-12-05 01:20

    Check out my own question about this very same thing. in the end though, all you need is something like this:

    Window window1 = new Window();
    ElementHost.EnableModelessKeyboardInterop(window1);
    window1.Show();
    

    Why is my WPF textbox "kinda" readonly?

    0 讨论(0)
  • 2020-12-05 01:30

    It is not necessary to create derived TextBox. The code for IOTextBox can be used in a UserControl hosting textboxes. I have successfully tested it with WPF control used for custom options page used in VS2010 package.

    0 讨论(0)
  • 2020-12-05 01:35

    I have a similar issue with a wxWidgets parent window and embedded WPF TextBox controls. I found that although attaching ChildHwndSourceHook does solve the problem of not receiving keyboard input, I ended up with occasional duplicate space characters. It seems the WM_KEYDOWN message handles the space characters reliably, but a duplicate WM_CHAR message is also received for some of the spaces. To solve this I added the following clause to the body of the ChildHwndSourceHook function, which simply ignores the WM_CHAR space character:

            const UInt32 WM_CHAR = 0x0102;
    
            if (msg == WM_CHAR)
            {
                // avoid duplicated spaces when parent window is a native window
                if (wParam.ToInt32() == 32)
                    handled = true;
            }
    
    0 讨论(0)
  • 2020-12-05 01:41

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

    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;
            }
        }
    
    0 讨论(0)
提交回复
热议问题