]> git.saurik.com Git - wxWidgets.git/commitdiff
Add semi-public wxDynamicLibrary::MSWGetModuleHandle().
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 7 Dec 2009 03:04:33 +0000 (03:04 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 7 Dec 2009 03:04:33 +0000 (03:04 +0000)
Rename old private wxGetModuleHandle() function to wxDynamicLibrary::
MSWGetModuleHandle() to allow its use in the dll sample.

This fixes the sample compilation with VC6 which lacks GetModuleHandleEx()-
related declarations.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62801 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/dynlib.h
samples/dll/my_dll.cpp
src/msw/dlmsw.cpp

index 213df6a8fd109a4c5ee99a607ea91f3a846f931f..1057f09cae3630bc784b15364430249cc5ca1ca2 100644 (file)
@@ -357,6 +357,19 @@ public:
     static wxString GetPluginsDirectory();
 
 
+#ifdef __WXMSW__
+    // return the handle (HMODULE/HINSTANCE) of the DLL with the given name
+    // and/or containing the specified address: for XP and later systems only
+    // the address is used and the name is ignored but for the previous systems
+    // only the name (which may be either a full path to the DLL or just its
+    // base name, possibly even without extension) is used
+    //
+    // the returned handle reference count is not incremented so it doesn't
+    // need to be freed using FreeLibrary() but it also means that it can
+    // become invalid if the DLL is unloaded
+    static HINSTANCE MSWGetModuleHandle(const char *name, void *addr);
+#endif // __WXMSW__
+
 protected:
     // common part of GetSymbol() and HasSymbol()
     void *DoGetSymbol(const wxString& name, bool *success = 0) const;
index 99dbedc002b8c6254c56066c8649beeac5f8156b..8097479b7bf84634e708b68102253a10b9ef61e4 100644 (file)
@@ -27,6 +27,7 @@
 #endif
 
 #include "wx/app.h"
+#include "wx/dynlib.h"
 #include "wx/frame.h"
 #include "wx/panel.h"
 #include "wx/sizer.h"
@@ -192,16 +193,15 @@ unsigned wxSTDCALL MyAppLauncher(void* event)
     //       at this point and won't release it until we signal it.
 
     // We need to pass correct HINSTANCE to wxEntry() and the right value is
-    // HINSTANCE of this DLL, not of the main .exe.
-    //
-    // This method of obtaining DLL's instance handle requires at least
-    // Windows XP/2003. We could also implement DllMain() and remember it from
-    // there, that would work on older systems too.
-    HINSTANCE hInstance;
-    int ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
-                                (LPCTSTR)&MyAppLauncher,
-                                &hInstance);
-    if ( ret == 0 )
+    // HINSTANCE of this DLL, not of the main .exe, use this MSW-specific wx
+    // function to get it. Notice that under Windows XP and later the name is
+    // not needed/used as we retrieve the DLL handle from an address inside it
+    // but you do need to use the correct name for this code to work with older
+    // systems as well.
+    const HINSTANCE
+        hInstance = wxDynamicLibrary::MSWGetModuleHandle("my_dll",
+                                                         &gs_wxMainThread);
+    if ( !hInstance )
         return 0; // failed to get DLL's handle
 
     // IMPLEMENT_WXWIN_MAIN does this as the first thing
index 25700c5cdb5a4b828eba5ea0067bedc9314bdc0d..ea04a1ae1937443197707fd1673fe76783a1b9fa 100644 (file)
@@ -100,53 +100,6 @@ public:
     EnumModulesProc(NameStr_t name, DWORD_32_64 base, ULONG size, void *data);
 };
 
