C++ Metro stuff运行在什么桌面上?
只是好奇,从WinAPI开发者的角度来看,Metro应用程序运行在什么环境中 这些东西:C++ Metro stuff运行在什么桌面上?,c++,c,winapi,microsoft-metro,win32gui,C++,C,Winapi,Microsoft Metro,Win32gui,只是好奇,从WinAPI开发者的角度来看,Metro应用程序运行在什么环境中 这些东西: 我不知道这会是一个如此秘密。。。所以我必须做一些调查,以下是我的发现: 首先,回答我最初的问题——Metro(或现代UI)的运行方式与“桌面”应用程序完全相同(请原谅这个双关语)。实际上,这一切都非常简单。简而言之,所有微软批准的Metro产品都运行在InternetExplorer\u服务器容器中(用外行的话说就是InternetExplorer);或者在容器(这是Microsoft的专有类,用于呈现其未
我不知道这会是一个如此秘密。。。所以我必须做一些调查,以下是我的发现: 首先,回答我最初的问题——Metro(或现代UI)的运行方式与“桌面”应用程序完全相同(请原谅这个双关语)。实际上,这一切都非常简单。简而言之,所有微软批准的Metro产品都运行在
InternetExplorer\u服务器
容器中(用外行的话说就是InternetExplorer);或者在容器(这是Microsoft的专有类,用于呈现其未记录的UI)中,都在windows中,且样式已打开,这使它们呈现在其他内容之上。就这样
这里有几个例子:
让我们拆分桌面并使用Spy++
查看引擎盖下发生的事情:
因此,如果我们查看“天气”应用程序窗口,它只不过是类“internetexplorer\u Server
”的常规(Win32)窗口,该类位于“webplatformembedding
”类的窗口中,而该类又位于“Windows.UI.Core.corefown
”中在以下位置上具有WS\u EX\u最顶部
和WS\u EX\u NOREDIRECTIONBITMAP
样式的容器:
如果你看得更深入一些,所有微软的Metro东西似乎都是从这个过程中运行的,简单来说,这个过程就是为Metro应用程序运行JavaScript的容器
现在让我们来看看这个问题本身。由于它完全覆盖了桌面,我们需要使用不同的工具及其Shift键快照功能来访问它:
通过它,我们可以获得开始屏幕的窗口句柄(或者在我的例子中是0x10158
),并在Spy++中查找它:
从这两个工具中可以看到,“开始”屏幕有一个窗口类,它位于ImmersiveLauncher
类的窗口中,该类具有WS_EX_TOPMOST
和WS_EX_NOREDIRECTIONBITMAP
样式,使其保持在顶部。这是它与“桌面”应用程序创建的任何其他窗口之间的唯一区别
同样有趣的是,在拆分窗口的情况下,“桌面”本身是如何呈现的。我最初认为,在这种情况下,桌面只是简单地移到(或移动)一边并调整大小,但事实并非如此。。。在现实中(或在我的Windows 8.1中),如果桌面和Metro应用程序分离,Metro应用程序只覆盖桌面,但桌面本身不会改变其位置或大小。在这种情况下,仅移动任务栏和现有桌面窗口并调整其大小以适应拆分。这可以通过以下图表来说明:
顺便说一句,这种移动和调整大小对于用户来说是非常烦人的,因为当拆分消失时,桌面窗口的原始位置和大小不会恢复
最后,一个有点出乎意料的发现。我决定检查一下Google人员是如何实现他们的Chrome浏览器(作为Metro应用程序运行)的,并发现:
Chrome在Windows.UI.Core.CoreWindow
类窗口中呈现,属于Google自己的进程:“C:\ProgramFiles(x86)\Google\Chrome\Application\Chrome.exe
”。因此,不用深入研究,显然可以将Metro风格的应用程序封装在非Microsoft容器中,这对于不关心AppStore XAML应用程序的开发人员来说是个好消息:)
编辑:忘了提及,如果您计划从Win32进程中显示自己的弹出消息,并且该消息在Metro应用程序顶部可见,则需要执行以下操作:
- 在流程清单中设置
。您可以在Visual Studio中执行此操作,方法是转到UIAccess=“true”
项目属性
->
链接器
->
清单文件
,然后将
UAC旁路UI保护设置为是。(请注意,您可以将
UAC执行级别保持为
,也可以不要求提升流程。)asInvoker
- 对流程进行代码签名。这很重要,因为如果没有签名,它将无法工作,您将看到以下错误消息:“从服务器返回了一个引用。”
- 将编译后的可执行文件放入
文件夹,或者更实际地放入%windir%\System32
文件夹,或者放入产品安装位置的备选%ProgramFiles%\Company\Product
文件夹%ProgramFiles(X86)%\Company\Product
- 之后,当您在弹出窗口上设置
样式时,它将显示在任何其他窗口的上方,包括Metro应用程序、开始屏幕等WS_EX_TOPMOST
//You may also consider setting the WS_EX_NOACTIVATE style
::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0 , 0, 0, SWP_NOMOVE | SWP_NOSIZE);
我们可以做到这一点:
既然您说您的实际问题是知道Metro应用程序是否正在运行,那么答案就是调用
IAppVisibility::GetAppVisibilityOnMonitor
。通过要检查的监视器。请注意,无论应用程序在哪个桌面上运行,这都将给出正确答案。这是一个实施细节,可能会发生更改。你的实际编程问题是什么?@RaymondChen:知识。除此之外,如果Metro应用程序正在运行,我可能需要显示一个弹出通知。已经有一个,但显然没有人知道。尽管如此,我还是想知道,除了技术基础之外,这种以全屏模式运行应用程序的疯狂决定是如何实现的
//You may also consider setting the WS_EX_NOACTIVATE style
::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0 , 0, 0, SWP_NOMOVE | SWP_NOSIZE);