My blog
My LinkedIn Profile

BOOKS i'm reading

Napoleon Hill Keys to Success: The 17 Principles of Personal Achievement, Napoleon Hill, ISBN: 978-0452272811
The 4-Hour Workweek: Escape 9-5, Live Anywhere, and Join the New Rich (Expanded and Updated), Timothy Ferriss, ISBN: 978-0307465351
The Fountainhead, Ayn Rand, ISBN: 0452273331

Alternative to MFC for GDI programming

Olivier Langlois, IT superstar coach, Dominate LinkedIn Formula author
by Olivier Langlois

C++ MFC alternative for GDI programming demo program



I got the idea of developing this project after I started to study MFC GDI related classes. I saw a lot of code for features that I have never used. From there, I wanted to perform an experiment where I could verify if by using a stripped down version of GDI classes, it would translate to a better painting performance. As you will see in the conclusion, I did not obtain the results I was hoping for, and I hesitated to write a C++ Windows programming tutorial about the code I wrote. I concluded that if a fellow programmer was looking for an OO GDI encapsulation in a non MFC project, this code could be useful to him. In this C++ Windows programming tutorial, I will first describe what I did not like in MFC code, highlight the important points of the new class set, present the demo program, and conclude by presenting the result of the experiment.

MFC features for GDI classes not so useful

CDC::m_hAttribDC is one of these features. Most of the time m_hAttribDC == m_hDC and the presence of m_hAttribDC just add superfluous overhead all over CDC code. Here is an example:

CPoint CDC::MoveTo(int x, int y)
    ASSERT(m_hDC != NULL);
    CPoint point;

    if (m_hDC != m_hAttribDC)
        VERIFY(::MoveToEx(m_hDC, x, y, &point));
    if (m_hAttribDC != NULL)
        VERIFY(::MoveToEx(m_hAttribDC, x, y, &point));
    return point;

Also, related to m_hAttribDC, the class CMetafileDC is flawed. It forces its users to explicitly set m_hAttribDC, and CMetafileDC forbids you to set m_hAttribDC to m_hDC, but this is wrong! It should work because the first parameter of CreateEnhanced() is:

  • pDCRef - Identifies a reference device for the enhanced metafile.

When it is NULL, the reference device will be the display. The reason why MFC ignores pDCRef and sets m_hAttribDC to NULL is probably because CMetaFileDC also supports the old Windows 1.0 metafile format and these metafiles have no notion of reference devices. Most of the functions overridden in CMetaFileDC from CDC are virtual, and in almost all cases, it was done like that only to enforce the flawed rule that a metafile attribute DC should not equal the output DC. Hence, virtual function calls overhead is applied to all CDC objects for nothing.

And finally, the last source of overhead in MFC GDI classes is the handle maps. Handle maps are essential for window objects but I still have to see a situation with GDI objects where the handle maps are crucial. Handle maps are invoked when the functions Attach(), Detach(), and FromHandle() are called. You could think that if you are not calling these functions then you are not using them, right? Well, this is wrong. Every time an object is selected in a CDC object, the object pointer returned by the SelectObject() function comes from CGdiObject::FromHandle(). To get an idea of the magnitude of this source of overhead, consider the pseudocode for CGdiObject::FromHandle():

  • Try to find the requested handle in the permanent object map.
  • If not found, try to find the requested handle in the temporary object map.
  • If not found, create a temporary object.

All these temporary objects will then be deleted the next time the MFC framework enters its idle function.

Page 1 2 3

Home :: Fractals :: Tutorials :: Books :: My blog :: My LinkedIn Profile :: Contact