使用 ShellExecuteEx() 启动 osk.exe 后,我想相对于数据输入字段定位键盘窗口,这样它就不会覆盖它们。
如何在调用 osk 之前设置它的窗口位置?
另外,完成后如何让应用程序隐藏 osk?
使用 ShellExecuteEx() 启动 osk.exe 后,我想相对于数据输入字段定位键盘窗口,这样它就不会覆盖它们。
如何在调用 osk 之前设置它的窗口位置?
另外,完成后如何让应用程序隐藏 osk?
您可以使用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 实用程序获得了窗口类。
笔记:
Remy Lebeau 在评论中指出,您应该确保使用CreateProcess()
orShellExecuteEx()
以便您取回一个进程句柄,然后WaitForInputIdle()
在调用FindWindow()
. 否则调用FindWindow()
可能发生在 OSK 创建窗口之前。
mghie 在评论中指出,他可以让它工作的唯一方法是以管理员身份运行应用程序;否则调用会SetWindowPos()
导致“拒绝访问 (5)”。
如上所述,我不能移动窗口。使用 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
}