Я работаю над dll с компонентами пользовательского интерфейса, и в соответствии с документацией MSDN нам нужно явно отменить регистрацию оконных классов, зарегистрированных в dll. (в отличие от регистрации внутри процесса non 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;
};
}