X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e6d18909c9cb124feaab32966f2aa44c2f0b0617..8d7490018a47f60149a35ced6f880ec834aba471:/src/msw/dc.cpp diff --git a/src/msw/dc.cpp b/src/msw/dc.cpp index fa9c434fb4..0801815ebf 100644 --- a/src/msw/dc.cpp +++ b/src/msw/dc.cpp @@ -238,14 +238,37 @@ public: return m_dll.IsLoaded() ? m_dll.GetSymbol(name) : NULL; } + void Unload() + { + if ( m_dll.IsLoaded() ) + { + m_dll.Unload(); + } + } + private: wxDynamicLibrary m_dll; const wxChar *m_dllName; }; -static wxOnceOnlyDLLLoader wxGDI32DLL(_T("gdi32")); static wxOnceOnlyDLLLoader wxMSIMG32DLL(_T("msimg32")); +// we must ensure that DLLs are unloaded before the static objects cleanup time +// because we may hit the notorious DllMain() dead lock in this case if wx is +// used as a DLL (attempting to unload another DLL from inside DllMain() hangs +// under Windows because it tries to reacquire the same lock) +class wxGDIDLLsCleanupModule : public wxModule +{ +public: + virtual bool OnInit() { return true; } + virtual void OnExit() { wxMSIMG32DLL.Unload(); } + +private: + DECLARE_DYNAMIC_CLASS(wxGDIDLLsCleanupModule) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxGDIDLLsCleanupModule, wxModule) + #endif // wxUSE_DYNLIB_CLASS // =========================================================================== @@ -2694,9 +2717,9 @@ static DWORD wxGetDCLayout(HDC hdc) { typedef DWORD (WINAPI *GetLayout_t)(HDC); static GetLayout_t - pfnGetLayout = (GetLayout_t)wxGDI32DLL.GetSymbol(_T("GetLayout")); + wxDL_INIT_FUNC(s_pfn, GetLayout, wxDynamicLibrary(_T("gdi32.dll"))); - return pfnGetLayout ? pfnGetLayout(hdc) : (DWORD)-1; + return s_pfnGetLayout ? s_pfnGetLayout(hdc) : (DWORD)-1; } wxLayoutDirection wxDC::GetLayoutDirection() const @@ -2713,8 +2736,8 @@ void wxDC::SetLayoutDirection(wxLayoutDirection dir) { typedef DWORD (WINAPI *SetLayout_t)(HDC, DWORD); static SetLayout_t - pfnSetLayout = (SetLayout_t)wxGDI32DLL.GetSymbol(_T("SetLayout")); - if ( !pfnSetLayout ) + wxDL_INIT_FUNC(s_pfn, SetLayout, wxDynamicLibrary(_T("gdi32.dll"))); + if ( !s_pfnSetLayout ) return; if ( dir == wxLayout_Default ) @@ -2730,7 +2753,7 @@ void wxDC::SetLayoutDirection(wxLayoutDirection dir) else layout &= ~LAYOUT_RTL; - pfnSetLayout(GetHdc(), layout); + s_pfnSetLayout(GetHdc(), layout); } #else // !wxUSE_DYNLIB_CLASS