-1

I am wondering how i can get the correct HWND from the process my DLL is injected into. I made the code bellow myself and are wondering how and if i can improve it so it does the same think as if i used the FindWindow function like this FindWindow(0, L"calculator"). I am doing this because i didn't want to compare with name using FindWindow function, and becouse i want to learn.

HWND CorrectHWND = NULL;
BOOL CALLBACK HWND_Callback(HWND hwnd, LPARAM lParam)
{
    if (CorrectHWND == NULL)
    {
        DWORD HWND_Process_ID;
        GetWindowThreadProcessId(hwnd, &HWND_Process_ID);
        if (GetCurrentProcessId() == HWND_Process_ID)
        {
            CorrectHWND = hwnd;
            return false;
        }
    }
    else
    {
        return false;
    }
    return true;
}

HWND Get_HWND()
{
    EnumWindows(HWND_Callback, 0);
    return CorrectHWND;
}
gofmode
  • 21
  • 4
  • 1
    BTW, instead of using a global variable, you can pass its address to `EnumWindows` and then access it via `*((HWND*)lParam)`. – Evg Aug 18 '18 at 16:57
  • So inside the callback function it is going to be `DWORD HWND_Process_ID; GetWindowThreadProcessId(hwnd, &HWND_Process_ID); if (GetCurrentProcessId() == HWND_Process_ID) { *((HWND*)lParam) = hwnd; return false; }` and in the Get_HWND function it is going to be something like `LPARAM HWND_address = NULL; EnumWindows(HWND_Callback, HWND_address); return *((HWND*)HWND_address);` at least that dident work for me i proble messed up in the last part @Evgeny –  gofmode Aug 18 '18 at 17:17
  • 1
    `lParam` should be a pointer to `CorrectHWND`, not its value. – Evg Aug 18 '18 at 17:19
  • `{ HWND CorrectHWND = 0; EnumWindows(HWND_Callback, reinterpret_cast(&CorrectHWND)); return CorrectHWND; }`, then `*reinterpret_cast(lParam) = hwnd`. – Evg Aug 18 '18 at 17:22
  • hmm, it looks like it return the wrong HWND sometimes. Isent GetCurrentProcessId getting the id from the window that my dll is injected into? @Evgeny –  gofmode Aug 18 '18 at 18:00
  • Sorry, I don't have an answer to your question. In my view `FindWindow` and what you're doing are different things, and I don't fully understand what you want to achieve. I suggest you expand your question with more details about your final goal. Now it's hard to give a meaningful answer. Try to enumerate all the windows matching your criteria into, e.g., `std::vector`, and then check (manually) what these windows are using Spy++. Probably this will help you to understand why sometimes you get not what you expect. – Evg Aug 18 '18 at 18:10
  • 2
    It's unclear, what you are trying to accomplish. We cannot help you improve the code without knowing, what it is meant to do. You will have to update your question to include that information. – IInspectable Aug 18 '18 at 18:15
  • I am just trying to get the HWND from the current process. (Meaning that i want to get the HWND from the window the dll is injected into). Thank you for answering @Evgeny You cleared up some stuff for me regarding the LPARAM lParam and showed me some tricks that i now i ame going to get use of <3 I think your answer is pointing in the right derection do :) –  gofmode Aug 18 '18 at 18:36
  • 1
    There can be several windows associated with a process and a thread. You should decide which one you need. – Evg Aug 18 '18 at 18:48
  • ahh, ok I think i come up with a soulution using see if visibal. Maby that is going to works. Going to test now. –  gofmode Aug 18 '18 at 18:56
  • 1
    There is no such concept as a *"main window"*. Any process can have 1 or more threads, and any thread can have 0 or more top-level windows. You will have to decide, which window you need. Once you write a formal specification, the code to implement the predicate will be trivially easy to write. But we cannot help you with that as we don't know, what you need. – IInspectable Aug 18 '18 at 18:58
  • ok, so let say i want the calculator.exe HWND. I inject my DLL into the calculator.exe, than i want to receive it. What do i do? [link](https://i.imgur.com/7i7QgQr.png?1) –  gofmode Aug 18 '18 at 19:12
  • It will have many windows. Run Spy++ to list them. – Evg Aug 18 '18 at 19:18
  • Calculator (in Windows 10) is a UWP application. The `HWND` you seek to find is largely useless in a UWP application. It's still wildly unclear, what you are ultimately trying to accomplish. – IInspectable Aug 18 '18 at 20:07
  • calculator.exe is just a exsample. I am trying to get the HWND to a game window. So i inject dll -> get hwnd from the window i injected the dll into. I than going to use the HWND to hook wndproc and for some dx11 stuff for drawing a overlay –  gofmode Aug 18 '18 at 21:25
  • If you are using examples, you need to make sure that they match your use case. If you cannot assess this, don't use examples. Ask for the Real Thing instead. – IInspectable Aug 18 '18 at 22:02

1 Answers1

1

To summarize the discussion in comments.

Your code seems to be correct. But FindWindow and what you're doing are different things. Your goal is not clear from the question as there can be several windows associated with a process and a thread and it's not clear which one you want. This is probably the reason why sometimes you get the "wrong" window: there are several windows matching your criterion (same process id), but enumeration order is not defined (effectively random). You can enumerate all the windows into, e.g., std::vector and then manually check (using Spy++, for example) which one you need. This analysis could help you to determine additional criteria (window style, for example) to single out the window you want.

As a sidenote, global variables should be avoided if possible. EnumWindows accepts second argument that is then passed into the callback function. The size of this argument is guaranteed to be enough to hold a pointer. Hence, we can declare a local variable and pass its address into the callback function.

BOOL CALLBACK HWND_Callback(HWND hwnd, LPARAM lParam)
{
    HWND& CorrectHWND = *reinterpret_cast<HWND*>(lParam);
    // exactly the same code
} 

HWND Get_HWND()
{
    HWND CorrectHWND = NULL;
    EnumWindows(HWND_Callback, reinterpret_cast<LPARAM>(&CorrectHWND)));
    return CorrectHWND;
}
Evg
  • 25,259
  • 5
  • 41
  • 83