1 u u 2 Message Map 3 Message

  • Slides: 48
Download presentation

목 1 차 메시지 개요 u 메시지 구조 u 메시지 종류 2 Message Map

목 1 차 메시지 개요 u 메시지 구조 u 메시지 종류 2 Message Map 처리 기본개념 3 Message Map의 구성 4 Message 처리단계 5 메시지 매크로의 확장 u DECLARE_MESSAGE_MAP u BEGIN_MESSAGE_MAP u END_MESSAGE_MAP 2 Univ of Incheon, 고급프로그래밍

메시지 개요(5/7) u 명령 메시지(WM_COMMAND) n n n 메뉴의 선택, 키보드 가속기 사용과 같은

메시지 개요(5/7) u 명령 메시지(WM_COMMAND) n n n 메뉴의 선택, 키보드 가속기 사용과 같은 사용자의 행동에 의해 발생된 메시지 어떤 메뉴가 눌렸는지 구별하기 위해 메뉴의 ID가 윈도우 메시지의 WPARAM 을 통해 전달 ON_COMMAND 메시지 맵 항목들을 가진 여러 응용 프로그램 구성 요소에 의 해 처리 <프로젝트명. cpp> BEGIN_MESSAGE_MAP(CMain. Frame, CFrame. Wnd) ON_COMMAND (ID_FILE_NEW, On. File. New) ON_COMMAND (ID_FILE_OPEN, On. File. Open) ON_COMMAND (ID_FILE_SAVE, On. File. Save) ON_COMMAND (ID_FILE_SAVE_AS, On. File. Save. As) ON_COMMAND (ID_FILE_EXIT, On. File. Exit) END_MESSAGE_MAP() void CMain. Window: : On. File. Exit () { Post. Message (WM_CLOSE, 0, 0); } 8 Univ of Incheon, 고급프로그래밍

