getting the HWND for my own application in C
Asked Answered
L

8

6

since I couldn't find an answer to this question I researched a bit further into the MSDN and I found isChild(). It might give me the answer to that other question.

Now, in order to use isChild() I need to pass the HWND of the parent application that I want to check, in this case my own application. How do I get the HWND of my own application?

I don't know the title since it changes constantly so I can't use FindWindow().

Thanks

Edit:

Since it's not clear, I'll add more information: I am not creating a window. I don't have access to the creation of a window. My code is a piece of code that gets compiled together with whatever application the other programmer is coding and I have no access to how the window is created, the title or any other information. So, how do I get the HWND to the "WINDOW" of the application I am running?

Leith answered 14/7, 2009 at 13:56 Comment(0)
F
6

Use GetTopWindow() and GetNextWindow() to walk through windows z-order.

However, don't think it is necessary, but you can use GetCurrentProcessId() and GetWindowThreadProcessId(), may be something like following will help you:

HWND FindMyTopMostWindow()
{
    DWORD dwProcID = GetCurrentProcessId();
    HWND hWnd = GetTopWindow(GetDesktopWindow());
    while(hWnd)
    {
        DWORD dwWndProcID = 0;
        GetWindowThreadProcessId(hWnd, &dwWndProcID);
        if(dwWndProcID == dwProcID)
            return hWnd;            
        hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
    }
    return NULL;
 }
Firstly answered 14/7, 2009 at 14:6 Comment(5)
GetTopWindow() always returns 0. The same with GetActiveWindow()Leith
Thanks for the replay, but GetTopWindow() if called with NULL might return the top window of another program (as I found out on the previous question) and I as I stated in that question and in this one I am looking for information about my own application and window.Leith
So you find topmost window -- then iterates through the windows in z-order using GetNextWindow and compares each window with yours. First that matched is what you need. I thought it can be done so...Firstly
You compare GetCurrentProcessId() with id returned GetWindowThreadProcessId() if it matched -- it'sj your process window.Firstly
I don't see how. Is there any chance you can show me? Thanks.Leith
A
9

Your application doesn't have a HWND. The window does. An application may have no windows or it may have many, so there is no general function to "Get the application's HWND".

The obvious solution is just to hold on to the handle when you get it. When you create the window, a HWND is returned. Store that.

Australorp answered 14/7, 2009 at 14:3 Comment(0)
F
6

Use GetTopWindow() and GetNextWindow() to walk through windows z-order.

However, don't think it is necessary, but you can use GetCurrentProcessId() and GetWindowThreadProcessId(), may be something like following will help you:

HWND FindMyTopMostWindow()
{
    DWORD dwProcID = GetCurrentProcessId();
    HWND hWnd = GetTopWindow(GetDesktopWindow());
    while(hWnd)
    {
        DWORD dwWndProcID = 0;
        GetWindowThreadProcessId(hWnd, &dwWndProcID);
        if(dwWndProcID == dwProcID)
            return hWnd;            
        hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
    }
    return NULL;
 }
Firstly answered 14/7, 2009 at 14:6 Comment(5)
GetTopWindow() always returns 0. The same with GetActiveWindow()Leith
Thanks for the replay, but GetTopWindow() if called with NULL might return the top window of another program (as I found out on the previous question) and I as I stated in that question and in this one I am looking for information about my own application and window.Leith
So you find topmost window -- then iterates through the windows in z-order using GetNextWindow and compares each window with yours. First that matched is what you need. I thought it can be done so...Firstly
You compare GetCurrentProcessId() with id returned GetWindowThreadProcessId() if it matched -- it'sj your process window.Firstly
I don't see how. Is there any chance you can show me? Thanks.Leith
D
1

Can't you just hold onto the handle returned from CreateWindow? If not, why not?

Debacle answered 14/7, 2009 at 13:57 Comment(7)
because i am not creating a window. My my is a module that gets compiled with someone else's code. Hence I don't have access to the creation of the window. Now, knowing that, how do I get the HWND for the window of the application where I am running?Leith
So you don't even have access to the window's message pump I assume? Then the only thing i can think of is to EnumWindows and then call GetWindowLong using the GWL_HINSTANCE parameter and compare the HINSTANCE returned to the one returned from GetModuleHandle.Debacle
It is worth noting you'll get back EVERY HWND associated with your HINSTANCE though ...Debacle
I've been trying this approach but for something so trivial is giving me a headache...Leith
Well it would certainly be easier all round to put a request through to the person writing the windowing system to add a "GetHWND()" function ...Debacle
console app i.e. a "hello world" does not create its own window thus the window is either DOS or Powershell that runs the hello.exe , so how does the hello.c get the DOS or powershell's hWnd is a question.Gallion
GetConsoleWindow() gets the hWnd of the console app itself, if someone wants to know.Gallion
H
1

As others have already pointed out

  • In general, an application can have zero or multiple top-level windows.
  • If you're creating the window yourself you can just remember the HWND somewhere.

But maybe your code is in a DLL, so you didn't actually create the top-level window yourself. So what to do?

I would suggest the following:

  • Use EnumWindows to enumerate all top-level windows.
  • Use GetWindowLongPtr to get the HINSTANCE for each top-level window. Compare this against the HINSTANCE of the application, which you can get using GetModuleHandle(NULL). If they're identical, you've found your main window.

Edit: Here is some code. Turns out you also have to use IsWindowVisible because there seem to be quite a few invisible "helper" windows.

HWND hwndMain;

BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM lParam)
{
    HINSTANCE hinst=(HINSTANCE)GetModuleHandle(NULL);

    if((HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE)==hinst &&
        IsWindowVisible(hwnd))
    {
        hwndMain=hwnd;
        return FALSE;
    }
    else
        return TRUE;
}

Then in the place you want to find the window:

hwndMain=NULL;
EnumWindows(EnumWindowProc, 0);

And after this, hwndMain should contain the handle of the window, or NULL if none exists.

Using EnumWindows is a bit burdensome but is recommended over calling GetWindow in a loop because, as MSDN notes: "An application that calls GetWindow to perform this task risks being caught in an infinite loop or referencing a handle to a window that has been destroyed."

Haploid answered 14/7, 2009 at 14:20 Comment(1)
Thanks. That looks like a lot of code to get something so simple. Do you have an sample?Leith
S
1

Presumably your code gets called by main application code, otherwise what use is it? In which case I acnnot see why your code's API cannot include some way of informing you of the handle of the application's main window.

Saturate answered 14/7, 2009 at 15:4 Comment(2)
Because is not in the design paper. That's all.Leith
My thoughts exactly. This is all that is necessary.Waldenburg
B
1

You can inject a DLL in a thread who appeal user32.dll http://msdn.microsoft.com/en-us/library/ms821625.aspx

Beechnut answered 31/7, 2009 at 16:21 Comment(0)
W
0

This is old for me, but IIRC you should receive the HWND as a parameter in the window proc. You can save it in a global variable somewhere in the beginning.

Wholesome answered 14/7, 2009 at 13:59 Comment(1)
Actually rather than storing it as a global, you can pass it, or a pointer to another structure as the last parameter of the CreateWindowEX. That pointer will then be available to the Windows procedure during the WM_CREATE message.Philology
S
0

What about your windows class name? Is it always different on window creation? If not you could still you FindWindow().

Stretcherbearer answered 14/7, 2009 at 14:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.