Metro的东西在什么桌面上运行?

时间:2014-04-20 02:59:14

标签: c++ c winapi microsoft-metro win32gui

只是好奇,从WinAPI开发人员的角度来看,运行Metro应用程序的desktop是什么?

这个东西:

enter image description here

2 个答案:

答案 0 :(得分:24)

我不知道这将是一个秘密...所以我不得不做一些调查,这就是我发现的:

首先,回答我的原始问题 - Metro(或现代用户界面)内容与"桌面"完全相同desktop。应用程序(原谅双关语。)它实际上非常简单。简短的回答 - 所有 Microsoft批准的 Metro内容都在Internet Explorer_Server容器中运行(以外行人的名义,就是Internet Explorer);或者在DirectUIHWND容器(这是Microsoft提供其未记录的UI的专有类)中,所有这些都在打开WS_EX_TOPMOST样式的窗口中,这使得它们在其他内容之上呈现。就是这样!

以下是几个例子:

让我们拆分桌面并使用Spy++查看幕后发生的事情:

enter image description here

因此,如果我们调查"天气"应用程序窗口,它只不过是类#34; Internet Explorer_Server"的常规(Win32)窗口。它位于" Web Platform Embedding"的窗口中。阶级,而后者又位于" Windows.UI.Core.CoreWindow" on WS_EX_TOPMOSTWS_EX_NOREDIRECTIONBITMAP样式的容器:

enter image description here

如果你看得更深,那么所有微软的Metro 东西似乎都来自WWAHOST.exe进程,简单来说就是为Metro应用程序运行JavaScript的容器

现在让我们看一下Start Screen本身。由于它完全覆盖了桌面,我们需要使用不同的工具及其Shift键快照功能来实现它:

enter image description here

从中我们可以获得Start Screen的窗口句柄(或者我的情况下为0x10158)并在Spy ++中查找:

enter image description here

正如您从两个工具中看到的那样,“开始屏幕”具有窗口类DirectUIHWND,它位于ImmersiveLauncher类的窗口内,即WS_EX_TOPMOSTWS_EX_NOREDIRECTIONBITMAP的窗口。 Windows.UI.Core.CoreWindow样式使其保持最佳状态。这是 it 和"桌面"创建的任何其他窗口之间的唯一区别。应用

有趣的是"桌面"在出现分裂窗口的情况下呈现本身。我最初假设在这种情况下,桌面只是简单地移动(或移动)到一侧并调整大小,但不是会发生什么......实际上(或在我的Windows 8.1中)如果是在桌面和Metro应用程序之间进行拆分,metro应用程序只覆盖桌面,但桌面本身不会更改其位置或大小。在这种情况下,仅移动任务栏和现有桌面窗口并调整其大小以适合拆分。这可以通过以下图表来说明:

enter image description here

作为旁注,这样的移动和调整大小对用户来说可能非常烦人,因为当分割消失时,桌面窗口的原始位置和大小不会恢复。

最后,一个意外的发现。我决定查看Google用户如何实施他们的Chrome浏览器(作为Metro应用程序运行)并找到了:

enter image description here

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 ,或者不要求提升您的流程。)

  • 对您的流程进行代码签名。重要的是,由于没有签名它不会起作用,您将看到此错误消息:" 从服务器返回引用。"

enter image description here

替代签名(或用于开发系统上的测试目的),您可以将以下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}}

可以做到这一点:

enter image description here

答案 1 :(得分:7)

由于您说您的实际问题是知道Metro应用程序是否正在运行,因此答案是致电IAppVisibility::GetAppVisibilityOnMonitor。通过要检查的显示器。请注意,无论应用程序运行的桌面是什么,这都将给​​出正确的答案。