2015-11-12 5 views
0

Мне нужно использовать компонент OnScreenKeyboard, такой как встроенная ОС Windows в приложении Wpf. Я могу вызвать пользовательский интерфейс Process.Start («osk.exe»), но пользовательский интерфейс появляется поверх главного окна ui. Я хочу запустить приложение OSK только в нижней части моего приложения. Возможно ли это с любыми аргументами? -например. process.StartInfo.WindowPosition = xxx- Я бы предпочел использовать его, прежде чем я создам свой собственный компонент.Использование встроенной экранной клавиатуры Windows в приложении WPF

+0

Главное окно * osk.exe * использует [WS_EX_TOPMOST] (https://msdn.microsoft.com/en-us/library/windows/desktop/ff700543.aspx) расширенный стиль окна, так он всегда находится перед всеми другими не-верхними окнами. Этого следует ожидать, так как пользователю придется взаимодействовать с OSK. Замаскировать его другим окном в значительной степени бросает вызов этой цели. Если вам нужно (временно) скрыть OSK, вызовите [ShowWindow] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548.aspx) в окне верхнего уровня. Более назойливым способом было бы удалить стиль 'WS_EX_TOPMOST' (' SetWindowLongPtr'). – IInspectable

ответ

0

OK. Я решил проблему с помощью метода Win32 SetWindowPos. Обмен, если это может помочь другим. Ниже код открывает и изменяет размер/позиционирует Native OSK.exe. Он помещает клавиатуру относительно положения мыши.

[StructLayout(LayoutKind.Sequential)] 
public struct POINT 
{ 
    public int X; 
    public int Y; 

    public static implicit operator Point(POINT point) 
    { 
     return new Point(point.X, point.Y); 
    } 
} 

    [DllImport("user32.dll")] 
    public static extern bool GetCursorPos(out POINT lpPoint); 

    public static Point GetCursorPosition() 
    { 
     POINT lpPoint; 
     GetCursorPos(out lpPoint); 
     //bool success = User32.GetCursorPos(out lpPoint); 
     // if (!success) 

     return lpPoint; 
    } 


    private void OSKMenuItem_Click(object sender, RoutedEventArgs e) 
    { 
     Process osk = new Process(); 
     osk.StartInfo.FileName = "osk.exe"; 
     osk.StartInfo.WindowStyle = ProcessWindowStyle.Normal; 

     osk.Start(); 

     Task.Delay(1000).ContinueWith((a) => { 
      Point p = GetCursorPosition(); 

      try 
      { 
       IntPtr target_hwnd = FindWindowByCaption(IntPtr.Zero, "On-Screen Keyboard"); 
       if (target_hwnd == IntPtr.Zero) 
       { 
        Microsoft.Windows.Controls.MessageBox.Show("Error"); 
       } 
       SetWindowPos(target_hwnd, IntPtr.Zero, (int)p.X - 200, (int)p.Y, 1300, 600, 0); 
      } 
      catch (Exception ex) 
      { 

       //throw; 
      } 
     }); 
+1

Это очень хрупкий код, также довольно непригодный как есть. Попытайтесь продолжить работу с Process.WaitForInputIdle() и MainWindowHandle. –

+0

Process.WaitforInputIdle странно не работает. Я не знаю почему. – Kubi

+1

[WaitForInputIdle не работает.] (Http://stackoverflow.com/q/33405201/1889329) – IInspectable