If InitCommonControls doesn’t do anything, why do you have to call it?

One of the problems beginners run into when they start using shell common controls is that they forget to call the InitCommonControls function. But if you were to disassemble the InitCommonControls function itself, you'll see that it, like the FlushInstructionCache function, doesn't actually do anything.

Then why do you need to call it?

As with FlushInstructionCache, what's important is not what it performs, but just the fact that you called it.

Recall that merely listing a lib file in your dependencies doesn't actually cause your program to be bound to the corresponding DLL. You have to call a function in that DLL in order for there to be an import entry for that DLL. And InitCommonControls is that function.

Without the InitCommonControls function, a program that wants to use the shell common controls library would otherwise have no reference to COMCTL32.DLL in its import table. This means that when the program loads, COMCTL32.DLL is not loaded and therefore is not initialized. Which means that it doesn't register its window classes. Which means that your call to the CreateWindow function fails because the window class has not been registered.

That's why you have to call a function that does nothing. It's for your own good.

(Of course, there's the new InitCommonControlsEx function that lets you specify which classes you would like to be registered. Only the classic Windows 95 classes are registered when COMCTL32.DLL loads. For everything else you have to ask for it explicitly.)

Comments (13)
  1. Steven says:

    If I understand correctly, then this implies that even if I have the call to InitCommonControls in a code block that is never executed (but not optimised away by the compiler) or if I use the common controls before calling ICC (by, say, putting it at the end of WinMain), it should still work?

  2. Jack Mathews says:

    … until it doesn’t.

  3. quest says:

    "Only the classic Windows 95 classes are registered when COMCTL32.DLL loads."

    Why isn’t this fact documented?

  4. Because you shouldn’t be relying on it. Just call InitCommonControlsEx like the documentation says.

  5. Seth McCarus says:

    So when are the Win95 classes registered? In DllMain?

    That would mean that the standard classes are always registered, and the non-Win95 ones get registered only when ICCEx() is called. And that comctl32.dll broke the DllMain rules.

    Steven, experiment seems to show that you’re correct. Interesting!

  6. Steven says:

    Thanks Seth. That explains why I had some trouble creating window classes with names colliding with the COMCTL32.DLL ones even when I didn’t actually call ICC. The only way around that was skip to using LoadLibrary.

  7. Mihai says:

    For quest:

    InitCommonControls doc:

    "This function is obsolete. New applications should use the InitCommonControlsEx function."

    InitCommonControlsEx doc:

    "Registers specific common control classes from the common control dynamic-link library (DLL)."


    Is logical. At the time when InitCommonControls was created and documented, it did load all available (at that time) control window classes.

    But if you read the documentation of InitCommonControls, you know is obsolete and you should not use it.

  8. PatriotB says:

    According to Mike Dimmick (http://mikedimmick.blogspot.com/2004/07/changes-to-win32-api-in-longhorn_11.html) there’s a Histogram control coming in Longhorn’s common controls. (Like the Task Manager CPU usage I’d assume?)

    I hope that this ends up being true–Despite Microsoft’s shifting emphasis to WinFX/Avalon, there is still a good use for classic Win32 controls provided by the OS.

  9. quest says:

    Hmmm, but in my opinion if someone who does not know this and reads the documentation for InitCommonControls:

    "Registers and initializes the common control window classes."

    One would normally think that it registers *all* available common control window classes.

  10. Ryan Phelps says:

    Why was "Ex" chosen as the extension for a new version of a function call? Why not "2nd" or "_2"? What happens when there’s a third version? "ExEx"? I presume there’s some bit of interesting history here that *someone* must know.

  11. quest says:

    Yeah but, there is only written that you *should* use the InitCommonControlsEx function. But there is no word that this is a *must* for window classes other than the Windows 95 classes.

    I think there is missing a sentence about it in the documentation, but don’t lets discuss too much on it. ;-)

    Ryan: No need for an InitCommonControlsExEx, the INITCOMMONCONTROLSEX structure has a size field, that means Microsoft can extend the structure if the functions needs more parameters.

  12. oshah says:

    Because one day, it may very well end up doing something?

Comments are closed.

Skip to main content