[ttssh2-commit] [9481] LoadIconWithScaleDown() を使用してアイコンをロード

Back to archive index
scmno****@osdn***** scmno****@osdn*****
2021年 10月 18日 (月) 23:55:44 JST


Revision: 9481
          https://osdn.net/projects/ttssh2/scm/svn/commits/9481
Author:   zmatsuo
Date:     2021-10-18 23:55:44 +0900 (Mon, 18 Oct 2021)
Log Message:
-----------
LoadIconWithScaleDown() を使用してアイコンをロード

- compat_win.cpp にAPI追加
  - pSetDefaultDllDirectories()
  - pSetDllDirectoryA()
  - pLoadIconWithScaleDown()
  - _LoadIconWithScaleDown()
    - LoadIconWithScaleDown() が使用できないとき LoadImageW() を使用
- SxS DLLロードに対応(dllutil.cpp)

Modified Paths:
--------------
    trunk/teraterm/common/compat_win.cpp
    trunk/teraterm/common/compat_win.h
    trunk/teraterm/common/dlglib_cpp.cpp
    trunk/teraterm/common/dllutil.cpp
    trunk/teraterm/common/dllutil.h

-------------- next part --------------
Modified: trunk/teraterm/common/compat_win.cpp
===================================================================
--- trunk/teraterm/common/compat_win.cpp	2021-10-18 14:55:35 UTC (rev 9480)
+++ trunk/teraterm/common/compat_win.cpp	2021-10-18 14:55:44 UTC (rev 9481)
@@ -63,6 +63,8 @@
 DWORD (WINAPI *pExpandEnvironmentStringsW)(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize);
 static ULONGLONG (WINAPI *pVerSetConditionMask)(ULONGLONG dwlConditionMask, DWORD dwTypeBitMask, BYTE dwConditionMask);
 static BOOL (WINAPI *pVerifyVersionInfoA)(LPOSVERSIONINFOEX lpVersionInformation, DWORD dwTypeMask, DWORDLONG dwlConditionMask);
+BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD DirectoryFlags);
+BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR lpPathName);
 
 // gdi32
 int (WINAPI *pAddFontResourceExW)(LPCWSTR name, DWORD fl, PVOID res);
@@ -95,7 +97,10 @@
 // shell32.dll
 static HRESULT (WINAPI *pSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR* ppszPath);
 
+// comctl32.dll
+static HRESULT (WINAPI *pLoadIconWithScaleDown)(HINSTANCE hinst, PCWSTR pszName, int cx, int cy, HICON *phico);
 
+
 class Initializer {
 public:
 	Initializer() {
@@ -196,6 +201,8 @@
 	{ "GetConsoleWindow", (void **)&pGetConsoleWindow },
 	{ "VerSetConditionMask", (void **)&pVerSetConditionMask },
 	{ "VerifyVersionInfoA", (void **)&pVerifyVersionInfoA },
+	{ "SetDefaultDllDirectories", (void **)&pSetDefaultDllDirectories },
+	{ "SetDllDirectoryA", (void **)&pSetDllDirectoryA },
 	{},
 };
 
@@ -228,6 +235,11 @@
 	{},
 };
 
