我有一个隐藏的进程,等待非标准的硬件按钮消息并运行一个应用程序(使用CreateProcess)。用户干扰没问题,这是用户自己认可的动作。当通常的布局显示任务栏并且加上字幕和非字幕窗口时,一切都很好。但是当前应用程序是全屏时,XP和7的情况有所不同。在这种情况下,全屏应用是没有边框的窗口具有与屏幕完全相同的尺寸。 Windows隐藏了此类应用程序的任务栏,即使它始终打开。
在Xp中,没关系,在这种情况下显示任务栏和应用程序(例如计算器),全屏应用程序仍然可以在启动的应用程序和任务栏以外的区域中看到。但是在Windows 7中没有任何视觉效果,全屏幕应用程序仍处于打开状态,如果我切换到任务栏,则执行的应用程序就在那里。我试图用SetForegroundWindow,BringWindowToTop,甚至AllowSetForegroundWindow(GetCurrentProcessId())调用一个用CreateProcess-WaitForIntputIdle-EnumThreadWindows找到的窗口句柄来解决它,没有变化。因为XP与正式记录的全屏窗口相关,所以做了一些改变吗?
谢谢,
最高
答案 0 :(得分:1)
Vista引入了desktop composition功能。简而言之,所有窗口都绘制到内存位图,桌面窗口管理器然后组成这些位图并在全屏Direct3D表面上绘图。全屏窗口不参与桌面合成并直接在屏幕上绘图(主要是因为大多数全屏应用都是需要实时屏幕更新的游戏)。
特别是,这意味着当全屏应用程序启动并运行时,它将覆盖DWM组合图像,并且用户需要切换到DWM管理的窗口,以便DWM开始在完整的基础上绘图屏幕应用。
遗憾的是,我没有很好的解决方案。解决这个问题的一种方法是将WS_CAPTION样式添加到您的应用程序,然后自己处理WM_NCPAINT
/ WM_NCCALCSIZE
/ WM_NCHITTEST
。这将允许您欺骗DWM您是一个常规的窗口应用程序,但可视化您的NC区域看起来像你没有标题。但是,这确实需要一定数量的额外代码,并且您可能需要投入更多精力。
您可以尝试解决问题的另一种方法是在启动新流程时明确最小化全屏应用程序窗口。但是,您必须解决何时再次将其最大化的问题。
顺便说一句,你可能会发现Raymond Chen对this post的评论很有意思。
答案 1 :(得分:1)
我想,如果你有自己的硬件设备,那就有一些用于生成“真实”用户输入的API。显然,传统的键盘和鼠标,以及现在的USB HID驱动程序(我认为其中许多是用户模式?)都可以访问API。
Synergy +例如可以在连接的PC上生成虚假的键盘和鼠标事件,伪造输入的结果是正常的窗口切换激活。
所以,我最初的想法是让你的用户模式“设备”应用程序合成实际的键盘消息 - SendInput似乎可能是“可以”伪造“真实用户输入事件的API。
然后,在“UI”应用中使用类似RegisterHotKey的API来响应设备应用生成的热键组合。
现在,(假设SendInput IS在正确级别生成用户输入事件),您应该(从UI应用程序中的WM_HOTKEY处理程序中)获得权限(因为所有内容都是“用户启动”)来更改前景窗口(对你自己)。
答案 2 :(得分:0)
Windows支持多个desktops,我的猜测是全屏使用的是与默认桌面不同的桌面(显示应用程序的位置)。 Windows中的桌面对象是“逻辑显示表面,包含用户界面对象,如窗口,菜单和挂钩”。例如,屏幕保护程序通常在单独的桌面上启动。
您可以使用Process Explorer找出运行应用程序的桌面:
如果您知道此应用运行的桌面是什么,您可以先在同一桌面上启动您的流程,先致电OpenDesktop
以获取此桌面的句柄,然后将其传递到您的STARTUPINFO
CreateProcess
致电。