3

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

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

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

4

2 回答 2

5

您可以使用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 文章。我使用 AutoHotKey 的 Window Spy 实用程序获得了窗口类。

笔记:

  1. Remy Lebeau 在评论中指出,您应该确保使用CreateProcess()orShellExecuteEx()以便您取回一个进程句柄,然后WaitForInputIdle()在调用FindWindow(). 否则调用FindWindow()可能发生在 OSK 创建窗口之前。

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

于 2014-07-12T00:16:29.233 回答
1

如上所述,我不能移动窗口。使用 Win32 命令,SetWindow 或 MoveWindow 不适用于屏幕键盘。它仅在以管理员权限运行 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
                               }
于 2015-07-13T05:45:30.520 回答