Add semi-public wxDynamicLibrary::MSWGetModuleHandle().
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
This commit is contained in:
@@ -357,6 +357,19 @@ public:
|
|||||||
static wxString GetPluginsDirectory();
|
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:
|
protected:
|
||||||
// common part of GetSymbol() and HasSymbol()
|
// common part of GetSymbol() and HasSymbol()
|
||||||
void *DoGetSymbol(const wxString& name, bool *success = 0) const;
|
void *DoGetSymbol(const wxString& name, bool *success = 0) const;
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/app.h"
|
#include "wx/app.h"
|
||||||
|
#include "wx/dynlib.h"
|
||||||
#include "wx/frame.h"
|
#include "wx/frame.h"
|
||||||
#include "wx/panel.h"
|
#include "wx/panel.h"
|
||||||
#include "wx/sizer.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.
|
// 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
|
// We need to pass correct HINSTANCE to wxEntry() and the right value is
|
||||||
// HINSTANCE of this DLL, not of the main .exe.
|
// 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
|
||||||
// This method of obtaining DLL's instance handle requires at least
|
// not needed/used as we retrieve the DLL handle from an address inside it
|
||||||
// Windows XP/2003. We could also implement DllMain() and remember it from
|
// but you do need to use the correct name for this code to work with older
|
||||||
// there, that would work on older systems too.
|
// systems as well.
|
||||||
HINSTANCE hInstance;
|
const HINSTANCE
|
||||||
int ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
hInstance = wxDynamicLibrary::MSWGetModuleHandle("my_dll",
|
||||||
(LPCTSTR)&MyAppLauncher,
|
&gs_wxMainThread);
|
||||||
&hInstance);
|
if ( !hInstance )
|
||||||
if ( ret == 0 )
|
|
||||||
return 0; // failed to get DLL's handle
|
return 0; // failed to get DLL's handle
|
||||||
|
|
||||||
// IMPLEMENT_WXWIN_MAIN does this as the first thing
|
// IMPLEMENT_WXWIN_MAIN does this as the first thing
|
||||||
|
@@ -100,53 +100,6 @@ public:
|
|||||||
EnumModulesProc(NameStr_t name, DWORD_32_64 base, ULONG size, void *data);
|
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
|
// wxVersionDLL implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -246,7 +199,8 @@ wxDynamicLibraryDetailsCreator::EnumModulesProc(NameStr_t name,
|
|||||||
details->m_length = size;
|
details->m_length = size;
|
||||||
|
|
||||||
// to get the version, we first need the full path
|
// 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 )
|
if ( hmod )
|
||||||
{
|
{
|
||||||
wxString fullname = wxGetFullModuleName(hmod);
|
wxString fullname = wxGetFullModuleName(hmod);
|
||||||
@@ -341,5 +295,47 @@ wxDynamicLibraryDetailsArray wxDynamicLibrary::ListLoaded()
|
|||||||
return dlls;
|
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
|
#endif // wxUSE_DYNLIB_CLASS
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user