Link to home
Start Free TrialLog in
Avatar of chris rrr
chris rrrFlag for United States of America

asked on

Dll Get HWnd From HINSTANCE

How can my dll get the HWND of the calling app. (app doesn't give me any information)
I am NOT using MFC.

I need to get this in the DllMain(..)
I can call GetModuleHandle(NULL) to get the HINSTANCE, but then how would I get the HWND.

Thanks,

Chris
Avatar of chris rrr
chris rrr
Flag of United States of America image

ASKER

Currently I am using FindWindow(....).
I am hoping for a more sure way to get this. Especially since there may be multiple instances of the app opened.
 
ASKER CERTIFIED SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I saw this in another post you did, was hoping there was something more simple.
I will give it a shot if no-one has anything simpler.

Thanks,

Chris
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>was hoping there was something more simple.

No, that will all end up in something similar. But I don't see any complexity related to an one-liner like

HWND hwnd = GetHwndFromPID(GetCurrentProcessId());
I had to make a couple changes for this to work:

BOOL CALLBACK EnumThreadWndProc(HWND argHwnd, LPARAM lParam)
{
    *((HWND *)lParam = argHwnd;
    return FALSE;
}

HWND hMainWnd;
DWORD lThreadId = GetCurrentThreadId();
EnumThreadWindows(lThreadId, EnumThreadWndProc, (long)&hMainWnd);
Err, how can you be sure that the main window runs in the same thread? ;o)
One more little question.
Is it safe to get the hMainWnd only once.
Can the window handle change, or will is persist until window is closed, or recreated.
What circumstances could cause it to change if it can?

The reason I am asking this, is that when I use FindWindow, my dll works perfectly.
If I use either of these alternate methods, then the second time I call it I get a bug in my app. I don't think that it has anything to do with your example, I think it is how I am using the hMainWnd and MoveWindow. If I only call for the hwnd Once everything is OK. Don't worry about my code, that is not your problem, I am just wondering about the persistence of the hwnd.

Thanks,

Chris
>>Can the window handle change, or will is persist until window is closed, or recreated.

No, the window handle is valid and unique until the window it describes is destroyed. That you can be sure about.
The thread method does work for my situation, but I see what jkr is saying about the same thread not being the same as the app. This does sound like it could be a problem in some situations.

Sorry, when I said more simple, I was hoping for something like  MFC's afxGetMainWnd(?) or whatever it is. But the suggested methods works very well. Thanks jkr and wings. I will give it another day or two and then close the question.

Chris

>>when I said more simple, I was hoping for something like  MFC's afxGetMainWnd(?) or whatever it is

That works because the MFC framework stores the associated main window in a central place. A 'normal' Windows app doesn't, and that's why it is harder. BTW, my suggestion also works to find the top-level window of any process.
Never mind the couple of days...
I want to give you an "A" but I don't 100% understand what is happening in your supplied code jkr.
IF you could maybe give a simple explanation of how this works.

I havn't delt with processes yet, so I think this is what is causing me some confusion.
Is a process like in TaskManager(windows) where each instance of exe is a process. This is why the dll is still under the same process?

Here is what I am seeing so far.
You get the current DllprocID (since the dll is opened by the main app, they are run under the same process)

EnumWindows -
gets each window and passes dllProcID to the Callback.
This callback gets each windows procID (from its hwnd) and compares it to the dllProcID.
If they match then you have the current hWnd?

If this is correct then I get it, just want to make sure before I implement some code I " THINK " I understand. I don't like to copy/Paste because if there are problems... well , you know...

Chris
>>IF you could maybe give a simple explanation of how this works.

Sure, not a big deal. First, 'GetHwndFromPID()' calls 'EnumWindows()', which will call the supplied callback function 'FindHwndFromPID()' for each top-level window that exists on the system. This function is called with the handle of each window as the 1st parameter and the 2nd parameter that is supplied when 'EnumWindows()' is called, which is set to the Process ID that you want to get the HWND for by ''GetHwndFromPID()'. Given the enumerated window handle, 'FindHwndFromPID()' obtains the ID of the corresponding process using 'GetWindowThreadProcessId()' and compares it to the one passed in as the 2nd parameter. If they match, the window handle is stored in the global variable 'g_hwnd' and 'FindHwndFromPID()' returns FALSE, so teh enumeration stops. Now, 'GetHwndFromPID()' checks if a handle was found by examining 'g_hwnd' and returns that on success.
raised from 250 to 300 for split
Thanks!