Die Funktion CImageList::DrawIndirect der MFC-10
BOOL CImageList::DrawIndirect(CDC* pDC, int nImage, POINT pt, SIZE sz,
POINT ptOrigin, UINT fStyle = ILD_NORMAL, DWORD dwRop = SRCCOPY,
COLORREF rgbBack = CLR_DEFAULT, COLORREF rgbFore = CLR_DEFAULT,
DWORD fState = ILS_NORMAL, DWORD Frame = 0,
COLORREF crEffect = CLR_DEFAULT);
hat einen massiven Bug: Sie funktioniert einfach nicht.
Der Unsinn, der sich eingeschlichen hat, liegt in der überschriebenen Funktion
BOOL CImageList::DrawIndirect(IMAGELISTDRAWPARAMS* pimldp);
die durch die oben genannte Variante aufgerufen wird. Denn hier cbSize von IMAGELISTDRAWPARAMS nicht mehr in allen Fällen auf einen korrekten Wert gesetzt. Die Folge cbSize enthält Garbage und der Aufruf von ImageList_DrawIndirect geht in die Hose!
Sowohl in VC-2005 als auch VC-2008 wurde in dieser Funktion explizit der cbSize Member überschrieben, je nach dem ob ComCtl 6.0 oder höher von der Anwendung benutzt wird.
Auch das ist ein Bug, denn hierdurch wird evtl. ein korrekt gesetzter cbSize Wert mit IMAGELISTDRAWPARAMS_V3_SIZE (pre IE 5.01 d.h. _WIN32_IE < 0x0501) überschrieben und damit vergrößert vergrößert. Dadurch kann es zu Zugriffsfehlern kommen oder zu unerwünschten Seiteneffekten.
(siehe https://connect.microsoft.com/VisualStudio/feedback/details/322713/bug-in-cimagelist-drawindirect)
Also haben die Entwickler scheinbar die Zuweisung von pimldp->cbSize = sizeof(IMAGELISTDRAWPARAMS) entfernt! Allerdings haben Sie dabei vergessen in der anderen Funktion nun cbSize korrekt zu initialisieren!
Wir haben also wieder mal einen Fall von: Let us fix one thing and break others…
Das Gemeine an der Sache ist, dass dieser Bug noch vor RTM bekannt war:
https://connect.microsoft.com/VisualStudio/feedback/details/543108/bug-in-cimagelist-drawindirect
Nur ist er nicht mehr gefixed worden!
PS: Natürlich fährt die eigene Software mit der MFC-10 auch gegen die Wand, wenn man die CImageList::DrawIndirect(IMAGELISTDRAWPARAMS* pimldp) Variante verwendet und selbst cbSize nicht initialisiert, was ein ordentlicher Entwickler aber sicherlich nicht vergisst! 😉
Wem es möglich ist, sollte bei den beiden Connect Einträgen Abstimmen und diesen Bug als wichtig kennzeichnen!
Danke für den Bericht! Ich werde meinen Code gleich mal auf die Verwendung von CImageList::DrawIndirect abklopfen.
Übrigends habe ich diesen Bug auch per Support-Anfrage an MS eingereicht!