{"id":662,"date":"2010-08-28T10:36:27","date_gmt":"2010-08-28T09:36:27","guid":{"rendered":"http:\/\/blog.m-ri.de\/?p=662"},"modified":"2010-08-27T11:17:39","modified_gmt":"2010-08-27T10:17:39","slug":"bug-vc-2010-cformview-zeichnet-buttons-beim-rollen-falsch-es-erscheinen-schwarze-bloecke","status":"publish","type":"post","link":"http:\/\/blog.m-ri.de\/index.php\/2010\/08\/28\/bug-vc-2010-cformview-zeichnet-buttons-beim-rollen-falsch-es-erscheinen-schwarze-bloecke\/","title":{"rendered":"Bug: VC-2010 MFC CFormView zeichnet Buttons beim Rollen falsch, es erscheinen schwarze Bl\u00f6cke"},"content":{"rendered":"<p>In der <em>MFC 10.0 <\/em>hat sich ein Bug eingeschlichen, der sich unter <em>Windows Vista <\/em>und <em>Windows 7\u00a0 <\/em>bemerkbar macht. Unter Windows XP tritt der Fehler nicht auf. Das Problem tritt in jedem Stil auf, der <em>DWM<\/em> verwendet. D.h. nicht wenn Windows klassisch ausgew\u00e4hlt wird.<\/p>\n<p>Wenn auf einen <em>CFormView<\/em> mehrere Buttons liegen und der <em>CFormView<\/em> gerollt wird, dann kommt es unter Umst\u00e4nden zu Fehlern beim Neuzeichnen von Buttons. Dies schlie\u00dft alle Button-Formen ein: <em>Check-Buttons<\/em>, <em>Radio-Buttons <\/em>und normale <em>Buttons<\/em>.<\/p>\n<p>Das Ganze sieht nach dem Rollen in etwa so aus:<br \/>\n<a href=\"http:\/\/blog.m-ri.de\/wp-content\/uploads\/2010\/08\/CScrollView.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-663\" title=\"CScrollView Bug\" src=\"http:\/\/blog.m-ri.de\/wp-content\/uploads\/2010\/08\/CScrollView.png\" alt=\"\" width=\"319\" height=\"110\" srcset=\"http:\/\/blog.m-ri.de\/wp-content\/uploads\/2010\/08\/CScrollView.png 319w, http:\/\/blog.m-ri.de\/wp-content\/uploads\/2010\/08\/CScrollView-300x103.png 300w\" sizes=\"auto, (max-width: 319px) 85vw, 319px\" \/><\/a><\/p>\n<p>Der Text einiger Buttons erscheint nach dem Rollen als schwarze Bl\u00f6cke. Es kann auch vorkommen, dass nur Teile der Buttons falsch gezeichnet werden.<\/p>\n<p>Um das Problem gezielt nachzuvollziehen habe ich ein kleines Sample gebaut. Man kann durch zwei Schalter den CScrollView gezielt nach oben oder unten Rollen. Beim Rollen nach unten und bei bestimmten Fenstergr\u00f6\u00dfen tritt dann der Fehler auf. Ich habe das Main-Window entsprechend beim Start in der Gr\u00f6\u00dfe angepasst.<\/p>\n<p>Das Problem liegt in einer Implementierung von <em>WM_PRINTCLIENT <\/em>in <em>CScrollView (CScrollView::OnPrintClient)<\/em>, die ein Double-Buffering verwendet, dass entweder falsch ist oder sich eben mit der Standardimplementierung eines Dialoges bei\u00dft. Auf den ersten und zweiten Blick konnte ich in der Implementierung selbst keinen Fehler sehen. Deshalb vermute ich, dass sich dieses Double-Buffering mit dem auch vorhandenen Double-Buffering in den Standardimplementierungen der Dialogklasse bei\u00dft bzw. nicht korrekt ber\u00fccksichtigt, dass auch Child-Windows neu gezeichnet werden m\u00fcssen.<\/p>\n<p>Die L\u00f6sung ist entsprechend einfach:<\/p>\n<ul>\n<li>Man f\u00fcgt einfach einen Handler f\u00fcr <em>WM_PRINTCLIENT <\/em>in seiner von <em>CFormView<\/em> abgeleiteten Klasse ein.<\/li>\n<li>Dieser Handler ruft dann nicht die Implementierung der Basisklasse <em>CFormView<\/em> auf, sondern die Implementierung in <em>CView<\/em> (<em>CView::OnPrintClient<\/em>).<\/li>\n<\/ul>\n<pre lang=\"cpp\">...\r\nON_MESSAGE(WM_PRINTCLIENT,&amp;CScrollDialogMFCView::OnPrintClient)\r\n...\r\n\r\nLRESULT CScrollDialogMFCView::OnPrintClient( WPARAM wp, LPARAM lp )\r\n{\r\n  \/\/ Bypass the CScrollView::OnPrintClient implementation\r\n  return CView::OnPrintClient(wp,lp);\r\n}<\/pre>\n<p>Dieser Fehler ist in keiner der vorhergehenden MFC Versionen vorhanden (auch nicht in <em>MFCNext<\/em>), weil einfach kein entsprechender Handler vorhanden war..<\/p>\n<p>Es stellt sich wohl bei einigen jetzt die Frage warum dieser Handler eingebaut wurde. Auch die Antwort ist einfach:<br \/>\nSeit <em>Windows Vista<\/em> wird stark von <em>AnimateWindow<\/em> Gebrauch gemacht und auch <em>DWM<\/em> intern scheint des \u00f6fteren <em>WM_PRINT<\/em>\/<em>WM_PRINTCLIENT<\/em> zu verwenden. Entsprechend haben fast alle Klassen in der <em>MFC<\/em> entsprechende Handler erg\u00e4nzt bekommen.<\/p>\n<p>Das Sample kann man hier herunterladen: <a href=\"http:\/\/blog.m-ri.de\/wp-content\/uploads\/2010\/08\/ScrollDialogMFC-VS-2010.zip\">ScrollDialogMFC &#8211; VS-2010<\/a>.<br \/>\nIch habe in der stdafx.h einen define\u00a0<em>FIX_CSCROLLVIEW_PROBLEM<\/em> eingebaut mit dem man den Fix einfach aktivieren und deaktivieren kann.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In der MFC 10.0 hat sich ein Bug eingeschlichen, der sich unter Windows Vista und Windows 7\u00a0 bemerkbar macht. Unter Windows XP tritt der Fehler nicht auf. Das Problem tritt in jedem Stil auf, der DWM verwendet. D.h. nicht wenn Windows klassisch ausgew\u00e4hlt wird. Wenn auf einen CFormView mehrere Buttons liegen und der CFormView gerollt &hellip; <a href=\"http:\/\/blog.m-ri.de\/index.php\/2010\/08\/28\/bug-vc-2010-cformview-zeichnet-buttons-beim-rollen-falsch-es-erscheinen-schwarze-bloecke\/\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eBug: VC-2010 MFC CFormView zeichnet Buttons beim Rollen falsch, es erscheinen schwarze Bl\u00f6cke\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[30,4,3,17,172,2],"tags":[99,352,244,358,171,186],"class_list":["post-662","post","type-post","status-publish","format-standard","hentry","category-c","category-mfc","category-programmieren","category-vista-2","category-vs2010","category-windows-api","tag-bug","tag-mfc","tag-mfc-next","tag-vista","tag-vs-2010","tag-windows-7"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/662","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/comments?post=662"}],"version-history":[{"count":1,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/662\/revisions"}],"predecessor-version":[{"id":665,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/662\/revisions\/665"}],"wp:attachment":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/media?parent=662"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/categories?post=662"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/tags?post=662"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}