Wieder mal ein netter Bug in der MFC (VC-2003 Vers. 7.1 und VC-2005 Vers. 8.0).
Platziert man ein CFormView in einem CSplitterWnd dann werden trotz sichtbarer Rollbalken, alle Mouse Wheel Nachrichten geschluckt und ignoriert.
Nachvollziehen kann man das einfach:
- SDI Applikation im Explorer Stil erzeugen
- Rechtes Fenster als CFormView
- Anwendung so klein machen, dass im CFromView ein vertikaler Rollbalken erscheint.
- Nun versuchen mit dem Mausrad zu rollen.
- No chance…
Ursache ist der folgende Code in CScrollView:
BOOL CScrollView::OnMouseWheel(UINT fFlags, short zDelta, CPoint point)
{
// we don’t handle anything but scrolling
if (fFlags & (MK_SHIFT | MK_CONTROL))
return FALSE;
// if the parent is a splitter, it will handle the message
if (GetParentSplitter(this, TRUE))
return FALSE;
// we can’t get out of it–perform the scroll ourselves
return DoMouseWheel(fFlags, zDelta, point);
}
Wie man unschwer sieht wird bei einem Parent, dass ein CSplitterWnd ist, die Nachricht immer ignoriert. Korrekt wäre dies nur, wenn der Scrollbar nicht dem CScrollView gehört sondern dem CSplitterWnd. Das ist aber bei einem Konstrukt wie hier selten.
Workarround ist relativ simpel!
Einfach selber einen eigenen OnMouseWheel Handler erzeugen, der so aussieht:
BOOL CMyFromView::OnMouseWheel(UINT fFlags, short zDelta, CPoint point)
{
// we don’t handle anything but scrolling
if (fFlags & (MK_SHIFT | MK_CONTROL))
return FALSE;
// we can’t get out of it–perform the scroll ourselves
return DoMouseWheel(fFlags, zDelta, point);
}
Hier der Report in connect!
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=276053
❗ PS: Das Problem tritt natürlich auch in anderen Klassen auf die von CScrollView abgeleitet werden!
Hier ein sample Code mit dem entsprechenden Workarround:
http://blog.m-ri.de/wp-content/uploads/2007/05/mousewheel.zip