我一直试图让屏幕键盘(osk.exe
)在我的应用程序中出现(并消失)在Windows 10上。我的应用程序在Windows 7中正常运行。在ShellExecute()
上调用osk.exe
会在那里显示键盘,但尝试在Windows 10中获得相同的行为已经证明是一种痛苦。
尝试隐藏键盘,一旦可见,我就试过了:
HANDLE wHandle = FindWindowW(L"OSKMainClass", L"On-Screen Keyboard");
if (wHandle != NULL)
{
long style = GetWindowLong(wHandle, GWL_STYLE);
if (style & WS_VISIBLE)
{
return TRUE;
}
else
{
SetWindowLongPtr(wHandle, GWL_STYLE, WS_VISIBLE);
}
但这没有效果。
我也尝试使用TabTip keyboard,但无法检测到它何时可见(我可以检测到它 不可见但是我无法获得当它可见时处理它!)。
对此问题的任何帮助都将不胜感激。
更新:osk
最初未显示的原因是' nCmdShow parameter supplied to
ShellExecute`,原始代码为此值提供了NULL,它在Windows上正常运行7所以我假设问题是搁置的。将它从NULL更改为SW_SHOWNORMAL修复了出现键盘的问题。
Paul Sanders的评论:在32位应用程序中,您还需要做一件事,请参阅:https://stackoverflow.com/a/50510526/5743288。
答案 0 :(得分:2)
您可以使用WinAPI中的IsWindowVisible
函数来确定您的hwnd是否是可见窗口。你试过吗?直接为这样简单的任务检查和管理标志不是最好的主意
https://msdn.microsoft.com/en-us/library/windows/desktop/ms633530(v=vs.85).aspx
答案 1 :(得分:2)
我决定重写这个答案,因为原文包含了很多不相关的细节,其中大部分是错误的。现在我已经正确地理解它实际上是如何运作的,而且说的话要少得多,而且对未来的访问者来说应该说的更有用。
首先,OP问题的答案是here。这应该让他完全按照自己的意愿行事。感谢@ zett42指出WM_SYSCOMMAND
技巧。现在是有趣的东西。
问题1:为什么在调用WM_SYSCOMMAND
时向osk
主窗口发布ShowWindow()
消息,正如OP试图做的那样,不?
答案:好吧,撇开隐藏OSK而不是关闭或最小化它的事实可能不是一个好主意,答案在于UI Privilege Level Isolation
(UIPI)。 OSK
运行升级,这限制了常规应用操作的方式。您可以阅读有关UIPI here的更多信息。
为了将来参考,您可以使用SysInternals'来判断程序是否正在运行。 Process Explorer。如果查看Process Properties窗口的Security选项卡,那么对于OSK,您会看到:
标志:诚信组:强制性标签\ 高强制性标签
而对于(例如)设置应用,您会看到:
标志:诚信组:强制性标签\ 中等强制性标签
问题2: OSK
是否属于UWP应用程序会影响其中任何一项(请参阅@IInspectable下面的评论)?
答案:实际上,没有。 UWP应用程序的顶级HWND似乎只是普通的HWND,尽管是Microsoft don't want you to rely on that。您可以使用Spy++(和use the 64 bit version, lol)调查他们使用的确切窗口层次结构 - 它的含义。
旁白:
OP,请尝试编写better questions。这个是一团糟,它造成了很多麻烦。我已经通过示例编辑了您的问题并为将来的访问者进行了清理,请查看。请投票给我。我已经获得了它。
发布回复的人:请先做一些研究。这个帖子中的其他答案没有用,部分(我会是第一个承认的),因为问题最初的措辞方式。我自己在最初的评论中犯了这个错误,所以我们都可以从中学习。
答案 2 :(得分:0)
你犯了一些错误:
如果您使用作业而不是考试
在SetWindowLongPtr
中只设置了一位,所有现有标志都丢失了。你应该使用:
long style = GetWindowLong(wHandle, GWL_STYLE);
if (style & WS_VISIBLE) // test
{
return TRUE;
}
else
{
style |= WS_VISIBLE; // set the bit
SetWindowLongPtr(wHandle, GWL_STYLE, style); // set the new style
ShowWindow(wHandle, SW_SHOWDEFAULT);
}
注意:Windows文档说明您必须致电SetWindowPos
,而不是ShowWindow
。