2009-05-07 29 views
19

Mevcut bir Windows Forms/MFC uygulama altyapısında (Rhino 3D) tüketilmek üzere WPF'de bir UI Denetimi geliştiriyoruz.WPF TextBox kabul etmiyor Pencere Formlarında ElementHost Girişinde

Uygulama altyapısı, Windows Forms denetimlerini, Motorlar Arabirimine takılabilen bir alt pencerenin içine koymanıza izin veren bir "Dockbar" yaratma yeteneğini açığa çıkarır.

Basit bir WPF TextBox'ı, Dockbar'a eklenen bir ElementHost denetiminin içine koymaya çalışıyorum. Bu ilk bakışta iyi çalışıyor gibi görünüyor; ancak TextBox'a yazmayı denedikten sonra sadece belirli diziler TextBox'ta görünür. , geri AL, KOPYALAMAYIN, MACUNU ve Metin seçme eser SİL. A-Z, 1-9 vb. Yazarsanız bu tuşlar görünmez.

Ben net DOLAŞTILAR ve ElementHost.EnableModelessKeyboardInterop() duymuşsunuzdur ama bu sadece WPF, Windows formdan oluşturulan için de geçerlidir. Sadece WPF UserControls yaratıyorum ve bunları ElementHost denetiminde barındırıyorum. KeyUp PreviewKeyDown, PreviewKeyUp,

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

:

Ben Dispatcher.Run() hakkında konuştuk bir yazı gördüm ve çeşit çalışır ancak form kalanı keser ve KeyDown olayları, TextBox'taki tüm yangın olaylarıdır, ancak TextBox'ta hiçbir metin görünmez.

Windows İletileri hakkında pek bir şey bilmiyorum, ancak WinSpector kullanarak TextBox'tan WM_GETTEXT iletisinin gelmediğini fark ettim (eğer bilmeseler bile).

Ayrıca yeni bir Windows Forms projesi oluşturuyorum ve aynı şeyi orada yaptım ve iyi çalışıyor, bu yüzden Windows'un Rhino 3D motorunda nasıl oluşturulduğu ve yuvaya alındığıyla ilgili bir sorun olmalı. ...

MFC iletişim penceresi alıyordu WM_CHAR

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

cevap

19

Sonunda baş scatching 2 gün sonra bunu anladım: Burada

çalışmıyor örnek kod mesajları ve kontrolün girişi ele almasını engeller. Bunu önlemek için, HwndSource'u bağladım ve her ne zaman WM_GETDLGCODE mesajını aldığımda, kabul edilecek giriş türlerini geri alıyorum ve ardından olayı ele alınan olarak işaretleyin. Bu aynı şey hakkında

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

Teşekkürler, bu tam olarak ihtiyacım olan şeydi. Aşağıda önerilen IvanH gibi UserControl'e koydum. ÇALIŞIYOR bir cazibe gibi! –

+0

Teşekkürler! Bu bugün bizim için bir sorun olarak ortaya çıktı ve bu hızla çözüldü! –

9

Kontrol dışarı Kendi sorumu:

Her metin kutusu düzeltmek zorunda önlemek için (Aşağıda bakınız) benim kendi TextBox yarattı.Bir WxWidgets ebeveyn pencere ile ben benzer bir sorun var

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

Why is my WPF textbox "kinda" readonly?

+3

Aslında soruma göre çözümünüzün geçerli olmadığını belirttim, bir pencere değilim, bir ElementHost içinde bir MFC İletişim Penceresinin içinde bir UserControl'üm ... –

+3

Haklısınız, benim kötü. Bu kadar dikkat etmediğim için hakettim. – Russ

6

ve gömülü WPF TextBox denetimleri: gerçi sonunda, tek ihtiyacınız böyle bir şeydir. ChildHwndSourceHook'un klavye girişi alma problemini çözmesine rağmen, ara sıra yinelenen boşluk karakterleriyle sonuçlandığımı buldum. WM_KEYDOWN mesajı alan karakterlerini güvenilir bir şekilde ele alıyor gibi görünüyor, ancak bazı boşluklar için bir çift WM_CHAR mesajı da alındı. Bunu çözmek için ben sadece WM_CHAR uzay karakterini görmezden ChildHwndSourceHook fonksiyonu, gövdesine aşağıdaki fıkra eklenmiştir:

 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

Adamım, hayatımı kurtardın, 1 günlük hata ayıklamasından sonra ... Anahtarla ilgili benzer bir sorunum var, bazen iki kez gönderildim. WM_KEYDOWN - WM_CHAR - WM_KEYUP, bu emriydi. Enter görünümleri için WM_CHAR'ı "yemek" ikiye katlama sorununun düzeltilmesi dışında bir soruna neden olmaz. – Zotyi

5

O türetilmiş TextBox oluşturmak için gerekli değildir. IOTextBox için kod, bir UserControl barındırma metin kutularında kullanılabilir. VS2010 paketinde kullanılan özel seçenekler sayfası için kullanılan WPF kontrolü ile başarılı bir şekilde test ettim.