2016-08-11 1 views
8

Ich versuche, die Osk in ein WPF-Fenster oder ein Benutzersteuerelement einzubetten, und ich habe den Code unten gefunden und es funktioniert für Notepad aber für tabtip.exe, sagt es es hat keine grafische Oberfläche ??Wie verbinde ich tabtip.exe in Windows

WaitForInputIdle fehlgeschlagen. Dies könnte daran liegen, dass der Prozess keine grafische Oberfläche hat.

Ich habe versucht, es für eine Weile statt Aufruf WaitForInputIdle Methode schlafen zu lassen, aber es wirft eine weitere Ausnahme:

Prozess beendet wird, so dass die angeforderten Informationen ist nicht verfügbar.

Aber in meinem Task-Manager kann ich noch TabTip.exe laufen sehen.

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     private System.Windows.Forms.Panel _panel; 
     private Process _process; 

     public MainWindow() 
     { 
      InitializeComponent(); 
      _panel = new System.Windows.Forms.Panel(); 
      windowsFormsHost1.Child = _panel; 
     } 

     [DllImport("user32.dll")] 
     private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong); 

     [DllImport("user32.dll", SetLastError = true)] 
     private static extern int GetWindowLong(IntPtr hWnd, int nIndex); 

     [DllImport("user32")] 
     private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent); 

     [DllImport("user32")] 
     private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags); 

     private const int SWP_NOZORDER = 0x0004; 
     private const int SWP_NOACTIVATE = 0x0010; 
     private const int GWL_STYLE = -16; 
     private const int WS_CAPTION = 0x00C00000; 
     private const int WS_THICKFRAME = 0x00040000; 


     protected override void OnClosing(System.ComponentModel.CancelEventArgs e) 
     { 
      base.OnClosing(e); 
      if (_process != null) 
      { 
       _process.Refresh(); 
       _process.Close(); 
      } 
     } 

     private void ResizeEmbeddedApp() 
     { 
      if (_process == null) 
       return; 

      SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, (int)_panel.ClientSize.Width, (int)_panel.ClientSize.Height, SWP_NOZORDER | SWP_NOACTIVATE); 
     } 

     protected override Size MeasureOverride(Size availableSize) 
     { 
      Size size = base.MeasureOverride(availableSize); 
      ResizeEmbeddedApp(); 
      return size; 
     } 

     private void button1_Click_1(object sender, RoutedEventArgs e) 
     { 
      button1.Visibility = Visibility.Hidden; 
      ProcessStartInfo psi = new ProcessStartInfo("C:\\Program Files\\Common Files\\microsoft shared\\ink\\TabTip.exe"); 
      _process = Process.Start(psi); 

      Thread.Sleep(500); 
      //_process.WaitForInputIdle(); 

      SetParent(_process.MainWindowHandle, _panel.Handle); 

      // remove control box 
      int style = GetWindowLong(_process.MainWindowHandle, GWL_STYLE); 
      style = style & ~WS_CAPTION & ~WS_THICKFRAME; 
      SetWindowLong(_process.MainWindowHandle, GWL_STYLE, style); 

      // resize embedded application & refresh 
      ResizeEmbeddedApp(); 
     } 

    } 
} 

Edit: Inspiriert von rene Kommentar, ich habe versucht, wie unten das Fenster ptr zu erhalten und verwenden Spion ++ zu überprüfen, ob die Adresse, die Findwindow gibt das richtige Fenster zeigt, aber es bewegt mich nach wie vor nicht:

Edit 2: Mein erster Gedanke war, dass Tab-Tipp konnte nicht in der Größe geändert werden, aber dann bemerkte ich ein Verhalten, wenn ich das Fenster über zwei verschiedene Bildschirm bewegen, wird es die Größe an die Bildschirmgröße anpassen, also bin ich sicher, dass es eine Möglichkeit geben muss, die Größe zu ändern, also habe ich spy ++ (x64) gestartet, um zu überprüfen:

Edit 3: nachdem ich mit user32 api getüftelt habe und keinen Fortschritt, habe ich versucht, einen Speicherscanner zu verwenden, um nach der x- und y-Position von tabtip zu suchen und sie zu ändern ausgelöst wird, frage ich mich, ob es machbar ist, diesen Weg zu gehen.

+1

Ich denke, die Instanz, die Sie starten, wird sofort geschlossen. [Diese Antworten] (http://stackoverflow.com/questions/17090325/show-hiding-the-windows-8-on-screen-keyboard-from-wpf) schlagen vor, dass Sie nach einem Fenster suchen müssen, das nicht unbedingt ist das Hauptfenster der Prozessinstanz, die Sie gestartet haben. – rene

+0

kann dies Ihnen helfen http://geekswithblogs.net/TechTwaddle/archive/2009/10/16/how-to-embed-an-exe-inside-another-exe-as-a.aspx – Mangrio

+0

@QadeerMangrio Ich bin Ich suche, tabtip in einem anderen Fenster grafisch einzubetten, von dem, was ich verstehe, spricht der Blog darüber, wie man in Begriffen des Gedächtnisses einbindet. –

Antwort

1

Können Sie versuchen, Ihren Handle-Code in STA-Thread auszuführen? Ich hatte ein ähnliches Problem mit dem nativen Fenster, das ich mit STA-Thread gelöst hatte.

var thread = new Thread(() => { 
      // Your code here 
}); 
thread.TrySetApartmentState(ApartmentState.STA); 
thread.Start(); 
+0

Ich bin nicht sicher, wie das einen Unterschied machen wird, aber ich habe es trotzdem versucht, es hat nicht geholfen. –

Verwandte Themen