사용자 정의 메시지 처리기 사용하기
사용자가 정의한 메시지를 수신할 수 있는 윈도우는 크게 2가지가 있다.
1. CWnd 의 파생 클래스
2. CWinThread의 파생 클래스 : 사용자 인터페이스 클래스(User Interface Class)
즉, 윈도우를 출력하는 클래스가 사용자 정의 메시지를 받을 수 있다.
MFC의 계층 구조도 모르고 Document 에서 사용자 정의 메시지 처리기를 만들면 아마 다음과
같은 에러 메시지를 볼 수 있을 것이다.
LRESULT (__thiscall CWnd::* )(WPARAM,LPARAM)'(으)로 변환할 수 없습니다
인터넷을 뒤지면 아마 사용자 정의 메시지 처리기의 리턴값을 LRESULT 로 바꾸면 해결 된다고
하는 글이 가장 많은데 아마 그렇게 변경해 주어도 안되면 CWnd나 CWinThread의 파생 클래스
가 아닌 곳에서 구현하려 해서 에러가 나는 경우일 것이다.
CMainFrame 나 CView의 파생 클래스 에서 사용자 정의 메시지 처리기를 만들어 주자
위에서 언급한 사용자 정의 메시지 처리기 함수 리턴값에 대한 에러는
VC6.0 에서 .Net 이상의 컴파일러 사용시 나타나는 문제이다.
.Net 이상부터 MFC 에서는 메시지 처리기의 반환 형식 및 매개변수 형식을 보다 엄격하게
검사한다. 이로써 안전하지 않은 메시지 처리기를 오류 메시지로 플래그를 지정하여 발생할 수
있는 문제를 개발자에게 알린다.
MFC 에서 ON_MESSAGE, ON_REGISTERED_MESSAGE, ON_THREAD_MESSAGE,
ON_REGISTERED_THREAD_MESSAGE 에 대해 정적 캐시팅을 사용한다.
VC6.0 에서 ON_MESSAGE 또는 ON_REGISTERED_MESSAGE 에 대해 메시지 처리기 함수가
void 값을 리턴하였을 경우 .Net 이상에서는 컴파일 에러를 일으킨다.
즉, 메시지 처리기는 LRESULT 를 리턴해야 한다.
# CWnd 파생 클래스 에서 사용자 정의 메시지 처리기 사용
1. 사용자 정의 메시지 정의
const UINT UM_READ_RESULT = WM_USER + 1;
2. 메시지 맵에 메시지 함수 Overriding
- 구현파일 (*.cpp)
BEGIN_MESSAGE_MAP(CReadProgressThread, CWinThread)
ON_MESSAGE(UM_PROGRESS_SET, OnSetProgress)
END_MESSAGE_MAP()
…
LRESULT CProgressThread::OnSetProgress(WPARAM _wParam, LPARAM _lParam)
{
...
}
UM_PROGRESS_SET 사용자 정의 메시지를 OnSetProgress 함수와 연결
수신 프로그램에 메시지가 도착 하므로 해당하는 메시지 핸들러가 수행 되도록
메시지 핸들러를 오버라이딩
※ Message Map
- 메시지와 메시지 핸들러(함수) 를 연결하는 역할
3. 사용자 정의 메시지 함수 작성
- 헤더파일 (*.h)
protected:
afx_msg LRESULT OnSetProgress(WPARAM _wParam, LPARAM _lParam);
DECLARE_MESSAGE_MAP()
# CWinThread 파생 클래스 에서 사용자 정의 메시지 처리기 사용
- 사용자 인터페이스 스레드 즉, CWinThread의 파생클래스가 사용자 정의 메시지를 수신 하는
경우는 Message Map을 연결하는 부분과 메시지 핸들러 원형만 다르다.
1. 사용자 정의 메시지 정의
const UINT UM_READ_RESULT = WM_USER + 1;
2. 메시지 맵에 메시지 함수 Overriding
- 구현파일 (*.cpp)
BEGIN_MESSAGE_MAP(CReadProgressThread, CWinThread)
ON_THREAD_MESSAGE(UM_PROGRESS_SET, OnSetProgress)
END_MESSAGE_MAP()
void CProgressThread::OnSetProgress(WPARAM _wParam, LPARAM _lParam)
{
...
}
3. 사용자 정의 메시지 함수 작성
- 헤더파일 (*.h)
protected:
afx_msg void OnSetProgress(WPARAM _wParam, LPARAM _lParam);
DECLARE_MESSAGE_MAP()
Update 09.01.22
오늘 사용자 정의 메시지를 사용할 일이 있어서 구현 하는데 잘 안되더라...
정리한 것을 다시 읽고 구현했는데 또 안되더라 -_-;;;
가장 앞줄에 써 있는 "CWnd 의 파생 클래스" 를 그냥 읽고 지나쳐 버려서....
Visual Studio 의 경고, 에러 메시지 역시 자세히 봐야 겠다는 것을 느꼈다.
뭐 하나 그냥 지나칠게 없다는것을 느꼈다.
아무튼! 문제에 대한 접근방법!! 기억하자.