【问题标题】:Using Native Windows On Screen Keyboard in WPF App在 WPF 应用程序中使用本机 Windows 屏幕键盘
【发布时间】:2016-02-13 16:17:20
【问题描述】:

我需要在我的 Wpf 应用程序中使用像 Native Windows OSK 这样的 OnScreenKeyboard 组件。我可以通过 Process.Start("osk.exe") 调用 UI,但 UI 出现在主 ui 窗口的顶部。我想在我的应用程序底部启动 OSK 应用程序。这可能有任何论据吗? -例如。 process.StartInfo.WindowPosition=xxx- 我希望在创建自己的组件之前使用它。

【问题讨论】:

  • osk.exe 的主窗口使用WS_EX_TOPMOST 扩展窗口样式,因此它始终位于所有其他非最顶层窗口的前面。这是意料之中的,因为用户必须与 OSK 交互。用另一个窗口遮住它几乎违背了这个目的。如果您需要(暂时)隐藏 OSK,请在其顶层窗口中调用 ShowWindow。一种更具侵入性的方法是删除 WS_EX_TOPMOST 样式 (SetWindowLongPtr)。

标签: wpf winapi win32gui on-screen-keyboard


【解决方案1】:

好的。我用 Win32 SetWindowPos 方法解决了我的问题。分享是否可以帮助他人。下面的代码是打开和调整/定位本机 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;
            }
        });

【讨论】:

  • 那是非常脆弱的代码,也相当不可用。尝试使用 Process.WaitForInputIdle() 和 MainWindowHandle。
  • Process.WaitforInputIdle 奇怪地不起作用。我不知道为什么。
猜你喜欢
  • 2010-11-13
  • 2018-11-03
  • 2015-11-11
  • 1970-01-01
  • 2011-11-27
  • 2018-12-18
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
相关资源
最近更新 更多