答案 0 :(得分:24)
我不知道这将是一个秘密...所以我不得不做一些调查,这就是我发现的:
首先,回答我的原始问题 - Metro(或现代用户界面)内容与"桌面"完全相同desktop。应用程序(原谅双关语。)它实际上非常简单。简短的回答 - 所有 Microsoft批准的 Metro内容都在Internet Explorer_Server
容器中运行(以外行人的名义,就是Internet Explorer);或者在DirectUIHWND
容器(这是Microsoft提供其未记录的UI的专有类)中,所有这些都在打开WS_EX_TOPMOST
样式的窗口中,这使得它们在其他内容之上呈现。就是这样!
以下是几个例子:
让我们拆分桌面并使用Spy++
查看幕后发生的事情:
因此,如果我们调查"天气"应用程序窗口,它只不过是类#34; Internet Explorer_Server
"的常规(Win32)窗口。它位于" Web Platform Embedding
"的窗口中。阶级,而后者又位于" Windows.UI.Core.CoreWindow
" on WS_EX_TOPMOST
和WS_EX_NOREDIRECTIONBITMAP
样式的容器:
如果你看得更深,那么所有微软的Metro 东西似乎都来自WWAHOST.exe
进程,简单来说就是为Metro应用程序运行JavaScript的容器
现在让我们看一下Start Screen本身。由于它完全覆盖了桌面,我们需要使用不同的工具及其Shift键快照功能来实现它:
从中我们可以获得Start Screen的窗口句柄(或者我的情况下为0x10158
)并在Spy ++中查找:
正如您从两个工具中看到的那样,“开始屏幕”具有窗口类DirectUIHWND
,它位于ImmersiveLauncher
类的窗口内,即WS_EX_TOPMOST
和WS_EX_NOREDIRECTIONBITMAP
的窗口。 Windows.UI.Core.CoreWindow
样式使其保持最佳状态。这是 it 和"桌面"创建的任何其他窗口之间的唯一区别。应用
有趣的是"桌面"在出现分裂窗口的情况下呈现本身。我最初假设在这种情况下,桌面只是简单地移动(或移动)到一侧并调整大小,但不是会发生什么......实际上(或在我的Windows 8.1中)如果是在桌面和Metro应用程序之间进行拆分,metro应用程序只覆盖桌面,但桌面本身不会更改其位置或大小。在这种情况下,仅移动任务栏和现有桌面窗口并调整其大小以适合拆分。这可以通过以下图表来说明:
作为旁注,这样的移动和调整大小对用户来说可能非常烦人,因为当分割消失时,桌面窗口的原始位置和大小不会恢复。
最后,一个意外的发现。我决定查看Google用户如何实施他们的Chrome浏览器(作为Metro应用程序运行)并找到了:
Chrome浏览器在C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
类窗口中呈现,属于Google自己的流程:" UIAccess="true"
"。因此,如果不深入,显然可以将Metro风格的应用程序封装在非Microsoft容器中,这对于不关心AppStore XAML应用程序的开发人员来说是一个好消息:)
编辑:忘记提及,如果您打算在Metro应用程序顶部显示的Win32进程中显示自己的弹出消息,则需要执行以下操作:
在流程清单中设置Project Properties
。您可以通过转到Linker
- >在Visual Studio中执行此操作。 Manifest Files
- > UAC Bypass UI Protection
并将UAC Execution Level
设置为YES。 (请注意,您可以将asInvoker
保留为HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\ValidateAdminCodeSignatures
,或者不要求提升您的流程。)
对您的流程进行代码签名。重要的是,由于没有签名它不会起作用,您将看到此错误消息:" 从服务器返回引用。"
替代签名(或用于开发系统上的测试目的),您可以将以下registry key设置为0.(我还没有尝试过,而且不会'由于明显的安全问题,推荐它!但如果代码签名证书不可用,它似乎是另一种测试方式。)
%windir%\System32
%ProgramFiles%\Company\Product
文件夹,或者更真实地放入%ProgramFiles(X86)%\Company\Product
或产品安装位置的备用WS_EX_TOPMOST
文件夹中。< / LI>
另外,您可以考虑阅读有关此主题的Raymond Chen's article。
//You may also consider setting the WS_EX_NOACTIVATE style
::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0 , 0, 0, SWP_NOMOVE | SWP_NOSIZE);
样式时,它将显示在任何其他窗口上方,包括Metro应用程序,开始屏幕等。换句话说,这样做:
{{1}}
可以做到这一点:
答案 1 :(得分:7)
由于您说您的实际问题是知道Metro应用程序是否正在运行,因此答案是致电IAppVisibility::GetAppVisibilityOnMonitor
。通过要检查的显示器。请注意,无论应用程序运行的桌面是什么,这都将给出正确的答案。