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
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.
Also you may consider reading Raymond Chen's article about this topic.
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.
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.
Related
I have been working on an app in Visual Studio 2015 (C++). It's a kiosk app for my school's tech support. Basically, it's a support site that will run in a kiosk. I need to figure out how to lock windows so it only runs that program. It would also be helpful to run the program in fullscreen mode. Keep in mind that all of the kiosks run Windows 7.
Set registry key
HKCU SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
Shell="c:\path\to\whatever.exe"
Disallow task manager via security of taskmgr.exe (add a deny read + deny execute to the binary)
Set autologn:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
DefaultUserName = whatever
DefaultPassword = whatever
Have a boot disk handy. The only way to reverse this is to boot the boot disk and undo one of the steps after mounting the appropriate hive.
you can create your program with main window in full screen mode and popup:
hWnd = CreateWindowEx(WS_EX_CLIENTEDGE|WS_EX_APPWINDOW|WS_EX_TOPMOST,
lpClsName,
"MDI Project under Visual C++ WINAPI",
WS_BORDER|WS_POPUP,
...);// add the remaining parameters
and find taskmgr.exe and hide it and start menu button and hide them also:
hTaskBar = ::FindWindow ("Shell_TrayWnd", "");
hStart = ::FindWindowEx(GetDesktopWindow(), NULL, "Button", "Start");
ShowWindow(hTaskBar, SW_HIDE);
ShowWindow(hStart, SW_HIDE);
so your program looks like easycafe or handycafe
I actually switched from C++ to C#, so I'm gonna explain my answer with C#.
I used a keyboard hook library to capture keyboard input and block all non-letter/number input so alt-f4, alt-tab etc. would not work. I then determined a closing sequence of characters using another keyboard hook (LWin+C+Home+F12+PrtSc).
As for Ctrl-Alt-Del, that cannot be disabled (as far as I know) because it is a system function, so I just left that as it is.
I also got the bounds of the screen and set the size of the window to the maximum screen size at application launch, as well as whenever the app is resized or moved. This essentially makes it so the app covers the task bar, and the bar with the close and minimize buttons is also covered, but if someone found a way to move it it would immediately go back to it's full size.
I also set up autologin as was detailed in a previous answer, but I just didn't do it through code.
If my window has the 'always on top' extended style set, I would expect it to be on top of all windows that do not have the 'Always on top' style set and those windows that have the 'Always on top' style set but were activated before my window was activated.
To test this feature, I open the task manager window - set it to always on top and then I open my window (myWindow).
In Windows 7, I observe the expected behaviour - myWindow comes on top of the task manager.
However, in Windows 10, that's not the case. The task manager is 'always on top' of other windows, even if those windows in themselves have the 'always on top' style set.
Is there something special that they are doing with the task manager in Windows 10? If yes, is there some work around for bringing my window on top of the task manager? I have tried simply using the BringWindowToTop function, but that doesn't work. Neither does setWindowPos with HWND_TOP as a value for hWndInsertAfter argument.
From a small research that I did a while ago:
The Task Manager is indeed a "special kind" of Always-on-Top.
The Task Manager window is being created with the following undocumented function: CreateWindowInBand.
Trying to use this function from another process results in ERROR_ACCESS_DENIED. Perhaps only a signed Microsoft process can use it.
2020 update:
A detailed writeup about the functionality was published here:
Window z-order in Windows 10
There were lots of changes made to the Task Manager in Windows 8. It would not be at all surprising that among those changes was special-case code to ensure it was always on top of all other always-on-top windows. Microsoft would not be breaking any contractual guarantees by doing so, since the Task Manager is a built-in part of the operating system. It is free to do as it likes with OS components.
To answer your actual question, there is no documented API for this. WS_EX_TOPMOST is the best you get. It's meant as an aid for the user, not a way to etch your app's window in their retinas.
When two different windows have this style set, the behavior is implementation-dependent. The only guarantee that you get is windows with the WS_EX_TOPMOST style are always on top of other windows without this style in the Z order. The system is otherwise free to resolve conflicts as it sees fit, including keeping the most recently-active topmost window on top, breaking the tie by forcing windows belonging to system components to the top, or even punishing processes that have more than one window with this style by forcing their window(s) to the bottom of the "topmost" stack.
Related reading:
What if two programs did this?
What if two programs did this? Practical exam
How do I create a topmost window that is never covered by other topmost windows?
In linux and when installing packages etc. There are some installers that have a progress bar and a dos window which shows the files being extracted etc. How can i add this window to my C++ Win32 programs so that i can have it showing the tasks im doing? I cannot find any documentation on MSDN.
Question: How can i add a console window (if that's what its called, sure looks like one) in my program to show the details of the task at hand being done?
Here is a window with what i am asking.. (personal info so I erased the details. :]
You cannot embed a real console window inside another window (although a windowed process can have a separate console window). While it looks like a console window / command prompt, it is just a matter of appearances. What you want to do is create a sub-window/control with similar characteristics as a console window and then redirect the console output from the application(s) being run to append to that sub-window. For more information on how to do redirect the console output in Windows, see http://support.microsoft.com/kb/190351.
That "dos window" is a regular edit control: CreateWindow(ES_MULTILINE, EDIT, ...
However, it has the font set to a fixed-width one (Looks like courier). This is done by sending WM_SETFONT to the edit control.
#user995048 says "You cannot embed a real console window inside another window". But "cannot" is a strong word! I can run an entire virtualized computer in a window if I wish. :) So one can quite reasonably intuit that there are ways of doing what you say.
Sure, it is true that what you've seen are almost certainly cases of output redirection into a custom widget, designed to mimic the simple appearance of a terminal. However...if you want to embed one application's window inside another, there are things you can look into which might fit. Cooperative methods exist like GtkPlug, for instance:
http://developer.gnome.org/gtk/2.24/GtkPlug.html
To actually capture a not-designed-to-cooperate app's window and throw it in your app would be trickier. But possible, just as screen captures and virtual machines are possible. Probably best to avoid that sort of thing unless there's really a cause for it, though...
Try this
http://www.codeguru.com/cpp/misc/misc/article.php/c277/
link. I think the solution provided is what you need.
I tried it many years ago and it worked. I have not tried it in newer versions of windows though.
I always wondered how software such as iTunes, Winamp etc is able to create its own UI.
How is this accomplished under the Windows platform? Is there any code on the web explaining how one would create their own custom GUI?
WinAmp doesn't usually supply its own GUI at all -- it delegates that to a "skin". You can download dozens of examples and unless memory fails me particularly badly, documentation is pretty easily available as well.
From the looks of things, I'd guess iTunes uses some sort of translation layer to let what's basically written as a native Mac UI run on Windows (the same kind of thing that Apple recently decided was so evil that they're now forbidden on the iPhone and apparently the iPad).
Since saying anything that could possibly be construed as negative about Apple is often treated as heresy, I'll point to all the .xib files that are included with iTunes for Windows. An .XIB file (at least normally) is produced by Apple's Interface Builder to hold resources for OS/X programs, and compiled to a .NIB file prior to deployment. Windows doesn't normally use either .XIB or .NIB files at all, and it appears likely to me that Apple includes a compatibility layer to use them on Windows (though I've never spent any time looking to figure out what file it's stored in or anything like that).
Edit: (response to Mattias's latest comment). Rendering it is tedious but fairly straightforward. You basically take the input from the skin (for example) and create an owner draw control (e.g. a button) and render the button based on that input.
The easiest way to do this is to have fixed positions for your controls, and require the user to draw/include bitmaps for the background and controls. In this case, you just load the background bitmap and display it covering the entire client area of your application (and you'll probably use a borderless window, so that's all that shows). You'll specify all your controls as owner-drawn, and for each you'll load their bitmap and blit it to the screen for that control. Since there won't (usually) be a visible title bar, you'll often need to handle WM_NCHITTEST (or equivalent on other systems) to let the user drag the window around.
If you want to get a bit more complex, you can add things like allowing them to also specify a size and position for each control, as well as possibly specifying that some controls won't show up at all. Again, this isn't really terribly difficult to manage -- under Windows, for example, most controls are windows, and you can specify a size and position when you create a window. If the user loads a different skin at run-time, you can call MoveWindow to move/resize each control as needed.
I'm assuming that you mean creating a GUI application as opposed to a GUI framework.
There are lots of GUI frameworks available for Windows.
Some are
wxWidgets (www.wxwidgets.org)
Qt (http://qt.nokia.com/products)
And of course the venerable MFC framework (http://msdn.microsoft.com/en-us/library/d06h2x6e%28VS.90%29.aspx)
If you want a more complete list, look at the Wikipedia article for MFC (http://msdn.microsoft.com/en-us/library/d06h2x6e%28VS.90%29.aspx) and scroll to the bottom.
Each of these GUI frameworks is amply documented on the web.
The Windows API provides an API GetDesktopWindow( ) which returns the window handle
But I tested with Spy++ and I find that the window handle of the desktop and the window handle of the "Windows Desktop" is not the same.
As the "Windows Desktop" is a list view, do I need to do the following
1) HANDLE hWnd = GetDesktopWindow() ;
2) FindWindow(hWnd, ..... ) with the SyslistView32 as the Window class.
Once I get the Window handle, I want to use SendMessage() for operations like getting selected file name, the number of files selected , etc.
Please give your opinions. I am doing this using the Windows SDk
In light of a recent discussion on Meta complaining that questions like this one have "not been properly answered", I'm going to try and give answering this one a whirl. Not to imply that I think meklarian's answer is bad—in fact, far from it. But it's clearly been deemed unsatisfactory, so perhaps I can fill in some of the additional details.
Your problem results from a fairly widespread confusion over what the desktop window actually is. The GetDesktopWindow function does precisely what it's documented to do: it returns a handle to the desktop window. This, however, is not the same window that contains the desktop icons. That's a completely different window that appeared for the first time in Windows 95. It's actually a ListView control set to the "Large Icons" view, with the actual desktop window as its parent.
Raymond Chen, a developer on the Windows Shell team provides some additional detail in the following Windows Confidential article: Leftovers from Windows 3.0
[ . . . ] While in Windows 3.0, icons on the desktop represented minimized windows, in Windows 95, the desktop acted as an icon container.
The Windows 95 desktop was actually a window created by Explorer that covered your screen (but sat beneath all the other windows on your desktop). That was the window that displayed your icons. There was still a window manager desktop window beneath that (the window you get if you call GetDesktopWindow), but you never saw it because it was covered by the Windows 95 desktop—the same way that the wood paneling in the basement of my colleague’s house covered the original wall and the time capsule behind the wall.
[ . . . ]
This desktop design has remained largely unchanged since its introduction in Windows 95. On a typical machine, the original desktop is still there, but it’s completely covered by the Explorer desktop.
In summary, then, the window returned by the GetDesktopWindow function is the actual desktop window, the only one we had way back in Windows 3.0. The Explorer desktop (the one that contains all your icons) is merely another window sitting on top of the desktop window (although one that completely covers the original) that wasn't added until Windows 95.
If you want to get a handle to the Explorer desktop window, you need to do some additional work beyond simply calling the GetDesktopWindow function. In particular, you need to traverse the child windows of the actual desktop window to find the one that Explorer uses to display icons. Do this by calling the FindWindowEx function to get each window in the hierarchy until you get to the one that you want. It has a class name of SysListView32. You'll also probably want to use the GetShellWindow function, which returns a handle to the Shell's desktop window, to help get you started.
The code might look like this (warning: this code is untested, and I don't recommend using it anyway!):
HWND hShellWnd = GetShellWindow();
HWND hDefView = FindWindowEx(hShellWnd, NULL, _T("SHELLDLL_DefView"), NULL);
HWND folderView = FindWindowEx(hDefView, NULL, _T("SysListView32"), NULL);
return folderView;
I noted there that I don't actually recommend using that code. Why not? Because in almost every case that you want to get a handle to the desktop window (either the actual desktop window, or the Explorer desktop), you're doing something wrong.
This isn't how you're supposed to interact with the desktop window. In fact, you're not really supposed to interact with it at all! Remember how you learned when you were a child that you're not supposed to play with things that belong to other people without their permission? Well, the desktop belongs to Windows (more specifically, to the Shell), and it hasn't given you permission to play with its toys! And like any good child, the Shell is subject to throwing a fit when you try to play with its toys without asking.
The same Raymond Chen has published another article on his blog that details a very specific case, entitled What's so special about the desktop window?
Beyond the example he gives, this is fundamentally not the way to do UI automation. It's simply too fragile, too problematic, and too subject to breaking on future versions of Windows. Instead, define what it is that you're actually trying to accomplish, and then search for the function that enables you to do that.
If such a function does not exist, the lesson to be learned is not that Microsoft simply wants to make life harder for developers. But rather that you aren't supposed to be doing that in the first place.
If you want the Desktop window as defined in GetDesktopWindow(), use that window handle. This is the window handle you should use to look for top-level windows and other related activities.
What you're seeing in Spy++ is just the content drawn as the desktop in your session. If you use the auto-locate in Spy++, you'll see that the SysListView32-declared window is a child window of your explorer shell. It is quite infrequent for someone to need access to this window. Also, the existence of this window may be subject to changes between versions of windows.
Edit (additional info)
If you are looking to interact or place things on the actual shell desktop, you may be better served by other APIs. Here are two such APIs that can accomplish this, depending on the target version of windows.
Windows Sidebar # MSDN
This is available on Vista and Windows 7
Using the Active Desktop # MSDN
This is available on Windows 2000 and XP, although frequently disabled by users and sysadmins.