MFC 에서 다수개의 뷰 윈도우가 사용될 때 특정 뷰에서는 WM_MOUSEWHEEL 메시지를 받지 못하는 경우가 있었는데, 아래의 코드를 사용하여 처리할 수가 있었다. 아래의 코드는 xxxApp 클래스의 Pretrans 함수이며 이 안에서 WM_MOUSEWHEEL 메시지의 발생을 인지하고 해당 뷰 윈도우로 다시 메시지를 보내주는 내용이다. 대상 뷰 윈도우에서는 OnMouseHWheel() 가상함수를 오버라이드해야 여기서 전달하는 메시지에 반응할 수 있다.
BOOL CXPACSViewerApp::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message==WM_MOUSEWHEEL)
{
CPoint point;
GetCursorPos (&point);
HWND hWnd = ::WindowFromPoint (point);
CWnd* ptrImageWnd = (ImageWnd*)(AfxGetMainWnd()->GetActiveWindow());
if(hWnd==ptrImageWnd->m_hWnd)
{
ptrImageWnd->SendMessage(WM_MOUSEHWHEEL, pMsg->wParam, pMsg->lParam);
return TRUE;
}
}
return CWinAppEx::PreTranslateMessage(pMsg);
}
위의 방법으로도 성공했지만 위의 코드는 동적으로 형변환하는 과정에서 해당 클래스가 아닐 경우도 있으므로 오류가 발생할 수도 있을 것이다. 그러므로 다음과 같이 하는 것이 더 안전한 방법일 것이다. 동적 캐스팅이 필요한 경우이므로 아래처럼 dynamic_cast<>() 를 사용하여 형변환하는 것이 좋겠다.
BOOL CXPACSViewerApp::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message==WM_MOUSEWHEEL)
{
CPoint point;
GetCursorPos (&point);
HWND hWnd = ::WindowFromPoint (point);
CWnd* ptrWnd = AfxGetMainWnd()->GetActiveWindow();
// 위에서 리턴된 윈도우 포인터를 특정 클래스 형으로 동적 형변환핧 때 오류없이 안전하게 처리하는 방법
ImageWnd* ptrImageWnd = dynamic_cast<ImageWnd*>(ptrWnd); //동적형변환이 안되면 NULL을 리턴하므로 안전하다
if(ptrImageWnd != NULL)
{
ptrImageWnd->SendMessage(WM_MOUSEHWHEEL, pMsg->wParam, pMsg->lParam);
return TRUE;
}
}
return CWinAppEx::PreTranslateMessage(pMsg);
}
대상 뷰 윈도우의OnMouseHWheel() 함수
void ImageWnd::OnMouseHWheel(UINT nFlags, short zDelta, CPoint pt)
{
// This feature requires Windows Vista or greater.
// The symbol _WIN32_WINNT must be >= 0x0600.
// TODO: Add your message handler code here and/or call default
AfxMessageBox(_T("ImageWnd::OnMouseHWheel() WM_MOUSEWHEEL"));
CFrameWnd::OnMouseHWheel(nFlags, zDelta, pt);
}