原文链接:https://devblogs.microsoft.com/oldnewthing/20050718-16/?p=34913
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.
初学者学习使用系统外壳通用控件时,经常遇到的其中一个问题是忘记调用 InitCommonControls 方法。不过,如果对 InitCommonControls 方法反编译一下的话,你会发现它像 FlushInstructionCache 一样,事实上什么事情也没做。
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.
就像 FlushInstructionCache 一样,重点不在它做了什么,而在于你调用了它这件事上。
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.
回想一下,只是将某个库文件列在你的依赖列表里,并不意味着你的程序就与对应的DLL绑定了。你得调用这个DLL中的某个方法,才能保证其入口点的存在,而 InitCommonControls 做的就是这件事。
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.
没有对 InitCommonControls 的调用,要使用系统外壳通用控件库的程序,其导入表中就不存在对 COMCTL32.DLL 的引用,这就意味着当程序加载时,COMCTL32.DLL 并没有被加载,因此也没有被初始化,也就意味着没有注册其窗口类,最终意味着当你调用 CreateWindow 时会失败,因为窗口类尚未被注册。
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.)
(当然了,后来还有个 InitCommonControlsEx 允许你指定要注册哪些类。当 COMCTL32.DLL 加载时,只有传统的 Windows 95 类是默认注册的,要想用到其它的类,你必须进行明确的指定。)
远嚣 Comment