WPF 텍스트 상자는 창 양식의 ElementHost에서 입력을 수락하지 않습니다.

StackOverflow https://stackoverflow.com/questions/835878

문제

기존 Windows Forms / MFC Application Engine (Rhino 3D) 내에서 소비 할 WPF에서 UI 컨트롤을 개발하고 있습니다.

애플리케이션 엔진은 기능을 노출시켜 "도크 바"를 생성하는 능력을 노출시켜 엔진 인터페이스에 도킹 할 수있는 하위 창에 Windows 양식 컨트롤을 넣을 수 있습니다.

Dockbar에 추가되는 ElementHost 컨트롤 내에 간단한 WPF 텍스트 상자를 넣으려고합니다. 이것은 언뜻보기에 잘 작동하는 것으로 보입니다. 그러나 텍스트 상자에 입력하려고 시도한 후에는 특정 시퀀스 만 실제로 텍스트 상자에 나타납니다. 그만큼 삭제, 역행 키이, 복사, 반죽, 그리고 텍스트 선택 일하다. AZ, 1-9 등을 입력하면 해당 키가 나타나지 않습니다.

나는 그물을 수색했고 ElementHost.EnableModelessKeyboardInterop() 그러나 이것은 양식에서 생성되는 WPF Windows에만 적용됩니다. WPF USERCONTROLS 만 만들고 ElementHost 컨트롤에서 호스팅하고 있습니다.

나는 Dispatcher.run ()에 대해 이야기 한 게시물을 보았고 일종의 작품이지만 나머지 양식을 깨뜨 렸습니다.

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

그만큼 미리 키키, 미리 키워 다운, 키 업, 그리고 키 다운 이벤트는 모든 텍스트 상자에 불이 붙지 만 텍스트 상자에는 텍스트가 표시되지 않습니다.

Windows 메시지에 대해 많이 알지 못하지만 WinSpector를 사용하여 텍스트 상자에서 WM_GETTEXT 메시지가 나오지 않는다는 것을 알았습니다 (심지어 알지 못하는 경우).

또한 새로운 Windows Forms 프로젝트를 만들고 그곳에서 동일한 작업을 수행했으며 잘 작동하므로 Rhino 3D 엔진 내에 Windows를 만드는 방법에 문제가 있어야합니다.

다음은 작동하지 않는 샘플 코드입니다.

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 일간의 머리를 쫓아 낸 후 그것을 알아 냈습니다 ...

MFC 대화 창이 WM_CHAR 메시지 및 제어가 입력 처리를 방지합니다. 그래서 이것을 막기 위해 나는 hwndsource를 연결하고 내가받을 때마다 WM_GETDLGCODE 메시지는 수락 할 입력 유형으로 답장을 한 다음 이벤트를 처리 한대로 표시합니다.

모든 텍스트 상자를 수정하지 않기 위해 나만의 텍스트 상자를 만들었습니다 (아래 참조).

    /// <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;
        }
    }

다른 팁

이것에 대한 내 자신의 질문을 확인하십시오. 결국, 당신이 필요한 것은 다음과 같습니다.

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

내 WPF TextBox "Kinda"가 읽기 쉬운 이유는 무엇입니까?

WXWIDGETS 상위 창과 WPF 텍스트 상자 컨트롤과 비슷한 문제가 있습니다. childhwndsourcehook을 첨부하면 키보드 입력을받지 못하는 문제를 해결하지만 가끔 중복 공간 문자가 생겼음을 알았습니다. WM_Keydown 메시지는 공간 문자를 안정적으로 처리하는 것처럼 보이지만 일부 공간에 대해 중복 WM_CHAR 메시지도 수신됩니다. 이것을 해결하기 위해 나는 childhwndsourcehook 함수의 본문에 다음 절을 추가했는데, 이것은 단순히 WM_CHAR SPACE 문자를 무시합니다.

        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;
        }

파생 된 텍스트 상자를 만들 필요는 없습니다. iotextbox의 코드는 UserControl 호스팅 텍스트 상자에서 사용할 수 있습니다. VS2010 패키지에 사용되는 사용자 정의 옵션 페이지에 사용 된 WPF 컨트롤로 성공적으로 테스트했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top