问题描述
从WinAPI开发人员的角度来看,桌面可以在其中运行Metro应用吗?
Just curious, from a standpoint of WinAPI developer, what desktop do Metro apps run in?
这个东西:
推荐答案
我不知道这会是个秘密...所以我不得不做一些调查,这就是我发现的东西:
I didn't know that it would be such a secret... so I had to do some investigating and here's what I found:
首先,要回答我的原始问题-Metro(或Modern UI)内容在完全相同的台式机作为台式机"应用程序(对双关语).实际上,这非常简单.简短的答案-所有 Microsoft批准的 Metro内容都在Internet Explorer_Server
容器中运行(用外行的话来说是Internet Explorer);或在 DirectUIHWND
容器(这是呈现其未记录的UI的Microsoft专有类)中 WS_EX_TOPMOST
样式已启用,这使得它们可以在其他内容之上呈现.就是这样!
First off, to answer my original question -- the Metro (or Modern UI) stuff runs in the exact same desktop as the "desktop" apps (pardon the pun.) It is actually all very simple. The short answer -- all Microsoft approved Metro stuff runs in the Internet Explorer_Server
container (which, in layman's terms, is the Internet Explorer); or in the DirectUIHWND
container (which is Microsoft's proprietary class that renders their undocumented UI), all in windows with the WS_EX_TOPMOST
style turned on, which makes them render on top of the other content. And that is it!
以下是几个示例:
让我们拆分桌面,然后使用Spy++
来查看幕后情况:
Let's split the desktop and use Spy++
to see what's happening under the hood:
因此,如果我们查看天气"应用程序窗口,则无非就是"Internet Explorer_Server
"类的常规(Win32)窗口,该窗口位于"Web Platform Embedding
"类,该类又位于具有WS_EX_TOPMOST
和WS_EX_NOREDIRECTIONBITMAP
样式的"Windows.UI.Core.CoreWindow
"容器中:
So if we look into the "Weather" app window, it is nothing more than the regular (Win32) window of the class "Internet Explorer_Server
" that is housed in the window of the "Web Platform Embedding
" class, which in turn sits in the "Windows.UI.Core.CoreWindow
" container that has the WS_EX_TOPMOST
and WS_EX_NOREDIRECTIONBITMAP
styles on:
如果您看上去更深入,则所有Microsoft Metro的东西 似乎都是从 WWAHOST.exe
进程,简单来说就是为Metro应用程序运行JavaScript的容器.
If you look even deeper, all Microsoft's Metro stuff seems to run from the WWAHOST.exe
process, which in simple terms is the container to run JavaScript for the Metro apps.
现在,让我们看一下开始"屏幕本身.由于它完全覆盖了桌面,因此我们需要使用其他工具及其Shift键快照功能来获取它:
Now let's look into the Start Screen itself. Since it completely covers the desktop we need to use a different tool and its Shift key snapshot capability to get to it:
从中我们可以获取开始屏幕"的窗口句柄(在我的情况下为0x10158
)并在Spy ++中进行查找:
From it we can get the Start Screen's window handle (or 0x10158
in my case) and look it up in the Spy++:
从这两个工具都可以看到,开始"屏幕具有窗口类 DirectUIHWND
,被放置在ImmersiveLauncher
类的窗口中,该窗口具有WS_EX_TOPMOST
和WS_EX_NOREDIRECTIONBITMAP
样式,使其保持在顶部.这是 it 和桌面"应用创建的任何其他窗口之间的唯一区别.
As you can see from both tools, the Start Screen has window class DirectUIHWND
, that is housed inside a window of the ImmersiveLauncher
class, that is the one with the WS_EX_TOPMOST
and WS_EX_NOREDIRECTIONBITMAP
styles that make it remain on top. And that is the only difference between it and any other window created by a "desktop" app.
有趣的是在出现分割窗口的情况下如何呈现桌面"本身.我最初以为是在这种情况下,桌面只是移动(或移动)到一侧并调整大小,但是不是会发生什么……实际上(或在我的Windows 8.1中) Metro应用程序是台式机和Metro应用程序之间的一个分离部分,它只是覆盖了台式机,但是台式机本身不会更改其位置或大小.在这种情况下,仅任务栏和现有的桌面窗口会移动并调整其大小以适合拆分.可以通过以下图表说明:
What is also interesting is how the "desktop" itself is rendered in case of a split-window situation. I originally assumed that in this case the desktop is simply shifted (or moved) to one side and resized, but that is not what happens... In reality (or in my Windows 8.1) in case of a split between a desktop and a Metro app, the metro app simply covers over the desktop, but the desktop itself does not change its position or size. In that case, only the taskbar and the existing desktop windows are moved and resized to fit the split. This could be illustrated by this diagram:
请注意,这种移动和调整大小对于用户来说可能非常烦人,因为当拆分消失时,桌面窗口的原始位置和大小不会恢复.
As a side note, such moving and resizing can be quite annoying for a user, since original positions and sizes of the desktop windows are not restored when the split goes away.
最后,这是一个出乎意料的发现.我决定检查Google员工如何实现他们的Chrome浏览器(作为Metro应用程序运行),并发现了这一点:
And lastly, a somewhat unexpected finding. I decided to check how Google folks were able to implement their Chrome browser (running as a Metro app) and found this:
Chrome在Windows.UI.Core.CoreWindow
类窗口中呈现,属于Google自己的进程:"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
".因此,不做任何深入研究,显然可以将Metro风格的应用程序封装在非Microsoft容器中,这对于不关心AppStore XAML应用程序的开发人员来说是个好消息:)
Chrome renders in the Windows.UI.Core.CoreWindow
class window, belonging to the Google's own process: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
". So without going any deeper, it is evidently possible to encapsulate a Metro-style app in a non-Microsoft container, which is a good news for developers that don't care about AppStore XAML apps :)
编辑:忘记提及了,如果您打算从Metro应用程序顶部可见的Win32进程中显示自己的弹出消息,则需要执行以下操作:
Forgot to mention, if you plan to show your own popup message from a Win32 process that is visible on top of a Metro app, you need to do the following:
-
在过程清单中设置
UIAccess="true"
.您可以在Visual Studio中执行此操作,方法是转到Project Properties
->Linker
->Manifest Files
并将UAC Bypass UI Protection
设置为是". (请注意,您可以将UAC Execution Level
保留为asInvoker
,或者不需要提升您的流程.)
Set
UIAccess="true"
in the process manifest. You can do so in the Visual Studio by going toProject Properties
->Linker
->Manifest Files
and setUAC Bypass UI Protection
to YES. (Note that you can keepUAC Execution Level
asasInvoker
, or not to require elevation of your process.)
对您的过程进行代码签名.这很重要,因为没有签名将无法使用,并且您会看到以下错误消息:"从服务器返回了引用."
Code-sign your process. It is important, since without a signature it won't work, and you'll see this error message: "A referral was returned from the server."
签名(或出于开发系统测试目的)的一种替代方法,您可以设置以下注册表密钥设置为0.(我还没有尝试过,出于明显的安全考虑,我不推荐!但这似乎是另一种方法如果没有代码签名证书,请进行测试.)
An alternative to signing (or for testing purposes on your development system) you can set the following registry key to 0. (I haven't tried it though, and I wouldn't recommend it due to obvious security concerns! But it seems to be another way to test it if a code-signing certificate is not available.)
HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\ValidateAdminCodeSignatures
- 将编译后的可执行文件放置在
%windir%\System32
文件夹中,或更实际地放置在%ProgramFiles%\Company\Product
文件夹中,或者放置在产品安装位置的替代%ProgramFiles(X86)%\Company\Product
文件夹中. - Place the compiled executable file either into the
%windir%\System32
folder, or more realistically into the%ProgramFiles%\Company\Product
, or into the alternative%ProgramFiles(X86)%\Company\Product
folder for your product's installation location. - 然后,当您在弹出窗口中设置
WS_EX_TOPMOST
样式时,它将显示在任何其他窗口的上方,包括Metro应用程序,开始"屏幕等. - After that, when you set the
WS_EX_TOPMOST
style on your popup window, it will be displayed above any other windows, including the Metro apps, Start Screen, etc.
您还可以考虑阅读 Raymond Chen的文章关于此主题.
Also you may consider reading Raymond Chen's article about this topic.
换句话说,这样做:
//You may also consider setting the WS_EX_NOACTIVATE style
::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0 , 0, 0, SWP_NOMOVE | SWP_NOSIZE);
可以实现这一目标:
这篇关于Metro东西在哪个桌面上运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!