我正在使用带有UI组件的dll,根据MSDN文档,我们需要显式注销在dll中注册的窗口类。 (与在非dll进程中注册时,系统会自动将其注销)不同。
现在的问题是,在DLL_PROCESS_DETACH
函数的DllMain
消息中,我们可以知道进程何时卸载dll或它是否终止,但是如何确定dll是否即将从内存中完全卸载?
因为在每个进程分离中取消注册窗口类的时间都不合适,因为其他窗口可能仍在使用注册的类。
一旦没有其他进程在“使用”该dll,我想注销所有类。似乎是执行此操作的正确时间。
这是我现在注销所有课程的方式:
BOOL APIENTRY DllMain(
HMODULE hModule,
DWORD ul_reason_for_call,
[[maybe_unused]] LPVOID lpReserved) noexcept
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
/*
* Note As it turns out, HMODULEs and HINSTANCEs are exactly the same thing.
* If the documentation for a function indicates that an HMODULE is required, you can pass an HINSTANCE and vice versa.
* There are two data types because in 16-bit Windows HMODULEs and HINSTANCEs identified different things
*/
// static method call to Unregister all window classes
wsl::ui::ClassAtoms::UnregisterClassAtoms(hModule);
break;
}
return TRUE;
}
这是实现,如果您好奇的话,但这并不重要。
namespace wsl::ui
{
class ClassAtoms
{
public:
static void AddClassAtom(const ATOM& atom)
{
mAtoms.push_back(atom);
}
static void UnregisterClassAtom(const ATOM& atom, const HINSTANCE& hInstance)
{
// If the class could not be found or if a window still exists
// that was created with the class, the return value is zero.
if (!UnregisterClass(MAKEINTATOM(atom), hInstance))
{
ShowError(ERR_BOILER);
}
}
static void UnregisterClassAtoms(const HINSTANCE& hInstance)
{
for (auto& ref : mAtoms)
{
UnregisterClassAtom(ref, hInstance);
}
mAtoms.clear();
}
private:
inline static std::vector<ATOM> mAtoms = {};
// deleted
ClassAtoms() = delete;
~ClassAtoms() = delete;
ClassAtoms(const ClassAtoms&) = delete;
ClassAtoms(ClassAtoms&&) = delete;
ClassAtoms& operator=(const ClassAtoms&) = delete;
ClassAtoms& operator=(ClassAtoms&&) = delete;
};
}