-// ----------------------------------------------------------------------------
-// private functions
-// ----------------------------------------------------------------------------
-
-// return the module handle for the given base name
-static
-HMODULE wxGetModuleHandle(const char *name, void *addr)
-{
-    // we want to use GetModuleHandleEx() instead of usual GetModuleHandle()
-    // because the former works correctly for comctl32.dll while the latter
-    // returns NULL when comctl32.dll version 6 is used under XP (note that
-    // GetModuleHandleEx() is only available under XP and later, coincidence?)
-
-    // check if we can use GetModuleHandleEx
-    typedef BOOL (WINAPI *GetModuleHandleEx_t)(DWORD, LPCSTR, HMODULE *);
-
-    static const GetModuleHandleEx_t INVALID_FUNC_PTR = (GetModuleHandleEx_t)-1;
-
-    static GetModuleHandleEx_t s_pfnGetModuleHandleEx = INVALID_FUNC_PTR;
-    if ( s_pfnGetModuleHandleEx == INVALID_FUNC_PTR )
-    {
-        wxDynamicLibrary dll(wxT("kernel32.dll"), wxDL_VERBATIM);
-        s_pfnGetModuleHandleEx =
-            (GetModuleHandleEx_t)dll.RawGetSymbol(wxT("GetModuleHandleExA"));
-
-        // dll object can be destroyed, kernel32.dll won't be unloaded anyhow
-    }
-
-    // get module handle from its address
-    if ( s_pfnGetModuleHandleEx )
-    {
-        // flags are GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
-        //           GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
-        HMODULE hmod;
-        if ( s_pfnGetModuleHandleEx(6, (char *)addr, &hmod) && hmod )
-            return hmod;
-    }
-
-    // Windows CE only has Unicode API, so even we have an ANSI string here, we
-    // still need to use GetModuleHandleW() there
-#ifdef __WXWINCE__
-    return ::GetModuleHandleW(wxConvLibc.cMB2WC(name).data());
-#else
-    return ::GetModuleHandleA((char *)name);
-#endif
-}
-
 // ============================================================================
 // wxVersionDLL implementation
 // ============================================================================
@@ -246,7 +199,8 @@ wxDynamicLibraryDetailsCreator::EnumModulesProc(NameStr_t name,
     details->m_length = size;
 
     // to get the version, we first need the full path
-    HMODULE hmod = wxGetModuleHandle(name, details->m_address);
+    const HMODULE
+        hmod = wxDynamicLibrary::MSWGetModuleHandle(name, details->m_address);
     if ( hmod )
     {
         wxString fullname = wxGetFullModuleName(hmod);
@@ -341,5 +295,47 @@ wxDynamicLibraryDetailsArray wxDynamicLibrary::ListLoaded()
     return dlls;
 }
 
+/* static */
+HMODULE wxDynamicLibrary::MSWGetModuleHandle(const char *name, void *addr)
+{
+    // we want to use GetModuleHandleEx() instead of usual GetModuleHandle()
+    // because the former works correctly for comctl32.dll while the latter
+    // returns NULL when comctl32.dll version 6 is used under XP (note that
+    // GetModuleHandleEx() is only available under XP and later, coincidence?)
+
+    // check if we can use GetModuleHandleEx
+    typedef BOOL (WINAPI *GetModuleHandleEx_t)(DWORD, LPCSTR, HMODULE *);
+
+    static const GetModuleHandleEx_t INVALID_FUNC_PTR = (GetModuleHandleEx_t)-1;
+
+    static GetModuleHandleEx_t s_pfnGetModuleHandleEx = INVALID_FUNC_PTR;
+    if ( s_pfnGetModuleHandleEx == INVALID_FUNC_PTR )
+    {
+        wxDynamicLibrary dll(wxT("kernel32.dll"), wxDL_VERBATIM);
+        s_pfnGetModuleHandleEx =
+            (GetModuleHandleEx_t)dll.RawGetSymbol(wxT("GetModuleHandleExA"));
+
+        // dll object can be destroyed, kernel32.dll won't be unloaded anyhow
+    }
+
+    // get module handle from its address
+    if ( s_pfnGetModuleHandleEx )
+    {
+        // flags are GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
+        //           GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
+        HMODULE hmod;
+        if ( s_pfnGetModuleHandleEx(6, (char *)addr, &hmod) && hmod )
+            return hmod;
+    }
+
+    // Windows CE only has Unicode API, so even we have an ANSI string here, we
+    // still need to use GetModuleHandleW() there
+#ifdef __WXWINCE__
+    return ::GetModuleHandleW(wxConvLibc.cMB2WC(name).data());
+#else
+    return ::GetModuleHandleA((char *)name);
+#endif
+}
+
 #endif // wxUSE_DYNLIB_CLASS