Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4421
  • Last Modified:

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
0
cafechris
Asked:
cafechris
  • 7
  • 7
2 Solutions
 
cafechrisAuthor Commented:
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.
 
0
 
jkrCommented:
You could use the following code

HWND  g_hwnd;
int  g_nFound;

BOOL CALLBACK FindHwndFromPID( HWND hwnd, LPARAM lParam) :


HWND GetHwndFromPID ( DWORD dwProcessId)
{
 g_hwnd = NULL;
 g_nFound = 0;

 EnumWindows (  FindHwndFromPID,    ( LPARAM) dwProcessId));

 if ( g_hwnd)  // we found one...
      return ( g_hwnd);

 // nothing found :-(

 return (NULL);
}

BOOL CALLBACK FindHwndFromPID( HWND hwnd, LPARAM lParam)
{
    DWORD   dwPID2Find  =   ( DWORD) lParam;
    DWORD   dwPID       =   0;

    if  (   GetWindowThreadProcessId    (   hwnd,   &dwPID))
        {
            if  (   dwPID   ==  dwPID2Find)
                {
                    g_hwnd  =   hwnd;


                    return  (   FALSE);
                }
        }

    return  (   TRUE);
}

And call 'GetHwndFromPID()' like

HWND hwnd = GetHwndFromPID(GetCurrentProcessId());

which will retrieve the top-level window handle for your app.
0
 
cafechrisAuthor Commented:
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
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
wings_gauravCommented:
Hi Chris,

If this suits you -

call GetCurrentThreadId();
and then call EnumThreadWindows()

i.e.

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

HWND hWnd;
DWORD lThreadId = GetCurrentThreadId();
EnumThreadWindows(lThreadId, EnumThreadWndProc, &hWnd);

-wings
0
 
jkrCommented:
>>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());
0
 
cafechrisAuthor Commented:
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);
0
 
jkrCommented:
Err, how can you be sure that the main window runs in the same thread? ;o)
0
 
cafechrisAuthor Commented:
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
0
 
jkrCommented:
>>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.
0
 
cafechrisAuthor Commented:
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

0
 
jkrCommented:
>>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.
0
 
cafechrisAuthor Commented:
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
0
 
jkrCommented:
>>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.
0
 
cafechrisAuthor Commented:
raised from 250 to 300 for split
0
 
jkrCommented:
Thanks!
0

Featured Post

Become an Android App Developer

Ready to kick start your career in 2018? Learn how to build an Android app in January’s Course of the Month and open the door to new opportunities.

  • 7
  • 7
Tackle projects and never again get stuck behind a technical roadblock.
Join Now