표준 Windows 메시지(WM_)에 대한 기본 처리기는 클래스 CWnd
에 미리 정의되어 있습니다. 클래스 라이브러리는 메시지 이름에 이러한 처리기의 이름을 기반으로 합니다. 예를 들어 WM_PAINT 메시지에 대한 처리기는 다음과 같이 선언됩니다.CWnd
afx_msg void OnPaint();
afx_msg 키워드는 처리기를 다른 virtual
멤버 함수와 구분하여 C++ CWnd
키워드의 효과를 제안합니다. 그러나 이러한 함수는 실제로 가상이 아닙니다. 대신 메시지 맵을 통해 구현됩니다. 메시지 맵은 C++ 언어에 대한 확장이 아닌 표준 전처리기 매크로에만 의존합니다.
afx_msg 키워드는 전처리 후 공백으로 확인됩니다.
기본 클래스에 정의된 처리기를 재정의하려면 파생 클래스에서 동일한 프로토타입을 사용하여 함수를 정의하고 처리기에 대한 메시지 맵 항목을 만들기만 하면 됩니다. "당신의 처리기는 해당 클래스의 기본 클래스들에 있는 같은 이름의 처리기를 '재정의'합니다."
어떤 경우에는 기본 클래스와 Windows가 메시지를 처리할 수 있도록 기본 클래스에서 재정의된 핸들러를 호출해야 합니다. 재정의에서 기본 클래스 처리기를 호출하는 위치는 상황에 따라 달라집니다. 경우에 따라 기본 클래스 처리기를 먼저 호출해야 하고 경우에 따라 마지막 처리기를 호출해야 합니다. 메시지를 직접 처리하지 않도록 선택하는 경우 조건부로 기본 클래스 처리기를 호출하는 경우가 있습니다. 기본 클래스 처리기를 호출한 다음 기본 클래스 처리기에서 반환된 값 또는 상태에 따라 조건부로 고유한 처리기 코드를 실행해야 하는 경우가 있습니다.
주의
기본 클래스 처리기에 전달하려는 경우 처리기에 전달된 인수를 수정하는 것은 안전하지 않습니다. 예를 들어 처리기의 nChar 인수 OnChar
를 수정하려고 할 수 있습니다(예: 대문자로 변환). 이 동작은 매우 모호하지만 이 효과를 수행해야 하는 경우 멤버 함수 CWnd
를 SendMessage
대신 사용합니다.
클래스 마법사가 지정된 메시지에 대한 처리기 함수의 기본 구조(예: OnCreate
처리기)를 작성할 때 지정된 메시지를 재정의하는 적절한 방법을 어떻게 결정하나요? 이 함수는 권장 재정의된 멤버 함수의 형태로 스케치됩니다. 다음 예제에서는 처리기가 먼저 기본 클래스 처리기를 호출하고 -1을 반환하지 않는 조건에서만 진행하는 것이 좋습니다.
int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFormView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
return 0;
}
규칙에 따라 이러한 처리기의 이름은 접두사 "On"으로 시작합니다. 이러한 처리기 중 일부는 인수를 사용하지 않지만 다른 처리기는 몇 가지 인수를 사용합니다. 일부는 void
외의 반환 유형을 가지고 있습니다. 모든 WM_ 메시지에 대한 기본 처리기는 이름이 "On"으로 시작하는 클래스 의 멤버 함수로 CWnd
에 문서화됩니다. 멤버 함수 선언의 CWnd
접두사는 afx_msg.