How do I get the window handle of the desktop? - c++

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 Get­Desktop­Window), 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.

Related

Is Task Manager a special kind of 'Always on Top' window for windows 10?

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?

Does the Win32 ShowWindow api behave differently on Windows 7 SP1 in some special case?

I found a bug yesterday in one of my Windows applications, which is built in a high level framework, which in the end, calls Windows APIs like CreateWindow, and ShowWindow, in order to display its user interface.
One one machine so far, and only one, which happened to be a customer machine, I observed the following behaviour:
For only one window in my entire application, when I first call ShowWindow(Handle,SW_SHOW ) for this window, the size which it previously had received by SetWindowPos is overridden.
Reading the MSDN Win32 API documentation, on ShowWindow(Handle,SW_SHOW) I can not see any reference it it moving the window bounds. I can work around this surprising result by having my window-show routine get the bounds before it calls the Win32 ShowWindow routine.
My question is, has anyone ever seen behaviour like this? I think it must be one of the following:
An obscure bug in Windows 7 Service Pack 1 that does not reproduce on all systems, and only reproduces perhaps for a particular version of a particular video card driver. (This affected system has dual AMD/ATI FireGL video cards)
An obscure problem caused by a side effect of some other software running on the system, which may be hooking window handles, installing trampolined code hooks somewhere (perhaps even inside my own process, thanks to some DLL or something that I am not aware of).
Something my 4 million line application is doing to me, through some weird code somewhere I have not yet identified.
I am hitting an application compatibility shim within the Win32 API layer.
If anyone who has worked in C++, C, or Delphi, or any other language, has ever seen anything like this and can think of a reason why ShowWindow would have this amazing and unexpected side effect, of moving the bounds of the window, back to a certain original position, in my case, x=175, y=175, width=320, height=240, which appears to be have been the window bounds right after the initial CreateWindow call, I'd like to know what it is.
Here is a sequence of events:
Application starts up, and creates a few top level windows parented to the desktop.
The first window created is the main application window and the second is a tool window, both have full window grabber bars and are conventional top level Win32 windows, Forms which are sizeable, draggable, and parented to the desktop.
The second window's position is loaded from disk, and the form is shown.
During the form show process, its bounds are set so that the window is at some x and y top/left position, and some height/width is given.
If I query the Win32 window handle immediately before I call ShowWindow, its bounds are where I expect.
If I query the Win32 window handle immediately after I call ShowWindow, its bounds have been reset.
According to MSDN help SW_SHOW means Activates the window and displays it in its current size and position.
This is indeed what occurs on over 100 client PCs I have observed. Only on a single customer-owned Windows 7 PC is this behaviour different.
This affected system has dual AMD/ATI FireGL video cards
I ain't sure about FireGL, but for consumers videocards, made upon the same chip lineage, video-drivers exactly have add-on to reposition windows as they think is easier for operator.
it is called HydraVision Package for Catalyst Software Suite

Drawing on top of a window of a third party application

Here is a description of my use case:
I have a Windows application that comprised of the main window and it also creates child windows (think of MS Word for instance). What i want to do is draw frames around certain children windows of a given application. Note that when i say window i mean any visible HWND (handle) in the system. This could be a certain window in Excel, or an open pdf document in Abode reader or whatever.
My question is:
Can this be implemented as AN independent API where one would for instance be able to call the following ?
DrawOutline(HWND, OutlineColor, Thikness);
Any pointers as to how to approach this ? Any limitations one might think of? This would not be a plugin to a specific application but a stand alone API. MFC is also OK. Thanx
The Spy++ tool draws frames around any window. Source code for several Spy++ versions is available on the net.

What desktop does Metro stuff run in?

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.

How to know the name/ID of window in focus

How to know the name/ID of window in focus specifically in OpenCV.
Is there any event handling/callback or windows api that make this possible if it is not possible with OpenCV.
I am working on Windows 7 and 8.1.
I want to do something similar to (but not limited to):
If a window is in focus, and some event like mouse or key press happens,
then update that particular window
.
As suggested by Kris, there exists a solution on window. Use windows api to take handle of active window as using:
HWND WINAPI GetActiveWindow(void);
Now use GetWindowText() function to extract out title, if any. It may not be portable. There should exist similar api for other OS.
first of all, I don't know if windows or any other api can help.
I have an idea to take screen-shot, somehow, and then use opencv itself for image processing. Assumption is that the focused window will be on the top and most focused so we can see the name easily. We can process color to separate focused window from others, if any. And using OCR to extract windows name.