Erstaunen: CMemDC ist Bestandteil der MFC!

Wer Double Buffering benötigt und die MFC nutzt, der kennt auch CMemDC. Vermutlich eine der meist genutzten und kopierten Klassen, die auf CodeProject und CodeGuru vorgestellt wurden.
http://www.codeproject.com/KB/GDI/flickerfree.aspx
http://www.codeguru.com/cpp/misc/misc/flickerfreedrawing/article.php/c389/Flicker-free-drawing-using-memory-DC.htm

Ich habe meine Erweiterung hier im Blog vorgestellt und die liegt normalerweise in einem separaten Namespace, wie alle meine Tool-Klassen.

Nicht schlecht staunte ich, als ich keinen Compilerfehler bekam obwohl ich CMemDC nutzte aber keinen Namespace angab. Siehe da: CMemDC hat in einer eigenen Implementierung den Weg in die MFC gefunden. Man findet sie in:
C:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\include\afxcontrolbarutil.h

Im Großen und Ganzen ist es die bekannte Standard-Implementierung, allerdings verfügt diese CMemDC Version auch Code, der auf Windows Vista und Windows 7, die fest im Betriebssystem verankerten Funktionen nutzt: BeginBufferedPaint, EndBufferedPaint
Siehe http://msdn.microsoft.com/en-us/library/bb773178(VS.85).aspx
Diese Funktionen werden innerhalb des Themeings von Windows Vista und Windows 7 verwendet und in dieser Funktionsgruppe ist auch Alphablending direkt verankert. (BufferedPaintSetAlpha). Ich vermute sogar, dass diese integrierten Klassen effektiver arbeiten, als die eigenen Klassen (ein Test steht noch aus), denn Windows weiß intern natürlich viel besser was wie zu puffern und zu zeichnen ist, als wir, wenn WM_PAINT aufgerufen wird.

Vielleicht ein guter Grund, die eigene CMemDC Klasse auch auf Vista/Windows 7 Funktionen zu erweitern oder die integrierte Klasse in der MFC zu verwenden.

Tipp: Übrigens hat die MFC CMemDC Klasse einen statischen Member, der es auf einfache Weise erlaubt das Double-Buffering abzuschalten (CMemDC:: m_bUseMemoryDC), dass ist besonders interessant beim Debuggen von grafischen Operationen, deren Ergebnisse man auch gleich sehen will, allerdings wird dieser Member nicht benutzt wenn das interne Windows Double-Buffering genutzt werden kann, schade eigentlich.

PS: Aber eigentlich muss man sich auch die Frage stellen, warum die Entwickler genau diesen Klassennamen verwendet haben, denn er provoziert ja auch direkt den Konflikt mit existierendem Code.

8 Gedanken zu „Erstaunen: CMemDC ist Bestandteil der MFC!“

  1. In VS 20008 ist die Klasse auch schon verfügbar, allerdings in afxglobals.h.

    In der Dokumentation wird noch gewarnt: „This class supports the MFC framework infrastructure and is not intended to be used directly from your code.“. Hat sich das in VS 2010 geändert?

    1. Korrekt ist, dass in VS-2008 SP1 (MFCNext), die Klasse schon drin war. Das habe ich übersehen.
      Aber auch dort war sie in afxcontrolbarutil.h deklariert. Nicht in afxglobals.h? Das kann ich nicht so nachvollziehen.
      Auch eine entsprechende Anmerkung kann ich so nicht sehen, wo steht dasim Code?

  2. CMemDC kam mit der BCG-Integration von VS 2008 SP1 in die MFC. In der BCG hieß sie CBCGPMemDC, dort gibt es sie auch schon seit vielen Jahren. In afxglobals.h taucht nur eine Friend-Deklaration auf.

    Die Anmerkung steht in der Hilfe zu CMemDC und nicht im Quellcode.

  3. Genau, in der Hilfe steht das. Dort wird auch die afxglobals.h erwähnt, die Klasse ist aber in afxcontrolbarutil.h, hatte das ungeprüft übernommen 🙂

    1. Diese Anmerkung (in der MSDN Doku für VS-2008 und VS-2010):

      This class supports the MFC framework infrastructure and is not intended to be used directly from your code.

      Ist IMHO absoluter Blödfug. Alles was sonst früher „intern“ in der MFC war, das war einfach auch nicht dokumentiert und damit implizit „intern“.

      Wenn diese Klasse intern ist, dann war die Entscheidung für den Namen CMemDC eine absolute Fehlentscheidung!

    1. Warum?
      Insgesamt unterstützen kann ich diese Behauptung nicht.
      Ich finde allerdings das:
      1. Es zu wenig samples gibt.
      2. Eskeine Walkthroughs für die Umstellung gibt
      3. Man dMFCNext isoliert als eigene DLL zur Standard MFC hätte ausliefern osllen. So wiedas die BCGLib ja auch einfach ist.

  4. Mit der Übernahme der BCG hielt plötzlich ein zweiter Programmierstil Einzug, der sich vom originalen MCF-Stil schon recht stark unterscheidet. Damit ist das „aus einem Guss“-Gefühl nicht mehr vorhanden.

    Punkt 3 ist auch das, was mich am meisten stört, weil man bei Nichtbenutzung der BCG viel unbenutzten Code mit ausliefert. Alleine die PNG-Ressourcen für die Office-Stile sind schon 1 MiB groß. Allerdings lässt sich die aktuelle MFC im Moment noch recht gut ohne BCG kompilieren. MS hat zwar ein paar Stolperstellen eingebaut (keine Makefiles, keine Auslieferung der .def-Dateien). Wenn man sich davon aber nicht abhalten lässt, wird man mit einer Core-MFC von 1.14 MiB belohnt. 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

This site uses Akismet to reduce spam. Learn how your comment data is processed.