0

I have some code to grab a window handle and then get its rectangle.

HWND hWnd = FindWindow("CalcFrame", NULL);

LPRECT rect;
int retval = GetWindowRect(hWnd, rect);

if (retval == 0) {
    DWORD error = GetLastError();
    std::cout << error << "\n";
} else {
    std::cout << "FindWindow/GetWindowRect Success" << "\n";
}

This code works fine, and the values are stored in rect when I have no logging statements. When I add this logging statement directly after...

std::cout << rect->left << "," << rect->top << "," << rect->right << "," << rect->bottom << "\n";

I get an error (error code 1400) from the GetLastError() winapi method, showing that we could not find the window handle and get the windows rectangle.

When I use this logging statement, I get no error.

std::cout << "Right: " << rect->right << "\n";
std::cout << "Bottom: " << rect->bottom << "\n";

What could possibly be the reason for this?

Tyler Nichols
  • 196
  • 3
  • 14
  • 9
    `rect` is uninitialised, you are clobbering random memory and have undefined behaviour. You need to provide the address of a `RECT` structure to store the values in. – Jonathan Potter Jun 05 '18 at 14:59
  • 3
    Change `LPRECT` to `RECT` and `GetWindowRect(hWnd, &rect);`. You need to pass the address of an existing RECT struct. – 001 Jun 05 '18 at 15:02
  • Thanks @JonathanPotter you were right in what was the issue. I wish you posted it as an answer :) – Tyler Nichols Jun 05 '18 at 15:04

1 Answers1

3

The correct code is:

RECT rect;
int retval = GetWindowRect(hWnd, &rect);

GetWindowRect expects a pointer to an existing structure.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • Does it make a difference to use RECT rect; or RECT rect = {0} ? I have seen the latter in another answer. – Tyler Nichols Jun 05 '18 at 15:04
  • 1
    @TylerNichols - `rect` here out only parameter. not need initialize it – RbMm Jun 05 '18 at 15:08
  • For my first comment https://stackoverflow.com/questions/88957/what-does-0-mean-when-initializing-an-object is relevant. – Tyler Nichols Jun 05 '18 at 15:08
  • 1
    @TylerNichols - and so what ? we can write and `RECT rect = {}`, but `GetWindowRect` not look and not use - what in `&rect` before call. it store here out data. as result need simply `RECT rect` without any initialization. – RbMm Jun 05 '18 at 15:14
  • @RbMm I totally agree. But I honestly had no idea of what x = {0} did, only a guess. And my guess was close. So I am adding it for context. – Tyler Nichols Jun 05 '18 at 15:16
  • 3
    @TylerNichols It is a good habit to always initialize variables, so there is always a defined state even if a programmer makes a mistake later in the code (e. g. using the value without checking return value of `GetWindowRect()` or a bug in `GetWindowRect()` ... very unlikely in this case but possible for more complex APIs). Trying to debug code with uninitialized variables can create real headache (typically crashes only on customers machine, never on devs machine). BTW, with C++11, you can leave out the zero and even the assignment operator (e. g. `RECT rect{};` will zero-initialize). – zett42 Jun 05 '18 at 15:19
  • @zett42 in pre-C++11 versions, depending on the compiler, you may be able to leave out the zero, at least: `RECT rect = {};` – Remy Lebeau Jun 05 '18 at 17:21