为什么user32.dll GetTopWindow返回名为“ MSCTFIME UI”的句柄?

时间:2019-11-08 18:18:33

标签: topmost setwindowpos

我试图将我的应用程序放在Windows的最顶层。因此,我正在调用此代码以将程序设置在所有内容之上:

SetWindowPos(MyProgramHWND, HWND_TOPMOST, CENTER_ME_W, CENTER_ME_Y, windowSize.x, windowSize.y, SWP_SHOWWINDOW);

那行得通。但是,另一个第三方程序决定窃取我的最高职位,因此我需要将程序“保持”在最前面。为此,我想检查我的程序是否位于顶部。

因此,在在线搜索之后,我正在使用以下代码来捕获应该位于顶部的窗口的HWND:

IntPtr TopHWND = GetTopWindow((IntPtr)null);

根据我在网上阅读的内容,调用GetTopWindow并传递一个null应该可以获取整个桌面的顶部窗口。

但是它返回的是一个奇怪的窗口,该窗口的GetWindowText和GetClassName都在返回:“ MSCTFIME UI”。这似乎既不是我的程序,也不是与我竞争最高奖项的其他程序。实际上,我什至不知道什么是“ MSCTFIME UI”!

我已经尽一切努力弄清楚“ MSCTFIME UI”是什么,或者它是否是某个父窗口,其中包含我正在寻找的窗口。它具有零个子窗口(根据EnumChildWindows),因此它似乎不是某种形式的父窗口或容器。我尝试在GetProcessesByName中找到它,但是找不到。我什至尝试使用ProcessExplorer(可以免费下载的独立应用程序)进行搜索,但我全力以赴找不到它。我真的不知道什么是“ MSCTFIME UI”!甚至谷歌搜索它也很少得到结果,没有一个解释它到底是什么。

谁能解释什么是“ MSCTFIME UI”,以及为什么GetTopWindow((IntPtr)null)返回它的hwnd?

注意:它总是返回“ MSCTFIME UI”作为最顶部的窗口,无论是将我的应用程序放在顶部,还是将另一个应用程序放在顶部,都没有关系。在所有情况下,它总是返回“ MSCTFIME UI”作为最上面的窗口。

1 个答案:

答案 0 :(得分:0)

所以我看到这个问题很旧,但是我最近正在尝试做类似的事情,所以我将在这里记录我的解决方案以供将来的读者...

首先,我们可以在创建任何Windows之前通过在应用程序启动时运行以下命令来禁用应用程序的输入法编辑器:

ImmDisableIME(GetCurrentThreadId());

这将防止在我们的窗口上方创建隐藏的IME窗口。但是,这也可能会破坏日语输入,因此请注意。

我们接下来要做的就是检查上面的窗口是否可见:

HWND windowAboveMe = GetWindow(hwnd,GW_HWNDPREV);
WINBOOL isAboveVisible = IsWindowVisible(windowAboveMe);

然后,如果窗口可见,我们可以将自己的窗口向上移:

if (isAboveVisible) {
    SetWindowPos(global_hwndMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
}

此代码在我正在使用的用例中有效。将窗口保持在开始菜单上方没有任何作用。在这种情况下,IsWindowVisible在Explorer.exe拥有的ToolTip类窗口上返回false。

其他选择是递归调用HWND hwndAbove = GetWindow(hwnd,GW_HWNDPREV)直到hwndAbove返回0,然后用GetWindowThreadProcessId(hwndAbove, &aboveHandle);GetProcessImageFileName(...)检查每个窗口,以查看z.explorer.exe以外的进程是否在z中更高。 -订购。我还考虑过使用WindowFromPoint来测试窗口上某个点之前是否有任何可见的窗口,但最终并未对其进行测试。