function call under wm_close or wm_destroy

I have this confusion that i cant decide whether to put the functions under WM_CLOSE or WM_DESTROY...the function calls for destroying windows and deleteing brushes/pens/icons etc should be put under which of the 2 messages??
Yes, this can be confusing. I tend to use WM_CLOSE even though the docs say the window can be assummed to still be valid during a WM_DESTROY. To tell you the truth, I don't usually use a WM_DESTROY. I do all my cleanup from WM_CLOSE, and call DestroyWindow() from there. For what its worth, that's what I do.

The thing you have to be careful about here is that if you return 0 from WM_CLOSE, WM_DESTROY won't be called. That's why I call DestroyWindow() from WM_CLOSE if I handle that message.
Last edited on
Thanks...i think ill keep that in mind and put all destroy functions under wm_close and only postquitemessage under wm_destroy..
Geeez, you got me to thinking. I've even fallen into the habit of putting my PostQuitMessage() in WM_CLOSE handlers too (if its the main program window). I got to wondering if I'd picked up a bad habit somewhere and there was some kind of stipulation that it should be in WM_DESTROY. I have noticed most folks use WM_DESTROY that way. This is what the docs say...

 
The PostQuitMessage function indicates to the system that a thread has made a request to terminate (quit). It is typically used in response to a WM_DESTROY message. 


So it doesn't say it has to be there. I've certainly seen no bad effects from what I do. This is like my typical SDK template...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
  Form1 -- My Basic Simple Template Program For Win32 Programming With The Windows Api.
*/

//Main.cpp
#include <windows.h>
#include <tchar.h>
#include "Form1.h"
EVENTHANDLER  EventHandler[3];


long fnWndProc_OnCreate(lpWndEventArgs Wea)          //Only occurs once
{                                                    //when Window is
 Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance; //created.
 return 0;
}

long fnWndProc_OnCommand(lpWndEventArgs Wea)         //A lot of the standard
{                                                    //Windows Controls such as
 return 0;                                           //edit controls, combo boxes,
}                                                    //etc, use WM_COMMAND


long fnWndProc_OnClose(lpWndEventArgs Wea)           //PostQuitMessage() will
{                                                    //cause the while loop
 DestroyWindow(Wea->hWnd);                           //(message pump) in WinMain()
 PostQuitMessage(0);                                 //to exit.
 return 0;
}


void AttachEventHandlers(void)      //This procedure maps windows messages to the
{                                   //procedure which handles them.
 EventHandler[0].Code=WM_CREATE,    EventHandler[0].fnPtr=fnWndProc_OnCreate;
 EventHandler[1].Code=WM_COMMAND,   EventHandler[1].fnPtr=fnWndProc_OnCommand;
 EventHandler[2].Code=WM_CLOSE,     EventHandler[2].fnPtr=fnWndProc_OnClose;
}


long __stdcall fnWndProc(HWND hwnd, unsigned int msg, WPARAM wParam,LPARAM lParam)
{
 WndEventArgs Wea;                  //This procedure loops through the EVENTHANDER array
                                    //of structs to try to make a match with the msg parameter
 for(unsigned int i=0; i<3; i++)    //of the WndProc.  If a match is made the event handling
 {                                  //procedure is called through a function pointer -
     if(EventHandler[i].Code==msg)  //(EventHandler[i].fnPtr).  If no match is found the
     {                              //msg is passed onto DefWindowProc().
        Wea.hWnd=hwnd, Wea.lParam=lParam, Wea.wParam=wParam;
        return (*EventHandler[i].fnPtr)(&Wea);
     }
 }

 return (DefWindowProc(hwnd, msg, wParam, lParam));
}


int __stdcall WinMain(HINSTANCE hIns, HINSTANCE hPrevIns, LPSTR lpszArgument, int iShow)
{
 TCHAR szClassName[]=_T("Form1");
 WNDCLASSEX wc;
 MSG messages;
 HWND hWnd;

 AttachEventHandlers();
 wc.lpszClassName=szClassName;                wc.lpfnWndProc=fnWndProc;
 wc.cbSize=sizeof (WNDCLASSEX);               wc.style=CS_DBLCLKS;
 wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);     wc.hInstance=hIns;
 wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION);  wc.hCursor=LoadCursor(NULL,IDC_ARROW);
 wc.hbrBackground=(HBRUSH)COLOR_BTNSHADOW;    wc.cbWndExtra=0;
 wc.lpszMenuName=NULL;                        wc.cbClsExtra=0;
 RegisterClassEx(&wc);
 hWnd=CreateWindowEx(0,szClassName,szClassName,WS_OVERLAPPEDWINDOW,100,100,350,300,HWND_DESKTOP,0,hIns,0);
 ShowWindow(hWnd,iShow);
 while(GetMessage(&messages,NULL,0,0))
 {
  TranslateMessage(&messages);
  DispatchMessage(&messages);
 }

 return messages.wParam;
}


header referenced...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//Form1.h
typedef struct    WindowsEventArguments
{
 HWND             hWnd;
 WPARAM           wParam;
 LPARAM           lParam;
 HINSTANCE        hIns;
}WndEventArgs, *lpWndEventArgs;


struct EVENTHANDLER
{
 unsigned int    Code;
 long            (*fnPtr)(lpWndEventArgs);
};


Yeahh..postquitemessage should be under wm_destroy..but i feel stuff like deleteobject and the rest should also be under wm_destroy-if we put it under wm_close,it would be destroyed whereas the window is still active while wm_close is processed...?
Topic archived. No new replies allowed.