1
votes

I packaged the winapi CreateWindowEx into a simple class. Since every window sharing a same wndProc(hwnd,msg,wparam,lparam), I put every window created by CreateWindowEx into a map to distribute msg, like this:

wndProc(hwnd, msg, wparam, lparam){
    if(map[hwnd]!=nil){
        switch(msg){
            map[hwnd].wndProc(...)
        }
    }
}

And each time a window or its parent window being destroyed, remove it from the map:

case WM_DESTROY: delete(map, hwnd)

But things like buttons do not receive WM_DESTROY. I printed all msg in WM_NOTIFY and WM_COMMAND but i got noting.

So how can I remove those child windows form the map at the right time? Or a way distribute the msg without creating a hwnd map?

2

2 Answers

6
votes

They certainly do get that message. But their window procedure is inside Windows, not inside your program. So you never see it. Something you can read in the MSDN documentation, note how WM_DESTROY doesn't get any special treatment. Nor generate a notification that your parent window can see.

Short from automatically removing all the child windows when you see the parent window destroyed, subclassing controls is a pretty standard requirement for C++ class library wrappers. Best to not invent your own btw, this has been done many times already.

2
votes

So how can I remove those child windows form the map at the right time?

You have to subclass every window you create, either with SetWindowLongPtr(GWL_WNDPROC) or SetWindowSubClass(), then you will receive all of the WM_DESTROY messages.

Or a way distribute the msg without creating a hwnd map?

Frameworks like ATL and VCL handle that by dynamically allocating a thunk for each window and putting the object pointer right in the thunk, then use the thunk as the window procedure. That way, whenever the thunk is called, it passes the message directly to its associated object.