본문 바로가기

old drawer/C, C++, MFC

[MFC] SDI 환경에서 이벤트 처리 OnCommand()

뷰 클레스에서 작업할때, 짜증나는게 어떤 마우스 이벤트나, 키 이벤트를 처리하는데, 수많은 마우스 이벤트에 대해서 처리하다 보면 뷰클레스의 크기가 커지고, 뷰클레스에서 작업하다 보니깐, 다른 클레스에 접근하는게 쉽지 않아서, 객체들간이 메시지 주고 받는게 적어지고, 거의 뷰클레스 위주로 짜여지는 악순환이 생기게 된다. 즉 뷰클레스에서 일어나는 이벤트는 뷰클레스에 추가할 수 밖에 없는 현실...  

나도 한참 뒤에 알았는데 좋은 방법이 있다. 바로 메인프레임에서 이벤트를 건드는 것이다.  메인프레임에서는 AfxGetMainWnd() 함수를 통해서 다른 클레스 객체에 접근이 쉽기때문이다.

초록색으로 표시한 부분은, 일반적인 이벤트 핸들러 추가로 생성한 코드고

빨간색은 메인프레임의 OnCommand를 오버라이드 한것이다. OnCommand를 오버라이드 하면 SDK 프로그래밍 하듯이 프로그램을 짤 수 있다.

   

   

   

당연히 실행되는 순서는 OnCommand 다음에 이벤트핸들러이다.

그리고 OnCommand함수 마지막에

 return CFrame::OnCommand(wParam, lPram)를 주석처리하고 그냥 true로 리턴하면

이벤트 핸들러 추가로 작성된 파란색 부분의 코드는 실행되지 않는다.

 

WM_COMMAND 메시지를 수신한

MFC 클래스

라우팅 순서와 내용

CMDIFrameWnd

(MDI 스타일의 최상위 부모 프레임 윈도우)

① CMDIChildWnd(활성화된 자식 프레임 윈도우) 클래스에서 처리

② CMDIFrameWnd 클래스에서 처리

③ CWinApp 클래스에서 처리

CFrameWnd

(SDI 스타일의 최상위 부모 프레임 윈도우 혹은 MDI의 자식 프레임 윈도우)

① 활성화된 클라이언트 뷰 윈도우에서 처리

② CFrameWnd 혹은 CMDIChildWnd 클래스에서 처리

③ CWinApp 클래스에서 처리

CView 뷰

① CView 클래스에서 처리

② CView 클래스와 연결된 CDocument 클래스에서 처리

CDocument 클래스

① CDocument 클래스에서 처리

② CDocument 클래스 객체와 연결된 문서 템플릿에서 처리

CDialog 클래스

① CDialog 클래스 객체에서 처리

② CDialog 클래스 객체를 소유한 윈도우에서 처리

③ CWinApp 클래스에서 처리


CView -> CDoc  -> CFrame -> App 순으로 수신된다.
<추천>
1. CView 클래스
2. CMainFrame 클래스
3. CWinApp 클래스