'Win32'에 해당되는 글 1건

  1. 2015.03.15 일반적인 윈도우 소멸 순서 - WM_CLOSE, WM_DESTROY, WM_QUIT
2015.03.15 15:02


※ WM_SYSCOMMAND → WM_CLOSE → WM_DESTROY → WM_QUIT


1. WM_CLOSE
   - 윈도우가 닫히기 전에 메시지가 전달 된다.
   - 아직 윈도우가 파괴된 것은 아니므로 윈도우가 파괴되는 것을 중간에 제어 할 수 있다.
   - 윈도우의 “닫기” 를 누르거나, 키보드의 “Alt + F4”를 눌렀을 경우 발생




   - WM_CLOSE 의 핸들러(OnClose) 에서 추가적인 제어를 하지 않는다면 메시지는
      DefWindowsProc 로 보내진다.
   - CDialog::OnClose() 는 내부적으로 DestroyWindow() 함수를 호출 한다.
   - DestroyWindow() 함수는 내부적으로 WM_DESTROY 메시지를 발생 시킨다.


2. DestroyWindow()
   - CWnd내부에 있는 윈도우를 destroy 한다. 
   - 윈도우를 해제하고 입력 포커스를 제거하기 위한 적절한 message를 윈도에게 보낸다. 
   - 윈도우의 메뉴 제거  
   - application queue를 비운다.
   - timer를 제거 
   - Clipboard의 소유주 제거
   - Clipboard-viewer chain을 끊는다. ( CWnd가 viewer chain의 맨 위에 있을 경우 ) 
   - WM_DESTROY(OnDestroy)와 WM_NCDESTROY(OnNcDestroy) 메시지를 윈도우 에게 보낸다.
     하지만 아직 CWnd 객체는 destroy하지 않는다.


3. WM_DESTROY
   - Framework이 CWnd에게 현재 CWnd가 소멸되고 있는 중이라고 알려 주기 위하여 호출 
   - 화면에 윈도우를 숨긴 후 메시지 발생, 아직 윈도우 자체는 파괴되지 않았다
   - DestroyWindows() 함수에서 발생 시킨다.
   - WM_CREATE 에 반대되는 동작을 수행 한다.
   - 차일드 윈도우가 있다면 이 메시지를 차례대로 전달 한다.
   - 메인 윈도우에서 PostQuitMessage() 함수를 반드시 호출하여 프로세스의 메시지 루프
     를 종료시켜야 한다. 그렇지 않다면 윈도우만 파괴되고 메시지 루프는 계속 실행중인
     상태가 되므로 프로세스가 종료되지 않는다.


4. WM_NCDESTROY
   - Client 영역이 아닌 영역이 Destroy 될 때 Framework 에 의하여 불려짐.
   - 윈도우가 소멸될 때 마지막으로 호출되는 메시지
   - 핸들러를 재정의 한다면 기본 호출 함수를 가장 위에서 해주자.

   
5. PostNcDestroy()
   - 윈도우가 소멸된 후 OnNcDestroy() 함수에 의해 불려지는 함수
   - 사용자들이 상속받아 만든 클래스의 정리를 위한 코드를 넣음.


6. View가 닫혀질 때 호출되는 핸들러 순서
BOOL CAniView::DestroyWindow() 

  
// TODO: Add your specialized code here and/or call the base class 
// 윈도우가 안보여 지기전에 해야 할 작업 처리
  
 return CView::DestroyWindow(); 
  

  
void CAniView::OnDestroy() 

  
  CView::OnDestroy(); 
  
  // TODO: Add your message handler code here 
  

  
void CAniView::PostNcDestroy() 

  
  // TODO: Add your specialized code here and/or call the base class 
  
  CView::PostNcDestroy(); 
  
}


7. WM_QUIT
   - 응용프로그램을 종료 하라는 메시지
   - PostQuitMessage() 가 발생 시키는 메시지
   - GetMessage() 함수가 0 을 리턴하도록 함으로써 메시지 루프를 종료
   - PeekMessage() 함수는 따로 WM_QUIT 메시지를 점검해야 한다.





다음과 같이 종료 시킨다.


HWND hWndBuilder;

hWndBuilder = ::FindWindow( NULL, "NxBuilder" );

1번 : if(hWndBuilder!=NULL) ::PostMessage(hWnd,WM_CLOSE,0,0);  --> 정상종료시

2번 : if(hWndBuilder!=NULL) ::PostMessage(hWnd,WM_DESTROY,0,0);  --> 마찬가지

3번 : if(hWndBuilder!=NULL) ::PostMessage(hWnd,WM_QUIT,0,0); --> 강제종료





신고


Posted by injunech

티스토리 툴바