1

I'm using the following code to get a handle of the topmost window:

HWND hwnd;
hwnd = GetForegroundWindow();

The problem with this is that it returns the top most system-wide. Is there any way to get the topmost ONLY from my own application?

I want to get the top most window ONLY of my application. This means, that I need an API to get my own's app top most window and NOT the systemwide top most window as GetForegroundWindow() does. Thanks!

EDIT:

OK, let me be clear here. My problem is that I am able to get the HWND for a window that doesn't belong to MY application. What I want to get is the TOPMOST for ONLY my application. If the HWND belongs to another application then I should not get the information.

wonderer
  • 3,487
  • 11
  • 49
  • 59
  • 2
    I know this is a rather old question, nevertheless I feel obliged to add a reference to http://blogs.msdn.com/b/oldnewthing/archive/2008/10/06/8969399.aspx – Jim Brissom Sep 26 '10 at 12:59
  • However, notice the "active" part of `GetActiveWindow()`. For instance, if the user activated another app, `GetActiveWindow()` will return null. Same with `GetWindow(main_hwnd, GW_ENABLEDPOPUP)` and `GetGUIThreadInfo(thread_id, &info) -> info.hwndActive`. – Simpleton Nov 03 '20 at 11:19

3 Answers3

4

Here is a callback you can use with EnumWindows():

BOOL CALLBACK FindTopmostWnd(HWND hwnd, LPARAM lParam)
{
    HWND* pHwnd = (HWND*)lParam;

    HWND myParent = hwnd;
    do
    {
        myParent = GetParent(myParent);
    }
    while (myParent && (myParent != *pHwnd));

    if (myParent != 0)
    {
        // If the window is a menu_worker window then use it's parent
        TCHAR szClassName[7];
        while (0 != GetClassName(hwnd, szClassName, 7)
            && 0 != _tcsncmp(szClassName, TEXT("Dialog"), 6)
            && 0 != _tcsncmp(szClassName, TEXT("Afx"), 3)
            )
        {
            // find the worker's parent
            hwnd = GetParent(hwnd);
        }

        *pHwnd = hwnd;

        return FALSE;
    }

    return TRUE;
}

As Adam points out, the LPARAM passed to EnumWindows() should be a pointer to an HWND. So you probably want to do something like this:

HWND hTopmostWnd = hWnd;
EnumWindows(FindTopmostWnd, (LPARAM)&hTopmostWnd);
Jared
  • 1,305
  • 9
  • 13
  • 1
    You should also mention that the LPARAM passed to `EnumWindows()` should be a pointer to an HWND. – Adam Rosenfield Jul 13 '09 at 14:32
  • where are you getting the hWnd? – wonderer Jul 13 '09 at 14:49
  • I don't have one. my original code returns the hwnd that i need. Ok, this is getting beyond what i needed, I mean i posted 2 lines of code and now i need to start finding windows titles to get an hwnd to pass to a callback function to see if the hwnd is the topmost. While i do appreciate the help, there's gotta be an easy and shorter way to do this. – wonderer Jul 13 '09 at 16:37
  • Sorry, I didn't mean to be rude. It's just that it doesn't make sense to have to write such a long piece of code for something so trivial. – wonderer Jul 13 '09 at 16:52
  • OK, i wrote the whole code and still it didn't solve my problem. I am still able to get the window rec for a window that is not on my application. – wonderer Jul 13 '09 at 16:59
  • In the above EnumWindows() call the &hTopmostWnd parameter is an input/output parameter. You pass in an HWND from any window. After the call returns the parameter will be set to the HWND of the topmost window in the app associated with the input. If you pass in an HWND from someone else's app then you will get back the topmost window from that other app. It sounds like you are passing in an HWND that you got from GetForegroundWindow() which is not what you want. – Jared Jul 13 '09 at 18:26
  • OK, maybe I wasn't clean. That is exactly what i want to avoid. I want to get the top most window ONLY of my application. This means, that I need an API to get my own's app top most window and NOT the systemwide top most window as GetForegroundWindow() does. That is the whole problem. That is what i need to change and that is was I asked. – wonderer Jul 13 '09 at 18:50
  • Now there might be a way to use isChild() but I can't get it to work correctly. I think the problem begins with getting my own application HWND which is a pain to get. I tried GetForegroundWindow() and others (and no, i don't want to use Findwindow()). – wonderer Jul 13 '09 at 18:52
1

Use the GetTopWindow Function, like this:

HWND hwnd;
hwnd = GetTopWindow(NULL);
Nick Dandoulakis
  • 42,588
  • 16
  • 104
  • 136
  • "The GetTopWindow function examines the Z order of the child windows associated with the specified parent window and retrieves a handle to the child window at the top of the Z order." what if my application's main window is the one that is the topmost? – wonderer Jul 13 '09 at 14:06
  • With `NULL` as the parameter you'll get the top most window, even if it's the main window. Do you mean that you don't want the main window? – Nick Dandoulakis Jul 13 '09 at 14:12
  • GetTopWindow() gives me a handle to the item in the taskbar, not the handle to the window. when trying to get the window rect i'm getting only the taskbar button measurements – wonderer Jul 13 '09 at 14:13
  • I do want the main window, i was asking if the function would only take the child windows. In any case, it's behaving very strangely – wonderer Jul 13 '09 at 14:14
  • Passing **NULL** probably results in the search starting at the desktop and including windows of ALL apps. If you want to restrict the search to your app, use your main app window's hWnd instead of NULL. – Scott Smith Feb 01 '23 at 20:50
0

I don't know that there is a function that does exactly this, but you could probably write one yourself. If your application windows all have a particular window class, then you can use FindWindow or FindWindowEx.

Alternatively, you could use GetForegroundWindow to get the foreground window from all applications and then use GetWindowLong to check the HINSTANCE. If it's not from your application, then keep enumerating the windows by Z-order (using GetWindow) until you find the first one from your application.

Nick Meyer
  • 39,212
  • 14
  • 67
  • 75