Determine COMCTL32 version

. You can also read a related article in MSDN at
http://www.microsoft.com/msdn/sdk/inetsdk/help/inet1560.htm

Here's what Roger had to say:

Just followed the link on that page to the MSDN Inet article about COMCTL32. It looks like a good way also of telling the version.

This article shows another method of testing - also I make use of a static so that the test only needs to be done once for efficiency.

The new windows common controls live in a system DLL called COMCTL32.DLL

The original Windows 95 included a version of COMCTL32.DLL which gave us most of the nice common control, like list views and tree controls.

With Internet Explorer 3, Microsoft introduced some new controls along with enhancements to the existing controls. These include features like flat toolbars, hover mode in list views, and new controls like the date picker.

Internet Explorer 4 adds support for new flat scroll bars. However, it also changes the behaviour of the toolbar control and makes existing MFC applications display toolbars incorrectly (because MFC CToolBar has hardcoded numbers for the size of seperators - but that is another story :-).

In order for your application to work with these different version, and to take advantage of the new features if they are available, one needs to be able to detect the version of COMCTL32 you are using.

The following addition to your CWinApp class will give you this ability.

Step 1:

In your application .h file add the following just before the definition of your CWinApp-derived application class...
enum COMCTL32VERSION {
     COMCTL32_UNKNOWN, COMCTL32_400, COMCTL32_470, COMCTL32_471
};

This enumeration has values for the origina Win95 COMCTL32 (v4), the IE3 COMCTL32 (v4.7) and the IE4 COMCTL32 (v4.71)

Step 2:

Add the following to your CWinApp-derived class in your application .h file...
class CMyWinApp : public CWinApp {
     ...
     // COMCTL32 detection
private:
     static COMCTL32VERSION c_nComCtl32Version;
public:
     static COMCTL32VERSION ComCtl32Version();
     ...
};

Step 3:

Add the following to your application .cpp file...
COMCTL32VERSION CMyWinApp::c_nComCtl32Version = COMCTL32_UNKNOWN;

COMCTL32VERSION CMyWinApp::ComCtl32Version() {
     // if we don't already know which version, try to find out
     if (c_nComCtl32Version == COMCTL32_UNKNOWN) {
          // have we loaded COMCTL32 yet?
          HMODULE theModule = ::GetModuleHandle("COMCTL32");
          // if so, then we can check for the version
          if (theModule) {
               // InitCommonControlsEx is unique to 4.7 and later
               FARPROC theProc = ::GetProcAddress(theModule, "InitCommonControlsEx");
               if (! theProc) {
                    // not found, must be 4.00
                    c_nComCtl32Version = COMCTL32_400;
               } else {
                    // The following symbol are unique to 4.71
                    //   DllInstall
                    //   FlatSB_EnableScrollBar FlatSB_GetScrollInfo FlatSB_GetScrollPos
                    //   FlatSB_GetScrollProp FlatSB_GetScrollRange FlatSB_SetScrollInfo
                    //   FlatSB_SetScrollPos FlatSB_SetScrollProp FlatSB_SetScrollRange
                    //   FlatSB_ShowScrollBar
                    //   _DrawIndirectImageList _DuplicateImageList
                    //   InitializeFlatSB
                    //   UninitializeFlatSB
                    // we could check for any of these - I chose DllInstall
                    FARPROC theProc = ::GetProcAddress(theModule, "DllInstall");
                    if (! theProc) {
                         // not found, must be 4.70
                         c_nComCtl32Version = COMCTL32_470;
                    } else {
                         // found, must be 4.71
                         c_nComCtl32Version = COMCTL32_471;
                    }
               }
          }
     }
     return c_nComCtl32Version;
}

This function gets a handle to COMCTL32 and then looks for what functions exist within it. By looking for functions which are known NOT to be in a given version (and only in later versions), we can tell what version we actually have.

By using a static to keep the result, we do not need to keep redoing the detection logic, as once we know, the COMCTL32 cannot change from underneath us - it will stay loaded until our application terminates.

Step 4:

When using a feature that relies on a given version, you can use code like
     if (CMyWinApp::ComCtl32Version() > COMCTL_400) {
          // use a feature only in IE3 version or later
          // like flat tool bars
     }

Of course, what I do is have my own standard enhanced CWinApp-derived class which has these additions (and others) in it. The I derive each application from this enhanced class.