+static const APIInfo Lists_comctl32[] = {
+	{ "LoadIconWithScaleDown", (void **)&pLoadIconWithScaleDown },
+	{},
+};
+
 static const DllInfo DllInfos[] = {
 	{ L"user32.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_user32 },
 	{ L"msimg32.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_msimg32 },
@@ -239,6 +251,7 @@
 	{ L"imagehlp.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_imagehlp },
 	{ L"dbghelp.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_dbghelp },
 	{ L"shell32.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_shell32 },
+	{ L"comctl32.dll", DLL_LOAD_LIBRARY_SxS, DLL_ACCEPT_NOT_EXIST, Lists_comctl32 },
 	{},
 };
 
@@ -256,6 +269,20 @@
 	}
 }
 
+static bool IsWindowsNT4()
+{
+	OSVERSIONINFOA osvi;
+	osvi.dwOSVersionInfoSize = sizeof(osvi);
+	GetVersionExA(&osvi);
+	if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT &&
+		osvi.dwMajorVersion == 4 &&
+		osvi.dwMinorVersion == 0) {
+		// NT4
+		return true;
+	}
+	return false;
+}
+
 void WinCompatInit()
 {
 	static BOOL done = FALSE;
@@ -361,12 +388,12 @@
 	DWORD dwTypeMask,
 	DWORDLONG dwlConditionMask)
 {
-	OSVERSIONINFO osvi;
+	OSVERSIONINFOA osvi;
 	WORD cond;
 	BOOL ret, check_next;
 
-	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-	GetVersionEx(&osvi);
+	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
+	GetVersionExA(&osvi);
 
 	if (dwTypeMask & VER_BUILDNUMBER) {
 		cond = (WORD)((dwlConditionMask >> (2*3)) & 0x07);
@@ -585,3 +612,28 @@
 	*ppszPath = _wcsdup(path);
 	return S_OK;
 }
+
+HRESULT _LoadIconWithScaleDown(HINSTANCE hinst, PCWSTR pszName, int cx, int cy, HICON *phico)
+{
+	if (pLoadIconWithScaleDown != NULL) {
+		HRESULT hr = pLoadIconWithScaleDown(hinst, pszName, cx, cy, phico);
+		if (SUCCEEDED(hr)) {
+			return hr;
+		}
+	}
+
+	HICON hIcon;
+	int fuLoad = LR_DEFAULTCOLOR;
+	if (IsWindowsNT4()) {
+		// Windows NT 4.0 \x82\xCD 4bit \x83A\x83C\x83R\x83\x93\x82\xB5\x82\xA9\x83T\x83|\x81[\x83g\x82\xB5\x82Ă\xA2\x82Ȃ\xA2
+		// 16(4bit) color = VGA color
+		fuLoad = LR_VGACOLOR;
+	}
+	hIcon = (HICON)LoadImageW(hinst, pszName, IMAGE_ICON, cx, cy, fuLoad);
+	if (hIcon == NULL) {
+		*phico = NULL;
+		return E_NOTIMPL;
+	}
+	*phico = hIcon;
+	return S_OK;
+}

Modified: trunk/teraterm/common/compat_win.h
===================================================================
--- trunk/teraterm/common/compat_win.h	2021-10-18 14:55:35 UTC (rev 9480)
+++ trunk/teraterm/common/compat_win.h	2021-10-18 14:55:44 UTC (rev 9481)
@@ -153,6 +153,8 @@
 extern HWND (WINAPI *pGetConsoleWindow)(void);
 ULONGLONG _VerSetConditionMask(ULONGLONG dwlConditionMask, DWORD dwTypeBitMask, BYTE dwConditionMask);
 BOOL _VerifyVersionInfoA(LPOSVERSIONINFOEXA lpVersionInformation, DWORD dwTypeMask, DWORDLONG dwlConditionMask);
+extern BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD DirectoryFlags);
+extern BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR lpPathName);
 
 // htmlhelp.dll (hhctrl.ocx)
 HWND _HtmlHelpW(HWND hwndCaller, LPCWSTR pszFile, UINT uCommand, DWORD_PTR dwData);
@@ -186,6 +188,10 @@
 #endif
 HRESULT _SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR* ppszPath);
 
+// comctl32.dll
+HRESULT _LoadIconWithScaleDown(HINSTANCE hinst, PCWSTR pszName, int cx, int cy, HICON *phico);
+
+
 void WinCompatInit();
 
 #ifdef __cplusplus

