Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
215 views
in Technique[技术] by (71.8m points)

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

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...