【问题标题】:How to position the On-Screen Keyboard window?如何定位屏幕键盘窗口?
【发布时间】:2014-07-11 23:06:33
【问题描述】:

使用 ShellExecuteEx() 启动 osk.exe 后,我想相对于数据输入字段定位键盘窗口,这样它就不会覆盖它们。

调用前如何设置osk的窗口位置?

另外,完成后如何让应用程序隐藏 osk?

【问题讨论】:

  • @Mason:这是 Windows“屏幕键盘”辅助功能小部件。

标签: delphi on-screen-keyboard


【解决方案1】:

您可以使用FindWindow 使用窗口类“OSKMainClass”来获取窗口句柄,然后在该句柄上使用SetWindowPos 将其定位到您想要的坐标。 (您可能需要使用控件的 ClientToScreen 方法来转换为正确的坐标,但我会让您弄清楚这部分。)

// Off the top of my head - not at a machine that has a Delphi compiler at
// the moment.
var
  OSKWnd: HWnd;
begin
  OSKWnd := FindWindow(PChar('OSKMainClass'), nil);
  if OSKWnd <> 0 then
  begin
    SetWindowPos(OSKWnd, 
                 HWND_BOTTOM, 
                 NewPos.Left, 
                 NewPos.Top, 
                 NewPos.Width,
                 NewPos.Height, 
                 0);
  end;
end;

部分代码来自与同一主题相关的CodeProject article。我使用 AutoHotKey 的 Window Spy 实用程序获得了窗口类。

注意事项:

  1. Remy Lebeau 在评论中指出,您应该确保使用CreateProcess() 或ShellExecuteEx(),以便在调用FindWindow() 之前取回可以传递给WaitForInputIdle() 的进程句柄。否则,可能会在 OSK 创建窗口之前调用FindWindow()。

  2. mghie 在评论中指出,他可以让它工作的唯一方法是以管理员身份运行应用程序;否则对 SetWindowPos() 的调用会导致“拒绝访问 (5)”。

【讨论】:

  • 您还应该使用CreateProcess() 或ShellExecuteEx() 而不是ShellExecute(),以便在调用FindWindow() 之前为您提供一个可以传递给WaitForInputIdle() 的进程HANDLE。否则你可能会在 OSK 创建它的窗口之前调用它。
  • HWND_TOPMOST 和 SWP_NOZORDER 是矛盾的
  • @David:谢谢。我从链接项目转录的错误。已更正。
  • @KenWhite 感谢肯和其他人。 OSK 似乎没有注意到我的任何 SetWindowPos 设置。由于 OSK 出现在它想要的位置并以固定大小出现,因此 Top/etc 似乎被忽略了。另外,我查看了 CodeProject,试图找到隐藏 OSK 的方法,但还没有任何效果,包括 NoActivate。
  • @user2175495:如果它不能解决你的问题,你为什么要接受它?
【解决方案2】:

如上所述,我不能移动窗口。 使用 Win32 命令,SetWindow 或 MoveWindow 不适用于屏幕键盘。 它仅在以 admin 权限 运行 exe 时起作用。

我认为这不是一个好的解决方案。 我找到了另一个解决方案。 请通过这个。 尝试使用注册表值后,它运行良好,我可以在我的应用程序中移动屏幕键盘

试试

                               {

                               RegistryKey myKey = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Osk", true);

                               myKey.SetValue("WindowLeft", oskLeft, RegistryValueKind.DWord);
                               myKey.SetValue("WindowTop", oskTop, RegistryValueKind.DWord);


                               }

                               catch

                               {

                                        //Log the error
                               }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-20
    • 2023-01-25
    • 1970-01-01
    • 2019-01-10
    • 2018-12-13
    相关资源
    最近更新 更多