HWND of desktop

I'm running Windows 7 and I want my program to detect when the desktop is in focus, including when I press the desktop key (minimize all windows and show desktop).

I used:

 
if(GetForegroundWindow() == GetShellWindow())


This works only when another window is in focus and I click on the desktop (GetForegroundWindow() returned (int)524654).

When I click the desktop button, however, it doesn't work. I figured this would be the same as:

 
if(GetForegroundWindow() == NULL)


..but that's apparently not the case. After pressing the desktop button the function returns (int)328192.

I can't just use these values because they change. Is there a function that returns what GetForegroundWindow() returns after the desktop button is pressed?

When you click "the desktop button" it makes the desktop visible but focus stays on the start bar. The start bar and desktop are two different things.

EDIT: @ below: I don't know, but I bet @andywestken does.
Last edited on
Ah, I wasn't aware the taskbar could be in focus. I was, however, well aware that they're two different things, thanks. Mind if I ask how you check if focus is set to the taskbar, then?

EDIT:

Ok I tried:

 
if(GetForegroundWindow() == FindWindow("Shell_TrayWnd", NULL))


After pressing the button focus only stays on the taskbar momentarily (GetForegroundWindow() returns a third value) then changes to the second value I mentioned in my original post.
Last edited on
It might be finding the "Start" button.

My Windows 7 (ASUS Eee) and Windows 8 (ASUS X502C!) PCs both have helper apps running on the desktop, so they're what get focus if nothing else is about and I haven't click on the actual desktop. ("Eee Docking" in the first instance; Asus Instant on Config in the latter.)

But when I kill the helper apps it's the Systray (class "Shell_TrayWnd") that gets focus in the Windows 8 case (I haven't installed the optional Start button) but the "Start" button (class "Button) for Windows 7.

Andy

PS Basic program I used to monitor what was going on.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <iostream>
using namespace std;

int main()
{
    HWND hwndShell   = GetShellWindow();
    HWND hwndDesktop = GetDesktopWindow();

    // Systray is child of desktop
    HWND hwndTray = FindWindowEx(hwndDesktop,
                                 NULL,  // start looking from first child
                                 "Shell_TrayWnd",
                                 NULL); // don't care about window title

    // Start button is child of systray (if Windows 8, prob missing)
    HWND hwndStart = FindWindowEx(hwndTray,
                                  NULL,    // start looking from first child
                                 "Button",
                                 "start"); // don't care about window title

    HWND hwndCurr = NULL;

    do
    {
        HWND hwndNow = GetForegroundWindow();

        if(hwndNow != hwndCurr)
        {
            hwndCurr = hwndNow;

            const size_t buffSize = 256;
            char windowClass[buffSize] = "";
            char windowName [buffSize] = "";
            GetClassNameA (hwndCurr, windowClass, buffSize);
            GetWindowTextA(hwndCurr, windowName , buffSize);

            cout << "hwnd  = " << hwndCurr << endl
                 << "class = " << windowClass;
            if(hwndCurr == hwndShell)
                cout << " [SHELL]";
            else if(hwndCurr == hwndDesktop)
                cout << " [DESKTOP]";
            else if(hwndCurr == hwndTray)
                cout << " [SYSTRAY]";
            else if((NULL != hwndStart) && (hwndCurr == hwndStart))
                cout << " [START BUTTON]";
            cout << endl
                 << "name  = " << windowName  << endl
                 << endl;
        }

        if(NULL == hwndCurr)
        {
            cout << "NULL window handle??? Bailing out!" << endl;
        }
        else
        {
            Sleep(1000);
        }
    }
    while(NULL != hwndCurr);

    return 0;
}
Last edited on
PS If you're interested you can check out the window hierarchy using one of the available tools, e.g.

Spy++, provided with retail versions of Visual Studio, but not the Express versions.

Introducing Spy++
http://msdn.microsoft.com/en-us/library/dd460756.aspx

Inspect, the new Windows SDK tool (the version of this tool in Windows SDK 7.0 looks a bit complete to me?)

Inspect
http://msdn.microsoft.com/en-us/library/dd318521.aspx

UISpy, and olded Windows SDK tool, provided in Windows SDK up to version 7.0, but now superseded by Inspect.

UISpy.exe (UI Spy)
http://msdn.microsoft.com/en-us/library/ms727247.aspx

Window Detective, an open source alternative (I haven't tried it as I have Spy++ and UISpy to hand.)

Window Detective
http://sourceforge.net/projects/windowdetective/

Andy

Microsoft Spy++ Alternatives and Similar Software
http://alternativeto.net/software/spy--/
Last edited on
Thanks Andy. I used your program and it came in handy; it turns out the start button wasn't the culprit. I'll be able to do what I need by checking when the foreground hwnd's classname is "WorkerW" - the Windows 7 version of progman (program manager for the shell). I guess the taskbar/start button are child classes of the program manager.. I'm going to download Spy++ to see what's going on here.

Much obliged ^^
Curious; my Windows 7 PC (32-bit) shows name = "Program Manager", class = "Progman" for the shell window.

According to Inspect, the hierarchy is:

"Desktop" (#32769)
-- <no name>  (Shell_TrayWnd)
-- -- "Start" (Button)
-- -- (etc)
-- (etc : inc. all app's main windows)
-- "Program Manager" (Progman)
-- -- SHELLDLL_DefView
-- -- -- SysListView3 (i.e. a List-View control)
-- -- -- -- (desktop icons)


Edit: have you got wallpaper enabled on your PC? If so, see linked stackoverflow.com post for more info.

When there is set the wallpaper mode to slideshow, you have to search for a window of class WorkerW and check the children, whether there is a SHELLDLL_DefView. If there is no slideshow, you can use the good old GetShellWindow().

Get handle to desktop / shell window
http://stackoverflow.com/questions/8364758/get-handle-to-desktop-shell-window

Andy
Last edited on
Topic archived. No new replies allowed.