#pragma once
// WAC.com Class Liblary for Visual C++
// Copyright (C) WAC.com Inc. All rights reserved.
//
// This file is a part of the WAC.com Class Liblary.
// The use and distribution terms for this software are covered by the
// Common Public License 1.0 (http://opensource.org/licenses/cpl.php)
// which can be found in the file CPL.TXT at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
// any other, from this software.
// '04.05.10 : UNICODE版でも使用できるように修正 (sha)
// '04.05.15 : SizeofResource()を復活させた (sha)
// '04.05.27 : SizeofResource()の不具合?を修正 (sha)
// '07.02.27 : コードの整備 (sekine)
// '07.03.07 : コードの整備 & メソッド追加 (sekine)
// '07.03.09 : COUNTOFから_countofに変更 (sha)
// '07.03.19 : FreeLibraryAndExitThreadでハンドルをNULLクリアするように変更 (sekine)
// '07.04.12 : コードの整備 (sha)
#define _MODULE_H
#if _MSC_VER < 1400
#if !defined(_countof)
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#endif
#endif
////////////////////////////////////////////////////////////////////////////////
// CModuleT
template <bool t_bManaged>
class CModuleT
{
protected:
typedef CModuleT<t_bManaged> thisClass;
public:
CModuleT()
{
m_hModule = NULL;
}
CModuleT(HMODULE hModule)
{
m_hModule = NULL;
this->Attach(hModule);
}
CModuleT(LPCTSTR lpFileName, bool bLoadLibrary = true)
{
m_hModule = NULL;
if (bLoadLibrary)
{
this->LoadLibrary(lpFileName);
}
else
{
this->GetModuleHandle(lpFileName);
}
}
virtual ~CModuleT()
{
if (t_bManaged && m_hModule != NULL)
{
this->FreeLibrary();
}
}
public:
BOOL IsValid()
{
return m_hModule ? TRUE : FALSE;
}
public:
void Attach(HMODULE hModule)
{
ATLASSERT(m_hModule == NULL);
ATLASSERT(hModule != NULL);
m_hModule = hModule;
}
HMODULE Detach()
{
ATLASSERT(m_hModule != NULL);
HMODULE hModule = m_hModule;
m_hModule = NULL;
return hModule;
}
public:
CModuleT& operator =(HMODULE hModule)
{
this->FreeLibrary();
this->Attach(hModule);
return *this;
}
operator HMODULE() const
{
return m_hModule;
}
HMODULE GetHandle()
{
return m_hModule;
}
public:
HMODULE LoadLibrary(LPCTSTR lpLibFileName)
{
ATLASSERT(m_hModule == NULL);
m_hModule = ::LoadLibrary(lpLibFileName);
return m_hModule;
}
HMODULE LoadLibraryEx(LPCSTR lpLibFileName, HANDLE hFile = NULL, DWORD dwFlags = 0)
{
ATLASSERT(m_hModule == NULL);
ATLASSERT(hFile != NULL);
m_hModule = ::LoadLibraryEx(lpLibFileName, hFile, dwFlags);
return m_hModule;
}
BOOL FreeLibrary()
{
ATLASSERT(m_hModule != NULL);
BOOL br = ::FreeLibrary(m_hModule);
m_hModule = NULL;
return br;
}
void FreeLibraryAndExitThread(DWORD dwExitCode)
{
ATLASSERT(m_hModule != NULL);
::FreeLibraryAndExitThread(m_hModule, dwExitCode);
m_hModule = NULL;
}
// NOTE: CModuleHandle(ハンドルの解放を行わない)でのみ、使用可能
HMODULE GetModuleHandle(LPCTSTR lpModuleName)
{
ATLASSERT(!t_bManaged);
ATLASSERT(m_hModule == NULL);
m_hModule = ::GetModuleHandle(lpModuleName);
return m_hModule;
}
FARPROC GetProcAddress(LPCTSTR lpProcName)
{
#if 0
ATLASSERT(m_hModule != NULL);
#else
// NOTE: 互換性維持のため
if (m_hModule == NULL)
{
ATLASSERT(0);
return NULL;
}
#endif
// m_hModuleがNULLの場合の挙動は、ドキュメントされていない
return ::GetProcAddress(m_hModule, CT2A((LPTSTR)lpProcName));
}
DWORD GetModuleFileName(LPTSTR lpFilename, DWORD nSize)
{
ATLASSERT(m_hModule != NULL);
return ::GetModuleFileName(m_hModule, lpFilename, nSize);
}
#if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
#ifndef _CSTRING_NS
DWORD GetModuleFileName(CString& strFilename)
#else
DWORD GetModuleFileName(_CSTRING_NS::CString& strFilename)
#endif
{
ATLASSERT(m_hModule != NULL);
strFilename.Empty();
TCHAR szFileName[_MAX_PATH] = { 0 };
DWORD dwLength = ::GetModuleFileName(m_hModule, szFileName, _countof(szFileName));
if (dwLength == 0)
{
return dwLength;
}
strFilename = szFileName;
return dwLength;
}
#endif
BOOL DisableThreadLibraryCalls()
{
ATLASSERT(m_hModule != NULL);
return ::DisableThreadLibraryCalls(m_hModule);
}
public:
HRSRC FindResource(LPCTSTR lpName, LPCTSTR lpType)
{
ATLASSERT(m_hModule != NULL);
return ::FindResource(m_hModule, lpName, lpType);
}
HRSRC FindResourceEx(LPCTSTR lpType, LPCTSTR lpName, WORD wLanguage)
{
ATLASSERT(m_hModule != NULL);
return ::FindResourceEx(m_hModule, lpType, lpName, wLanguage);
}
HGLOBAL LoadResource(HRSRC hResInfo)
{
ATLASSERT(m_hModule != NULL);
return ::LoadResource(m_hModule, hResInfo);
}
DWORD SizeofResource(HRSRC hResInfo)
{
ATLASSERT(m_hModule != NULL);
return ::SizeofResource(m_hModule, hResInfo);
}
/* Del sha '02.07.04
public:
// AtlGetDllVersion()が見つかったため、削除
#define PACKVERSION(major,minor) MAKELONG(minor,major)
static DWORD GetDllVersion(LPCTSTR lpstrDllName)
{
HRESULT hr = S_OK;
DLLVERSIONINFO dllVersionInfo = { sizeof(DLLVERSIONINFO) };
// hr = thisClass::InvokeDllGetVersion(lpstrDllName, &dllVersionInfo);
hr = ::AtlGetDllVersion(lpstrDllName, &dllVersionInfo);
if (FAILED(hr))
{
return 0;
}
return PACKVERSION(dllVersionInfo.dwMajorVersion, dllVersionInfo.dwMinorVersion);
}
// AtlGetDllVersionと同等
static HRESULT InvokeDllGetVersion(LPCTSTR lpstrDllName, DLLVERSIONINFO* pDllVersionInfo)
{
CModule module;
HMODULE hModule = module.LoadLibrary(lpstrDllName);
if (hModule == NULL)
{
return E_FAIL;
}
return thisClass::InvokeDllGetVersion((HINSTANCE)module, pDllVersionInfo);
}
// AtlGetDllVersionと同等
static HRESULT InvokeDllGetVersion(HINSTANCE hInstDLL, DLLVERSIONINFO* pDllVersionInfo)
{
if (hInstDLL == NULL)
{
return E_FAIL;
}
DLLGETVERSIONPROC func = (DLLGETVERSIONPROC)::GetProcAddress(hInstDLL, "DllGetVersion");
if (func == NULL)
{
return E_FAIL;
}
return (*func)(&pDllVersionInfo);
}
...Del sha '02.07.04 */
protected:
HMODULE m_hModule;
};
typedef CModuleT<false> CModuleHandle;
typedef CModuleT<true> CModule;