Modified: trunk/teraterm/common/dlglib_cpp.cpp
===================================================================
--- trunk/teraterm/common/dlglib_cpp.cpp	2021-10-18 14:55:35 UTC (rev 9480)
+++ trunk/teraterm/common/dlglib_cpp.cpp	2021-10-18 14:55:44 UTC (rev 9481)
@@ -333,9 +333,9 @@
  *	\x83A\x83C\x83R\x83\x93\x82\xF0\x83\x8D\x81[\x83h\x82\xB7\x82\xE9
  *	@param[in]	hinst
  *	@param[in]	name
- *	@param[in]	cx	\x83A\x83C\x83R\x83\x93\x83T\x83C\x83Y
+ *	@param[in]	cx	\x83A\x83C\x83R\x83\x93\x83T\x83C\x83Y(96dpi\x8E\x9E)
  *	@param[in]	cy	\x83A\x83C\x83R\x83\x93\x83T\x83C\x83Y
- *	@param[in]	dpi	cx,cy \x82\xCD 96dpi\x82\xA9\x82\xE7\x82̔䗦
+ *	@param[in]	dpi	\x83A\x83C\x83R\x83\x93\x83T\x83C\x83Y(cx,cy)\x82\xCDdpi/96\x94{\x82̃T\x83C\x83Y\x82œǂݍ\x9E\x82܂\xEA\x82\xE9
  *	@return		HICON
  *
  *		cx == 0 && cy == 0 \x82̂Ƃ\xAB\x83f\x83t\x83H\x83\x8B\x83g\x82̃A\x83C\x83R\x83\x93\x83T\x83C\x83Y\x82œǂݍ\x9E\x82\xDE
@@ -343,8 +343,6 @@
  */
 static HICON TTLoadIcon(HINSTANCE hinst, const wchar_t *name, int cx, int cy, UINT dpi)
 {
-	HICON hIcon;
-	HRESULT hr;
 	if (cx == 0 && cy == 0) {
 		// 100%(96dpi?)\x82̂Ƃ\xAB\x81AGetSystemMetrics(SM_CXICON)=32
 		if (pGetSystemMetricsForDpi != NULL) {
@@ -360,21 +358,10 @@
 		cx = cx * dpi / 96;
 		cy = cy * dpi / 96;
 	}
-#if 0 // defined(NTDDI_VISTA) && (NTDDI_VERSION >= NTDDI_VISTA)
-	// LoadIconWithScaleDown() \x82\xCD vista\x82\xA9\x82\xE7
-	hr = LoadIconWithScaleDown(hInst, name, cx, cy, &hIcon);
-	// LoadIconMetric();
-#else
-	hr = E_NOTIMPL;
-#endif
+	HICON hIcon;
+	HRESULT hr = _LoadIconWithScaleDown(hinst, name, cx, cy, &hIcon);
 	if(FAILED(hr)) {
-		int fuLoad = LR_DEFAULTCOLOR;
-		if (IsWindowsNT4()) {
-			// Windows NT 4.0 \x82\xCD 4bit \x83A\x83C\x83R\x83\x93\x82\xB5\x82\xA9\x83T\x83|\x81[\x83g\x82\xB5\x82Ă\xA2\x82Ȃ\xA2
-			// 16(4bit) color = VGA color
-			fuLoad = LR_VGACOLOR;
-		}
-		hIcon = (HICON)LoadImageW(hinst, name, IMAGE_ICON, cx, cy, fuLoad);
+		hIcon = NULL;
 	}
 	return hIcon;
 }

Modified: trunk/teraterm/common/dllutil.cpp
===================================================================
--- trunk/teraterm/common/dllutil.cpp	2021-10-18 14:55:35 UTC (rev 9480)
+++ trunk/teraterm/common/dllutil.cpp	2021-10-18 14:55:44 UTC (rev 9481)
@@ -33,11 +33,14 @@
 #endif
 #include <crtdbg.h>
 
+#include "compat_win.h"
+#include "ttlib.h"	// for IsWindowsXPOrLater()
+
 #include "dllutil.h"
 
 typedef struct {
 	const wchar_t *fname;
-	DLLLoadFlag LoadFlag;
+	BOOL NeedFreeLibrary;
 	HMODULE handle;
 	int refCount;
 } HandleList_t;
@@ -47,67 +50,86 @@
 
 static HMODULE GetHandle(const wchar_t *fname, DLLLoadFlag LoadFlag)
 {
-	wchar_t dllPath[MAX_PATH];
 	HMODULE module;
-	int i;
 	HandleList_t *p;
-	int r;
 
-	if (LoadFlag == DLL_GET_MODULE_HANDLE) {
-		module = GetModuleHandleW(fname);
-		assert(module != NULL);
-		return module;
-	}
-
 	// \x88ȑO\x82Ƀ\x8D\x81[\x83h\x82\xB5\x82\xBD?
-	p = HandleList;
-	for (i = 0; i < HandleListCount; i++) {
-		if (wcscmp(p->fname, fname) == 0) {
-			p->refCount++;
-			return p->handle;
+	if (LoadFlag != DLL_GET_MODULE_HANDLE) {
+		p = HandleList;
+		for (int i = 0; i < HandleListCount; i++) {
+			if (wcscmp(p->fname, fname) == 0) {
+				p->refCount++;
+				return p->handle;
+			}
+			p++;
 		}
-		p++;
 	}
 
-	// \x90V\x82\xBD\x82Ƀ\x8D\x81[\x83h\x82\xB7\x82\xE9
-	dllPath[0] = 0;
-	switch (LoadFlag) {
-	case DLL_LOAD_LIBRARY_SYSTEM:
-		r = GetSystemDirectoryW(dllPath, _countof(dllPath));
-		assert(r != 0);
-		if (r == 0) return NULL;
-		break;
-	case DLL_LOAD_LIBRARY_CURRENT:
-		r = GetModuleFileNameW(NULL, dllPath, _countof(dllPath));
-		assert(r != 0);
-		if (r == 0) return NULL;
-		*wcsrchr(dllPath, L'\\') = 0;
-		break;
-	default:
-		return NULL;
+	// \x83\x82\x83W\x83\x85\x81[\x83\x8B\x82\xAA\x83\x8D\x81[\x83h\x8Dς݂Ȃ\xE7\x83n\x83\x93\x83h\x83\x8B\x82\xAA\x8E擾\x82ł\xAB\x82\xE9
+	// exe\x82\xF0\x83\x8D\x81[\x83h\x82\xB5\x82\xBD\x82Ƃ\xAB\x82\xC9dll\x82\xAA\x83\x8D\x81[\x83h\x82\xB3\x82\xEA\x82Ă\xA2\x82\xEA\x82΁A\x83n\x83\x93\x83h\x83\x8B\x82\xAA\x95Ԃ\xC1\x82Ă\xAD\x82\xE9
+	module = GetModuleHandleW(fname);
+	if (LoadFlag == DLL_GET_MODULE_HANDLE) {
+		// module == NULL \x82ł\xE0 return \x82\xB7\x82\xE9
+		return module;
 	}
-	wcscat_s(dllPath, _countof(dllPath), L"\\");
-	wcscat_s(dllPath, _countof(dllPath), fname);
-	module = LoadLibraryW(dllPath);
+
+	BOOL NeedFreeLibrary = FALSE;
 	if (module == NULL) {
-		// \x91\xB6\x8D݂\xB5\x82Ȃ\xA2,dll\x82\xB6\x82\xE1\x82Ȃ\xA2?
-		return NULL;
+		// \x90V\x82\xBD\x82Ƀ\x8D\x81[\x83h\x82\xB7\x82\xE9
+		int r;
+		wchar_t dllPath[MAX_PATH];
+		dllPath[0] = 0;
+		switch (LoadFlag) {
+		case DLL_LOAD_LIBRARY_SxS:
+			if (IsWindowsXPOrLater()) {
+				// Side by Side \x83\x8D\x81[\x83f\x83B\x83\x93\x83O\x82𗘗p\x82\xB7\x82邽\x82߃t\x83\x8B\x83p\x83X\x82ɂ\xB5\x82Ȃ\xA2
+				;
+			} else {
+				// dll\x83C\x83\x93\x83W\x83F\x83N\x83V\x83\x87\x83\x93\x91΍\xF4\x82Ńt\x83\x8B\x83p\x83X\x82Ń\x8D\x81[\x83h
+				r = GetSystemDirectoryW(dllPath, _countof(dllPath));
+				assert(r != 0);
+				if (r == 0) return NULL;
+				wcscat_s(dllPath, _countof(dllPath), L"\\");
+			}
+			break;
+		case DLL_LOAD_LIBRARY_SYSTEM:
+			r = GetSystemDirectoryW(dllPath, _countof(dllPath));
+			assert(r != 0);
+			if (r == 0) return NULL;
+			wcscat_s(dllPath, _countof(dllPath), L"\\");
+			break;
+		case DLL_LOAD_LIBRARY_CURRENT:
+			r = GetModuleFileNameW(NULL, dllPath, _countof(dllPath));
+			assert(r != 0);
+			if (r == 0) return NULL;
+			*(wcsrchr(dllPath, L'\\') + 1) = 0;
+			break;
+		default:
+			return NULL;
+		}
+		wcscat_s(dllPath, _countof(dllPath), fname);
+		module = LoadLibraryW(dllPath);
+		if (module == NULL) {
+			// \x91\xB6\x8D݂\xB5\x82Ȃ\xA2,dll\x82\xB6\x82\xE1\x82Ȃ\xA2?
+			return NULL;
+		}
+		NeedFreeLibrary = TRUE;
 	}
 
 	// \x83\x8A\x83X\x83g\x82ɒlj\xC1
-	HandleListCount++;
-	HandleList = (HandleList_t *)realloc(HandleList, sizeof(HandleList_t)*HandleListCount);
-	p = &HandleList[i];
+	HandleList = (HandleList_t *)realloc(HandleList, sizeof(HandleList_t) * (HandleListCount + 1));
+	p = &HandleList[HandleListCount];
 	p->fname = _wcsdup(fname);
 	p->handle = module;
-	p->LoadFlag = LoadFlag;
+	p->NeedFreeLibrary = NeedFreeLibrary;
 	p->refCount = 1;
+	HandleListCount++;
 	return module;
 }
 
 static void DLLFree(HandleList_t *p)
 {
-	if (p->LoadFlag != DLL_GET_MODULE_HANDLE) {
+	if (p->NeedFreeLibrary) {
 		FreeLibrary(p->handle);
 	}
 	free((void *)p->fname);
@@ -281,10 +303,6 @@
 	BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR);
 	const wchar_t *kernel32 = L"kernel32.dll";
 
-#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
-#define LOAD_LIBRARY_SEARCH_SYSTEM32        0x00000800
-#endif
-
 	// SetDefaultDllDirectories() \x82\xAA\x8Eg\x82\xA6\x82\xE9\x8Fꍇ\x82́A
 	// \x8C\x9F\x8D\xF5\x83p\x83X\x82\xF0 %WINDOWS%\system32 \x82݂̂ɐݒ肷\x82\xE9
 	DLLGetApiAddress(kernel32, DLL_GET_MODULE_HANDLE,
@@ -317,11 +335,10 @@
 
 void DLLExit()
 {
-	int i;
 	if (HandleListCount == 0) {
 		return;		// \x96\xA2\x8Eg\x97p
 	}
-	for (i = 0; i < HandleListCount; i++) {
+	for (int i = 0; i < HandleListCount; i++) {
 		HandleList_t *p = &HandleList[i];
 		DLLFree(p);
 	}

Modified: trunk/teraterm/common/dllutil.h
===================================================================
--- trunk/teraterm/common/dllutil.h	2021-10-18 14:55:35 UTC (rev 9480)
+++ trunk/teraterm/common/dllutil.h	2021-10-18 14:55:44 UTC (rev 9481)
@@ -33,7 +33,8 @@
 typedef enum {
 	DLL_GET_MODULE_HANDLE,		// GetModuleHandleW() API\x82\xF0\x8Eg\x97p\x82\xB7\x82\xE9
 	DLL_LOAD_LIBRARY_SYSTEM,	// system \x83f\x83B\x83\x8C\x83N\x83g\x83\x8A\x82\xA9\x82\xE7 LoadLiberaryW() API\x82Ń\x8D\x81[\x83h
-	DLL_LOAD_LIBRARY_CURRENT,	// \x83J\x83\x8C\x83\x93\x83g\x83f\x83B\x83\x8C\x83N\x83g\x83\x8A\x82\xA9\x82\xE7 LoadLiberaryW() API\x82Ń\x8D\x81[\x83h
+	DLL_LOAD_LIBRARY_CURRENT,	// exe,dll\x82Ɠ\xAF\x88\xEA\x83f\x83B\x83\x8C\x83N\x83g\x83\x8A\x82\xA9\x82\xE7 LoadLiberaryW() API\x82Ń\x8D\x81[\x83h
+	DLL_LOAD_LIBRARY_SxS,		// Side by Side
 } DLLLoadFlag;
 
 typedef enum {


ttssh2-commit メーリングリストの案内
Back to archive index