-2

Alright the ONLY reason I ask is because I read up that HWND is a pointer, pointers change the original value instead of creating a duplicate that is stored in that memory location.

But it doesn't really act like a pointer the reason I say that because if I were to have a switch statement, Example:

void ExampleFunction(int iSwitch)
{
    HWND hButton;

    switch (iSwitch)
    {
     case 1:
     hButton = CreateWindow( Blah Blah blah); //<-- Shouldn't it return to hButton's location.
     break;

     case 2: 
     ShowWindow(hButton, SW_SHOW); //<-- Ops forgot what was stored in hButton.
     break;
    }
}

But view as a new C++ Win32 programmer, shouldn't it not forget? Just by locating the memory address then grabbing the contents inside. Unless the memory address changes etc.

I don't really know would, you mind elaborating? Thanks.

  • Please try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve), because the code in the question is missing a lot of context. – Some programmer dude Oct 17 '15 at 17:39
  • Think of an HWND as being a value that identifies the window. All you ever do is pass it to functions that need to know which window you refer to. – David Heffernan Oct 17 '15 at 17:47
  • _"pointers change the original value instead of creating a duplicate that is stored in that memory location"_ That's a very simplistic and inaccurate way of defining pointers. – Lightness Races in Orbit Oct 17 '15 at 18:10
  • @Lightness Races in Orbit - Well reading from books they tend to give you the simplistic way of describing something instead of having 5 chapters just describing what a pointer is. So I just copied what I heard from reading C++ Primer Plus 6th edition. – Trevin Corkery Oct 17 '15 at 18:12
  • @TrevinCorkery: Okay, but I also said "inaccurate". It's led you to this misunderstanding. Doesn't that say something? – Lightness Races in Orbit Oct 17 '15 at 18:21
  • In userland, it's an opaque token. Stop thinking of it as anything else. Maintaining GUI state data across message handlers etc. is up to you. – Martin James Oct 17 '15 at 18:42
  • Just the title: 'Static HWND - Why is it necessary?' is incorrect. It is not necessary. It's common for GUI frameworks to have at least one 'static' top level object to represent the entire application, but that is not an HWND. – Martin James Oct 17 '15 at 18:46
  • This is not a Windows API specific question and the behavior the OP is confused about is not exclusive to HWNDs. The OP does not understand why they have to declare local variables static in order for them to retain their values across function calls. I'm not sure how to answer that question appropriately, but I will try anyway. – andlabs Oct 17 '15 at 18:51
  • Possible duplicate of [Scope vs. Lifetime of Variable](https://stackoverflow.com/questions/11137516/scope-vs-lifetime-of-variable) – IInspectable Mar 05 '18 at 10:03

2 Answers2

3

This is probably not the highest quality answer; suggestions for improvement welcome.

You are correct in assuming that the value of a HWND never changes while the window that the HWND points to remains alive.

What I am guessing is that you have written code like this:

LRESULT CALLBACK wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    HWND button;

    switch (uMsg) {
    case WM_CREATE:
        button = CreateWindowEx(...);
        break;
    case WM_COMMAND:
        if (lParam == (LPARAM) button)
            /* button was clicked; do something */;
    }
    return DefWindowProc(...);
}

and wondering why it doesn't work, but changing

    HWND button;

to

    static HWND button;

fixes it.

This is not a property of HWNDs. Nothing about the code failing is because the value of the HWND has changed. In fact, this has nothing to do with Windows at all, and everything to do with C.

The reason why the code doesn't work is that the variable button is created fresh each time the wndproc() function is called. See, a window procedure is called many times, once for each message that a window ever receives throughout the execution of your program. Each time, you get a brand new button variable, and the value that the button variable had in previous calls is lost. The pointer is still there, but it's not stored in any variable or any other memory location! The window hasn't been destroyed. You just can't get to it through normal means anymore.

What the static does is tell C that you want the variable to stay around through every function call. So now every call to your window procedure has the same button, and that pointer value isn't lost anymore.

It's a quick fix, and it doesn't really scale well to very large projects. In those cases, structures containing the window handles, (maybe) global variables, or use of GWLP_USERDATA or other cbWndExtra bytes are better. I guess a better question is why this quick fix keeps getting suggested as the solution to other peoples's similar problems here on Stack Overflow (or at least why it is a quick fix isn't explained), but that's something we have to think about as a community.

Just remember that by default, in most languages (not just C and C++!), a function's local variables only exist for the duration of each individual function call.

andlabs
  • 11,290
  • 1
  • 31
  • 52
2

The code in the question is missing a lot of context (so just guessing blindly here), but if the code is in a separate function and the variable hButton is a local variable in that function, then you have to remember that local variables go out of scope when the function they are in returns, and the next time the function is called, the variable is a completely new one that is unique for that call and only that call.

Also worth mentioning is that non-static local variables are not initialized automatically in any way. If you don't explicitly initialize such a variable, its value will be indeterminate and using it in any way (except to initialize it) leads to undefined behavior.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • This wasn't my actual code I know its missing a lot because i didn't copy and paste, I just wrote it out in here for example purposes, and thanks for describing that to me. I understand now what you probably meant, the HWND and Switch were all in the same function so I will edit the main post to make that more clear. – Trevin Corkery Oct 17 '15 at 18:06
  • *This wasn't my actual code I know its missing a lot because i didn't copy and paste, I just wrote it out in here for example purposes, and thanks for describing that to me.* Please don't ever ever do that. Don't post fake code. Don't waste everyone's time. – David Heffernan Oct 18 '15 at 06:19