【问题标题】:Win32 Common Controls initialization breaks custom controls?Win32 Common Controls 初始化会破坏自定义控件?
【发布时间】:2013-10-16 00:49:07
【问题描述】:

所以我正在尝试在 Win32 中初始化通用控件和视觉样式。我构建了一个包含我编写的一些自定义控件的 DLL,以及一个包含 GUI 应用程序的 EXE。

通常,责任分离似乎是我的 DLL 不应该担心我们是否启用窗口样式。它应该只生成自定义控件并将它们公开给依赖的 EXE。然后,EXE 可以决定是否需要视觉样式,而 DLL 则更明智。

问题是这样的:我的 DLL 在进程附加时在 DllMain 中注册了它的窗口类。但是如果我在 EXE 中调用 InitCommonControlsEx,我的自定义控件中的按钮和其他东西不会显示出来,因为自定义控件是在 EXE 初始化公共控件之前注册的。

为了证明这一点,我在名为 InitCommonControlsEx 的 EXE 之后强制取消注册和重新注册我的自定义控件,并且它修复了它:按钮显示在我的自定义控件上,具有视觉样式。 p>

在理想情况下,我希望能够在未来的程序中链接到我的共享库,并开始使用自定义控件,而不用担心修复常见控件和样式的问题。这可能吗?

【问题讨论】:

    标签: c windows winapi


    【解决方案1】:

    简短的回答是,您不打算在DllMain() 中注册窗口类或do much of anything

    您应该提供一个从 DLL 导出的单独的 Init() 函数,应用可以调用该函数来注册 DLL 的控件,就像它调用函数 (InitCommonControls()) 来注册公共控件一样。

    【讨论】:

    • AFAIK,在 DllMain 中使用 RegisterClass 没有问题
    • @manuell 您可能想查看 DllMain 的文档。 “调用需要 Kernel32.dll 以外的 DLL 的函数可能会导致难以诊断的问题。例如,调用 User、Shell 和 COM 函数可能会导致访问冲突错误,因为某些函数会加载其他系统组件。”
    • 是的,我知道,但请注意“一些功能”。我认为 RegisterClass 不在其中。
    • @manuell 实际上并没有说“某些功能”,而是说“功能 .. 除了 Kernel32.dll”。 RegisterClass 在 User32.dll 中
    • 你绝对不应该从 DllMain 调用 RegisterClass。您不应该从 DllMain 调用 User32.dll 中的任何内容。它可能有时甚至在您的测试中一直有效,但这并不保证它的安全性或意味着它在您尚未测试的某些情况下或在未来版本或 Windows 或加载不同的程序时不会出错DLL 等。 Init 函数是做事的正确方法,这就是 InitCommonControls 本身;它注册了一堆窗口类。
    猜你喜欢
    • 2019-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多