Just curious, from a standpoint of WinAPI developer, what desktop do Metro apps run in?
This stuff:
I didn't know that it would be such a secret... so I had to do some investigating and here's what I found:
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!
Here's a couple of examples:
Let's split the desktop and use Spy++
to see what's happening under the hood:
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:
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.
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:
From it we can get the Start Screen's window handle (or 0x10158
in my case) and look it up in the Spy++:
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.
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.
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 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 :)
EDIT: 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:
Set UIAccess="true"
in the process manifest. You can do so in the Visual Studio by going to Project Properties
-> Linker
-> Manifest Files
and set UAC Bypass UI Protection
to YES. (Note that you can keep UAC Execution Level
as asInvoker
, 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."
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
folder, or more realistically into the %ProgramFiles%\Company\Product
, or into the alternative %ProgramFiles(X86)%\Company\Product
folder for your product's installation location.Also you may consider reading Raymond Chen's article about this topic.
WS_EX_TOPMOST
style on your popup window, it will be displayed above any other windows, including the Metro apps, Start Screen, etc.So in other words, doing this:
//You may also consider setting the WS_EX_NOACTIVATE style
::SetWindowPos(hWnd, HWND_TOPMOST, 0, 0 , 0, 0, SWP_NOMOVE | SWP_NOSIZE);
Can achieve this:
Since you say that your actual issue is knowing whether a Metro app is running, the answer is to call IAppVisibility::GetAppVisibilityOnMonitor
. Pass the monitor you want to check. Note that this will give the correct answer regardless of what desktop the applications run in.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With