작업 표시줄에서 '닫기'를 클릭하여도 WM_CLOSE 메세지가 발생합니다.
최소화 상태와 상관없이...
그런데 MainForm에서 WM_CLOSE 메세지를 잡으려고 Sub-classing해도 잡히지 않을것입니다.
그 이유는 다음팁을 보면 좀 알수 있습니다.
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=602
윈도우즈에서는 작업표시줄에 버튼이 나타나는 폼은
대개 Form의 WndParent 속성이 DeskTopWindow인경우에 나타납니다.
그런데 VCL(빌더 또는 델파이)에서 생성되는 폼은 WndParent 가 Application->Handle이 됩니다.
결론적으로
작업표시줄에 나타나는 버튼은 메인폼->Handle 이 아니라 Application->Handle 인것입니다.
그러므로 WM_CLOSE 메세지가 발생은 하는데
MainForm에서 발생하지 않고, Application 에서 발생하는것입니다.
Application->Handle을 sub-classing해보면 WM_CLOSE 메세지가 발생하는것을 확인할수 있습니다.
Forms.pas 파일을 보면
procedure TApplication.WndProc(var Message: TMessage); 함수
즉 Application의 윈도우 프로시져 함수를 보면 아래와 같은 부분이 있죠
procedure TApplication.WndProc(var Message: TMessage);
begin
....
WM_CLOSE:
if MainForm <> nil then MainForm.Close;
...
end;
즉 Application에서 WM_CLOSE 메세지가 발생하면
메인폼.Close를 call 해주네요
즉 작업표시줄에서 '닫기'를 클릭 하더라도 메인폼의 OnClose이벤트가 발생하겠죠
[Application->Handle sub-classing 샘플]
void * OrgAppWndProc;
int __stdcall AppWndProc(HWND Wnd,int Msg, int wParam, int lParam)
{
if(Msg==WM_CLOSE)
ShowMessage("Application wm_close");
CallWindowProc(( FARPROC)OrgAppWndProc,Wnd,Msg,wParam,lParam);
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
OrgAppWndProc=(WNDPROC)GetWindowLongA(Application->Handle,GWL_WNDPROC);
SetWindowLongA(Application->Handle,GWL_WNDPROC,(LONG)&AppWndProc);
}
그럼
아제나 님이 쓰신 글 :
: 작업 표시줄에서 '닫기'를 누르는 것은 강제로 프로세스를 죽이는 것과 마찬가지 입니다.
:
: 그렇기 때문에 WM_CLOSE가 발생하지 않죠.
:
: 하지만 WM_QUERYENDSESSION 과 WM_DESTORY 메시지는 정상적으로 발생합니다.
:
: WM_QUERYENDSESSION 프로그램 종료 여부를 한번 더 확인할 수 있으며,
:
: WM_DESTROY는 이미 종료가 결정되어서 발생되는 것이므로 프로그램에 필요한 정보 저장 등을 하시면 됩니다.
:
: 메인 폼에 OnCloseQuery 이벤트와 OnDestroy 이벤트를 등록하셔서 개발하시면 됩니다.
:
:
:
:
: 펭귄 님이 쓰신 글 :
: : 안녕하세요
: :
: : 프로그램을 최소화 한 상태에서 오른쪽 클릭 "닫기(C)"를 누르면 어디서 어떤 메시지가 발생하나요
: :
: : 우측 상단 X 종료 버튼은 WM_CLOSE 가 생기는데
: :
: : 이건
: :
: : WM_CLOSE 가 아니더라고요...