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

c00*_*0fd 9 c c++ winapi win32gui microsoft-metro

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

这个东西:

在此输入图像描述

c00*_*0fd 26

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

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

这里有几个例子:

让我们拆分桌面并使用它Spy++来查看引擎盖下发生的事情:

在此输入图像描述

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

在此输入图像描述

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

现在让我们看看开始屏幕本身.由于它完全覆盖桌面,我们需要使用不同的工具及其Shift键快照功能来实现:

在此输入图像描述

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

在此输入图像描述

你可以从两个工具看,在开始屏幕上有窗口类DirectUIHWND,即容纳在一个窗口内ImmersiveLauncher类,那是一个与WS_EX_TOPMOSTWS_EX_NOREDIRECTIONBITMAP风格,使其保持领先.这是与"桌面"应用程序创建的任何其他窗口之间的唯一区别.

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

在此输入图像描述

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

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

在此输入图像描述

Chrome在Windows.UI.Core.CoreWindow类窗口中呈现,属于Google自己的流程:" C:\Program Files (x86)\Google\Chrome\Application\chrome.exe".因此,如果不深入,显然可以将Metro风格的应用程序封装在非Microsoft容器中,这对于不关心AppStore XAML应用程序的开发人员来说是一个好消息:)

编辑:忘记提及,如果您打算从Metro应用程序顶部可见的Win32进程显示您自己的弹出消息,您需要执行以下操作:

  • 设置UIAccess="true"在流程清单中.您可以在Visual Studio中执行此操作,方法是转到Project Properties- > Linker- > Manifest Files并设置UAC Bypass UI Protection为YES.(请注意,您可以保留UAC Execution Level作为asInvoker,或不要求你的进程的高度.)

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

在此输入图像描述

作为签名(或用于开发系统上的测试目的)的替代方法,您可以将以下注册表项设置为0.(我没有尝试过,但由于明显的安全问题,我不推荐它!但它似乎如果代码签名证书不可用,则测试它是另一种方法.)

HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\ValidateAdminCodeSignatures
Run Code Online (Sandbox Code Playgroud)
  • 将已编译的可执行文件放入%windir%\System32文件夹中,或者更实际地放入产品安装位置%ProgramFiles%\Company\Product的备用%ProgramFiles(X86)%\Company\Product文件夹中.

您也可以考虑阅读Raymond Chen关于此主题的文章.

  • 之后,当您WS_EX_TOPMOST在弹出窗口中设置样式时,它将显示在任何其他窗口上方,包括Metro应用程序,开始屏幕等.

换句话说,这样做:

//You may also consider setting the WS_EX_NOACTIVATE style
::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0 , 0, 0, SWP_NOMOVE | SWP_NOSIZE);
Run Code Online (Sandbox Code Playgroud)

可以做到这一点:

在此输入图像描述


Ray*_*hen 7

既然您说您的实际问题是知道Metro应用程序是否正在运行,那么答案就是打电话IAppVisibility::GetAppVisibilityOnMonitor.通过要检查的显示器.请注意,无论应用程序运行的桌面是什么,这都将给​​出正确的答案.

  • 正如文档中所述,[用`CLSID_AppVisibility`调用`CoCreateInstance`函数](http://msdn.microsoft.com/en-us/library/windows/desktop/jj554119(v = vs.85).aspx ).这为您提供了一个支持`IAppVisiblity`的对象.调用`GetAppVisibilityOnMonitor`方法. (2认同)
  • 该界面是在Windows 8中引入的,因此您需要安装适用于Windows 8的Platform SDK. (2认同)