Message Map 처리 기본개념(3/5) SDK로 표현 LESULT CALLBACK Wnd. Proc (HWND hwnd, UINT i.

Message Map 처리 기본개념(3/5) SDK로 표현 LESULT CALLBACK Wnd. Proc (HWND hwnd, UINT i. Msg, WPARAM w. Param, LPARAM l. Param) { HDC hdc; PAINTSTRUCT ps; 해당하는 모듈을 모두 switch문으로 설정 } switch (i. Msg) { case WM_CREATE : //윈도가 만들어질 때 모듈 break; case WM_PAINT : //화면 출력 모듈 break; case WM_KEYDOWN : //키 입력시 처리 모듈 break; case WM_CHAR : //문자 입력시 처리 모듈 break; case WM_DESTROY : //윈도가 없어질 때 모듈 break; } MFC로 표현 BEGIN_MESSAGE_MAP(CMy. Wnd, CWnd) ON_WM_CREATE( ) ON_WM_PAINT( ) ON_WM_KEYDOWN( ) ON_WM_CHAR( ) ON_WM_DESTROY( ) END_MESSAGE_MAP( ) 13 Univ of Incheon, 고급프로그래밍

Message Map 의 구성 u 선언부 n DECLARE_MESSAGE_MAP() Class CChild. View : Public CWnd

Message Map 의 구성 u 선언부 n DECLARE_MESSAGE_MAP() Class CChild. View : Public CWnd { …. DECLARE_MESSAGE_MAP( ) } u 정의부 n n BEGIN_MESSAGE_MAP() END_MESSAGE_MAP() BEGIN_MESSAGE_MAP(CChild. View, CWnd) // 메시지 맵 엔트리 추가 END_MESSAGE_MAP() 16 Univ of Incheon, 고급프로그래밍

Message 처리단계(1/3) u 메시지 핸들러 함수 선언 (DECLARE_MESSAGE_MAP) Child. View. h class CChild. View

Message 처리단계(1/3) u 메시지 핸들러 함수 선언 (DECLARE_MESSAGE_MAP) Child. View. h class CChild. View : : public CWnd { //{{AFX_MSG(CChild. View) afx_msg void On. LButton. Down(UINT n. Flags, CPoint point); afx_msg void On. Key. Down(UINT n. Char, UINT n. Rep. Cnt, UINT n. Flags); 핸들러 함수 선언 afx_msg void On. RButton. Down(UINT n. Flags, CPoint point); //}}AFX_MSG DECLARE_MESSAGE_MAP( ) } 17 Univ of Incheon, 고급프로그래밍

Message 처리단계(2/3) u 메시지 매크로 (BEGIN_MESSAGE_MAP, END_MESSAGE_MAP) Child. View. cpp BEGIN_MESSAGE_MAP(CChild. View, CWnd) //{{AFX_MSG_MAP(CChild.

Message 처리단계(2/3) u 메시지 매크로 (BEGIN_MESSAGE_MAP, END_MESSAGE_MAP) Child. View. cpp BEGIN_MESSAGE_MAP(CChild. View, CWnd) //{{AFX_MSG_MAP(CChild. View) ON_WM_LBUTTONDOWN( ) ON_WM_KEYDOWN( ) ON_WM_RBUTTONDOWN ( ) //}}AFX_MSG END_MESSAGE_MAP( ) 18 Univ of Incheon, 고급프로그래밍

Message 처리단계(3/3) u 핸들러 구현(함수) : 메시지를 처리하는 함수 구현 Child. View. cpp void

Message 처리단계(3/3) u 핸들러 구현(함수) : 메시지를 처리하는 함수 구현 Child. View. cpp void CChild. View: : On. LButton. Down(UINT n. Flag, Cpoint) { CWnd: : On. LButton. Down(n. Flags, point); } void CChild. View: : On. Key. Down(UINT n. Flag, Cpoint) { CWnd: : On. Key. Down(n. Flags, point); } void CChild. View: : On. RButton. Down(UINT n. Flag, Cpoint) { CWnd: : On. RButton. Down(n. Flags, point); } 19 Univ of Incheon, 고급프로그래밍

메시지 매크로의 확장(1/8) u DECLARE_MESSAGE_MAP() AFXWIN. H 20 Univ of Incheon, 고급프로그래밍

메시지 매크로의 확장(1/8) u DECLARE_MESSAGE_MAP() AFXWIN. H 20 Univ of Incheon, 고급프로그래밍

메시지 매크로의 확장(7/8) BEGIN_MESSAGE_MAP(CChild. View, CWnd) ON_WM_LBUTTONDOWN( ) ON_WM_KEYDOWN( ) ON_WM_RBUTTONDOWN( ) END_MESSAGE_MAP( )

메시지 매크로의 확장(7/8) BEGIN_MESSAGE_MAP(CChild. View, CWnd) ON_WM_LBUTTONDOWN( ) ON_WM_KEYDOWN( ) ON_WM_RBUTTONDOWN( ) END_MESSAGE_MAP( ) const AFX_MSGMAP CChild. View: : Get. Message. Map( ) const { return & CChild. View: : message. Map; } const AFX_MSGMAP CChild. View: : _message Map = {&CWnd: : message. Map, &CChild. View: : _message. Entries[]}; const AFX_MSGMAP_ENTRY CChild. View: : _message. Entries[]={ {WM_LBUTTONDOWN, 0, 0, 0, Afx. Sig_vwp, &On. LButton. Down}, {WM_KEYDOWN, 0, 0, 0, Afx. Sig_vwp, &On. Key. Down}, {WM_RBUTTONDOWN, 0, 0, 0, Afx. Sig_vwp, &On. RButton. Down}, {0, 0, afx. Sig_end, (AFX_PMSG)0 } }; 26 Univ of Incheon, 고급프로그래밍

사용자 정의 메시지(5/8) u Send. Message n n n 사용자가 만든 메시지는 사용자가 직접

사용자 정의 메시지(5/8) u Send. Message n n n 사용자가 만든 메시지는 사용자가 직접 메시지를 발생시킴 이때 사용하는 함수가 Send. Message() CWnd의 멤버 함수 LRESULT Send. Message ( UINT message, WPARAM w. Param = 0, LPARAM l. Param = 0); Message : 보내고자 하는 Message ID w. Param : 메시지 정보와 함께 보내주는 WPARAM 인자 l. Param : 메시지 정보와 함께 보내주는 l. Param 인자 n WM_MYMESSAGE를 생성 Send. Message(WM_MYMESSAGE, 0, 0); 32 Univ of Incheon, 고급프로그래밍

메시지 처리 방식의 종류(1/2) u 큐 경유 방식 n n 입력 메시지들(WM_LBUTTONDOWN, WM_KEYDOWN, WM_SYSTEMDOWN,

메시지 처리 방식의 종류(1/2) u 큐 경유 방식 n n 입력 메시지들(WM_LBUTTONDOWN, WM_KEYDOWN, WM_SYSTEMDOWN, WM_TIMER 등) message queue message loop window procedure u 큐를 경유 하지 않는 방식 n n 입력 메시지를 제외한 대부분의 메시지들(WM_CREATE, WM_SIZE, WM_CLOSE, WM_PAINT() WM_DESTROY, WM_MOVE, 등) message window procedure 36 Univ of Incheon, 고급프로그래밍

메시지 처리 흐름(2/11) int CWin. Thread: : Run() // idle time 상태를 추적하기 위한

메시지 처리 흐름(2/11) int CWin. Thread: : Run() // idle time 상태를 추적하기 위한 변수 { BOOL b. Idle = TRUE; LONG l. Idle. Count = 0; //WM_QUIT를 받을 때까지 메시지를 가져와 분배한 다. for (; ; ) { while ( b. Idle && !: : Peek. Message( &m_msg. Cur, . . . ) ) {// b. Idle이 TRUE 이고 메시지 큐에 메시지가 없는지 체크 if ( !On. Idle ( l. Idle. Count++ ) ) b. Idle = FALSE; } do { if ( !Pump. Message() ) return Exit. Instance(); // WM_QUIT를 받으면 여기 if ( Is. Idle. Message ( &m_msg. Cur ) ) { b. Idle = TRUE; // idle 메시지면 여기 Idle. Count = 0; } } while ( : : Peek. Message ( &m_msg. Cur, . . . ) ); } } 39 Univ of Incheon, 고급프로그래밍

메시지 처리 흐름(5/11) event 1 CWin. Tread: : Run() n CWnd: : On. Wnd.

메시지 처리 흐름(5/11) event 1 CWin. Tread: : Run() n CWnd: : On. Wnd. Msg n 2 3 CWin. Tread: : Pump. Message() Get. Mesage. Map( )을사용하여메시지맵에서 아이디에 해당하는 핸들러 검색 n CWnd: : Pre. Translate. Messsage() 4 CWnd: : Dispatch. Messsage() 5 Afx. Wnd. Proc( ) 6 Afx. Call. Wnd. Proc( ) 7 CWnd: : On. Wnd. Msg() 8 CWnd: : Def. Window. Proc() 해당 메시지 핸들러(사용자 정의 메시지 핸들러) 검색 후 해당 메시지 핸들러 실행 n 예외) WM_COMMAND On. Command 함수 호출 WM_NOTIFY On. Notify 함수 호출 CWnd: : On. Command() CWnd: : On. Notify() CWnd: : Get. Message. Map() Tread Message Queue 6 42 Message Handling Function Univ of Incheon, 고급프로그래밍

메시지 처리 흐름(6/11) CWnd: : On. Wnd. Msg n Wincore. cpp // WM_COMMAND 계열

메시지 처리 흐름(6/11) CWnd: : On. Wnd. Msg n Wincore. cpp // WM_COMMAND 계열 처리 // WM_NOTIFY 계열 처리 // WM_ACTIVATE 처리 // WM_SETCURSOR 처리 43 Univ of Incheon, 고급프로그래밍

메시지 처리 흐름(10/11) u Def. Window. Proc CWnd: : On. Wnd. Msg에서는 메시지 핸들러가

메시지 처리 흐름(10/11) u Def. Window. Proc CWnd: : On. Wnd. Msg에서는 메시지 핸들러가 현재 클래스에 있으면 현재 클래스의 메시 지 핸들러를 호출하고 현재 클래스에 없으면 FALSE를 리턴해서 CWnd: : Window. Proc가 CWnd: : Def. Window. Proc를 호출하도록 되어 있다 LRESULT CWnd: : Window. Proc(UINT message, WPARAM w. Param, LPARAM l. Param) {. . . if (!On. Wnd. Msg(message, w. Param, l. Param, &l. Result)) l. Result = Def. Window. Proc(message, w. Param, l. Param); <--On. Wnd. Msg에서 FALSE가 리턴되면 여기. . . } 47 Univ of Incheon, 고급프로그래밍

메시지 처리 흐름(11/11) LRESULT CWnd: : Def. Window. Proc(UINT n. Msg, WPARAM w. Param,

메시지 처리 흐름(11/11) LRESULT CWnd: : Def. Window. Proc(UINT n. Msg, WPARAM w. Param, LPARAM l. Param) { if (m_pfn. Super != NULL) return : : Call. Window. Proc(m_pfn. Super, m_h. Wnd, n. Msg, w. Param, l. Param); WNDPROC pfn. Wnd. Proc; if ((pfn. Wnd. Proc = *Get. Super. Wnd. Proc. Addr()) == NULL) return : : Def. Window. Proc(m_h. Wnd, n. Msg, w. Param, l. Param); else return : : Call. Window. Proc(pfn. Wnd. Proc, m_h. Wnd, n. Msg, w. Param, l. Param); } m_pfn. Super은 창이 서브클래싱(subclassing)되어 있을 때 서브클래싱된 창의 윈도우 프로시저(WNDPROC)을 가리키는 함수 포인터이다. 즉, CWnd: : Def. Window. Proc은 창이 서브클래싱 된 경우 서브클래싱된 창의 윈도우 프로시저를 호출하고 서브클래싱 되지 않은 경우에는 : : Def. Window. Proc를 호출하여 default 방식으로 메시지를 처리하도록 하고 있다. 48 Univ of Incheon, 고급프로그래밍