• R/O
  • SSH
  • HTTPS

ttssh2: 提交


Commit MetaInfo

修订版9481 (tree)
时间2021-10-18 23:55:44
作者zmatsuo

Log Message

LoadIconWithScaleDown() を使用してアイコンをロード

- compat_win.cpp にAPI追加

- pSetDefaultDllDirectories()
- pSetDllDirectoryA()
- pLoadIconWithScaleDown()
- _LoadIconWithScaleDown()
- LoadIconWithScaleDown() が使用できないとき LoadImageW() を使用

- SxS DLLロードに対応(dllutil.cpp)

更改概述

差异

--- trunk/teraterm/common/compat_win.cpp (revision 9480)
+++ trunk/teraterm/common/compat_win.cpp (revision 9481)
@@ -63,6 +63,8 @@
6363 DWORD (WINAPI *pExpandEnvironmentStringsW)(LPCWSTR lpSrc, LPWSTR lpDst, DWORD nSize);
6464 static ULONGLONG (WINAPI *pVerSetConditionMask)(ULONGLONG dwlConditionMask, DWORD dwTypeBitMask, BYTE dwConditionMask);
6565 static BOOL (WINAPI *pVerifyVersionInfoA)(LPOSVERSIONINFOEX lpVersionInformation, DWORD dwTypeMask, DWORDLONG dwlConditionMask);
66+BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD DirectoryFlags);
67+BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR lpPathName);
6668
6769 // gdi32
6870 int (WINAPI *pAddFontResourceExW)(LPCWSTR name, DWORD fl, PVOID res);
@@ -95,7 +97,10 @@
9597 // shell32.dll
9698 static HRESULT (WINAPI *pSHGetKnownFolderPath)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR* ppszPath);
9799
100+// comctl32.dll
101+static HRESULT (WINAPI *pLoadIconWithScaleDown)(HINSTANCE hinst, PCWSTR pszName, int cx, int cy, HICON *phico);
98102
103+
99104 class Initializer {
100105 public:
101106 Initializer() {
@@ -196,6 +201,8 @@
196201 { "GetConsoleWindow", (void **)&pGetConsoleWindow },
197202 { "VerSetConditionMask", (void **)&pVerSetConditionMask },
198203 { "VerifyVersionInfoA", (void **)&pVerifyVersionInfoA },
204+ { "SetDefaultDllDirectories", (void **)&pSetDefaultDllDirectories },
205+ { "SetDllDirectoryA", (void **)&pSetDllDirectoryA },
199206 {},
200207 };
201208
@@ -228,6 +235,11 @@
228235 {},
229236 };
230237
238+static const APIInfo Lists_comctl32[] = {
239+ { "LoadIconWithScaleDown", (void **)&pLoadIconWithScaleDown },
240+ {},
241+};
242+
231243 static const DllInfo DllInfos[] = {
232244 { L"user32.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_user32 },
233245 { L"msimg32.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_msimg32 },
@@ -239,6 +251,7 @@
239251 { L"imagehlp.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_imagehlp },
240252 { L"dbghelp.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_dbghelp },
241253 { L"shell32.dll", DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_shell32 },
254+ { L"comctl32.dll", DLL_LOAD_LIBRARY_SxS, DLL_ACCEPT_NOT_EXIST, Lists_comctl32 },
242255 {},
243256 };
244257
@@ -256,6 +269,20 @@
256269 }
257270 }
258271
272+static bool IsWindowsNT4()
273+{
274+ OSVERSIONINFOA osvi;
275+ osvi.dwOSVersionInfoSize = sizeof(osvi);
276+ GetVersionExA(&osvi);
277+ if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT &&
278+ osvi.dwMajorVersion == 4 &&
279+ osvi.dwMinorVersion == 0) {
280+ // NT4
281+ return true;
282+ }
283+ return false;
284+}
285+
259286 void WinCompatInit()
260287 {
261288 static BOOL done = FALSE;
@@ -361,12 +388,12 @@
361388 DWORD dwTypeMask,
362389 DWORDLONG dwlConditionMask)
363390 {
364- OSVERSIONINFO osvi;
391+ OSVERSIONINFOA osvi;
365392 WORD cond;
366393 BOOL ret, check_next;
367394
368- osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
369- GetVersionEx(&osvi);
395+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
396+ GetVersionExA(&osvi);
370397
371398 if (dwTypeMask & VER_BUILDNUMBER) {
372399 cond = (WORD)((dwlConditionMask >> (2*3)) & 0x07);
@@ -585,3 +612,28 @@
585612 *ppszPath = _wcsdup(path);
586613 return S_OK;
587614 }
615+
616+HRESULT _LoadIconWithScaleDown(HINSTANCE hinst, PCWSTR pszName, int cx, int cy, HICON *phico)
617+{
618+ if (pLoadIconWithScaleDown != NULL) {
619+ HRESULT hr = pLoadIconWithScaleDown(hinst, pszName, cx, cy, phico);
620+ if (SUCCEEDED(hr)) {
621+ return hr;
622+ }
623+ }
624+
625+ HICON hIcon;
626+ int fuLoad = LR_DEFAULTCOLOR;
627+ if (IsWindowsNT4()) {
628+ // Windows NT 4.0 は 4bit アイコンしかサポートしていない
629+ // 16(4bit) color = VGA color
630+ fuLoad = LR_VGACOLOR;
631+ }
632+ hIcon = (HICON)LoadImageW(hinst, pszName, IMAGE_ICON, cx, cy, fuLoad);
633+ if (hIcon == NULL) {
634+ *phico = NULL;
635+ return E_NOTIMPL;
636+ }
637+ *phico = hIcon;
638+ return S_OK;
639+}
--- trunk/teraterm/common/compat_win.h (revision 9480)
+++ trunk/teraterm/common/compat_win.h (revision 9481)
@@ -153,6 +153,8 @@
153153 extern HWND (WINAPI *pGetConsoleWindow)(void);
154154 ULONGLONG _VerSetConditionMask(ULONGLONG dwlConditionMask, DWORD dwTypeBitMask, BYTE dwConditionMask);
155155 BOOL _VerifyVersionInfoA(LPOSVERSIONINFOEXA lpVersionInformation, DWORD dwTypeMask, DWORDLONG dwlConditionMask);
156+extern BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD DirectoryFlags);
157+extern BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR lpPathName);
156158
157159 // htmlhelp.dll (hhctrl.ocx)
158160 HWND _HtmlHelpW(HWND hwndCaller, LPCWSTR pszFile, UINT uCommand, DWORD_PTR dwData);
@@ -186,6 +188,10 @@
186188 #endif
187189 HRESULT _SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR* ppszPath);
188190
191+// comctl32.dll
192+HRESULT _LoadIconWithScaleDown(HINSTANCE hinst, PCWSTR pszName, int cx, int cy, HICON *phico);
193+
194+
189195 void WinCompatInit();
190196
191197 #ifdef __cplusplus
--- trunk/teraterm/common/dlglib_cpp.cpp (revision 9480)
+++ trunk/teraterm/common/dlglib_cpp.cpp (revision 9481)
@@ -333,9 +333,9 @@
333333 * アイコンをロードする
334334 * @param[in] hinst
335335 * @param[in] name
336- * @param[in] cx アイコンサイズ
336+ * @param[in] cx アイコンサイズ(96dpi時)
337337 * @param[in] cy アイコンサイズ
338- * @param[in] dpi cx,cy は 96dpiからの比率
338+ * @param[in] dpi アイコンサイズ(cx,cy)はdpi/96倍のサイズで読み込まれる
339339 * @return HICON
340340 *
341341 * cx == 0 && cy == 0 のときデフォルトのアイコンサイズで読み込む
@@ -343,8 +343,6 @@
343343 */
344344 static HICON TTLoadIcon(HINSTANCE hinst, const wchar_t *name, int cx, int cy, UINT dpi)
345345 {
346- HICON hIcon;
347- HRESULT hr;
348346 if (cx == 0 && cy == 0) {
349347 // 100%(96dpi?)のとき、GetSystemMetrics(SM_CXICON)=32
350348 if (pGetSystemMetricsForDpi != NULL) {
@@ -360,21 +358,10 @@
360358 cx = cx * dpi / 96;
361359 cy = cy * dpi / 96;
362360 }
363-#if 0 // defined(NTDDI_VISTA) && (NTDDI_VERSION >= NTDDI_VISTA)
364- // LoadIconWithScaleDown() は vistaから
365- hr = LoadIconWithScaleDown(hInst, name, cx, cy, &hIcon);
366- // LoadIconMetric();
367-#else
368- hr = E_NOTIMPL;
369-#endif
361+ HICON hIcon;
362+ HRESULT hr = _LoadIconWithScaleDown(hinst, name, cx, cy, &hIcon);
370363 if(FAILED(hr)) {
371- int fuLoad = LR_DEFAULTCOLOR;
372- if (IsWindowsNT4()) {
373- // Windows NT 4.0 は 4bit アイコンしかサポートしていない
374- // 16(4bit) color = VGA color
375- fuLoad = LR_VGACOLOR;
376- }
377- hIcon = (HICON)LoadImageW(hinst, name, IMAGE_ICON, cx, cy, fuLoad);
364+ hIcon = NULL;
378365 }
379366 return hIcon;
380367 }
--- trunk/teraterm/common/dllutil.cpp (revision 9480)
+++ trunk/teraterm/common/dllutil.cpp (revision 9481)
@@ -33,11 +33,14 @@
3333 #endif
3434 #include <crtdbg.h>
3535
36+#include "compat_win.h"
37+#include "ttlib.h" // for IsWindowsXPOrLater()
38+
3639 #include "dllutil.h"
3740
3841 typedef struct {
3942 const wchar_t *fname;
40- DLLLoadFlag LoadFlag;
43+ BOOL NeedFreeLibrary;
4144 HMODULE handle;
4245 int refCount;
4346 } HandleList_t;
@@ -47,67 +50,86 @@
4750
4851 static HMODULE GetHandle(const wchar_t *fname, DLLLoadFlag LoadFlag)
4952 {
50- wchar_t dllPath[MAX_PATH];
5153 HMODULE module;
52- int i;
5354 HandleList_t *p;
54- int r;
5555
56- if (LoadFlag == DLL_GET_MODULE_HANDLE) {
57- module = GetModuleHandleW(fname);
58- assert(module != NULL);
59- return module;
60- }
61-
6256 // 以前にロードした?
63- p = HandleList;
64- for (i = 0; i < HandleListCount; i++) {
65- if (wcscmp(p->fname, fname) == 0) {
66- p->refCount++;
67- return p->handle;
57+ if (LoadFlag != DLL_GET_MODULE_HANDLE) {
58+ p = HandleList;
59+ for (int i = 0; i < HandleListCount; i++) {
60+ if (wcscmp(p->fname, fname) == 0) {
61+ p->refCount++;
62+ return p->handle;
63+ }
64+ p++;
6865 }
69- p++;
7066 }
7167
72- // 新たにロードする
73- dllPath[0] = 0;
74- switch (LoadFlag) {
75- case DLL_LOAD_LIBRARY_SYSTEM:
76- r = GetSystemDirectoryW(dllPath, _countof(dllPath));
77- assert(r != 0);
78- if (r == 0) return NULL;
79- break;
80- case DLL_LOAD_LIBRARY_CURRENT:
81- r = GetModuleFileNameW(NULL, dllPath, _countof(dllPath));
82- assert(r != 0);
83- if (r == 0) return NULL;
84- *wcsrchr(dllPath, L'\\') = 0;
85- break;
86- default:
87- return NULL;
68+ // モジュールがロード済みならハンドルが取得できる
69+ // exeをロードしたときにdllがロードされていれば、ハンドルが返ってくる
70+ module = GetModuleHandleW(fname);
71+ if (LoadFlag == DLL_GET_MODULE_HANDLE) {
72+ // module == NULL でも return する
73+ return module;
8874 }
89- wcscat_s(dllPath, _countof(dllPath), L"\\");
90- wcscat_s(dllPath, _countof(dllPath), fname);
91- module = LoadLibraryW(dllPath);
75+
76+ BOOL NeedFreeLibrary = FALSE;
9277 if (module == NULL) {
93- // 存在しない,dllじゃない?
94- return NULL;
78+ // 新たにロードする
79+ int r;
80+ wchar_t dllPath[MAX_PATH];
81+ dllPath[0] = 0;
82+ switch (LoadFlag) {
83+ case DLL_LOAD_LIBRARY_SxS:
84+ if (IsWindowsXPOrLater()) {
85+ // Side by Side ローディングを利用するためフルパスにしない
86+ ;
87+ } else {
88+ // dllインジェクション対策でフルパスでロード
89+ r = GetSystemDirectoryW(dllPath, _countof(dllPath));
90+ assert(r != 0);
91+ if (r == 0) return NULL;
92+ wcscat_s(dllPath, _countof(dllPath), L"\\");
93+ }
94+ break;
95+ case DLL_LOAD_LIBRARY_SYSTEM:
96+ r = GetSystemDirectoryW(dllPath, _countof(dllPath));
97+ assert(r != 0);
98+ if (r == 0) return NULL;
99+ wcscat_s(dllPath, _countof(dllPath), L"\\");
100+ break;
101+ case DLL_LOAD_LIBRARY_CURRENT:
102+ r = GetModuleFileNameW(NULL, dllPath, _countof(dllPath));
103+ assert(r != 0);
104+ if (r == 0) return NULL;
105+ *(wcsrchr(dllPath, L'\\') + 1) = 0;
106+ break;
107+ default:
108+ return NULL;
109+ }
110+ wcscat_s(dllPath, _countof(dllPath), fname);
111+ module = LoadLibraryW(dllPath);
112+ if (module == NULL) {
113+ // 存在しない,dllじゃない?
114+ return NULL;
115+ }
116+ NeedFreeLibrary = TRUE;
95117 }
96118
97119 // リストに追加
98- HandleListCount++;
99- HandleList = (HandleList_t *)realloc(HandleList, sizeof(HandleList_t)*HandleListCount);
100- p = &HandleList[i];
120+ HandleList = (HandleList_t *)realloc(HandleList, sizeof(HandleList_t) * (HandleListCount + 1));
121+ p = &HandleList[HandleListCount];
101122 p->fname = _wcsdup(fname);
102123 p->handle = module;
103- p->LoadFlag = LoadFlag;
124+ p->NeedFreeLibrary = NeedFreeLibrary;
104125 p->refCount = 1;
126+ HandleListCount++;
105127 return module;
106128 }
107129
108130 static void DLLFree(HandleList_t *p)
109131 {
110- if (p->LoadFlag != DLL_GET_MODULE_HANDLE) {
132+ if (p->NeedFreeLibrary) {
111133 FreeLibrary(p->handle);
112134 }
113135 free((void *)p->fname);
@@ -281,10 +303,6 @@
281303 BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR);
282304 const wchar_t *kernel32 = L"kernel32.dll";
283305
284-#if !defined(LOAD_LIBRARY_SEARCH_SYSTEM32)
285-#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
286-#endif
287-
288306 // SetDefaultDllDirectories() が使える場合は、
289307 // 検索パスを %WINDOWS%\system32 のみに設定する
290308 DLLGetApiAddress(kernel32, DLL_GET_MODULE_HANDLE,
@@ -317,11 +335,10 @@
317335
318336 void DLLExit()
319337 {
320- int i;
321338 if (HandleListCount == 0) {
322339 return; // 未使用
323340 }
324- for (i = 0; i < HandleListCount; i++) {
341+ for (int i = 0; i < HandleListCount; i++) {
325342 HandleList_t *p = &HandleList[i];
326343 DLLFree(p);
327344 }
--- trunk/teraterm/common/dllutil.h (revision 9480)
+++ trunk/teraterm/common/dllutil.h (revision 9481)
@@ -33,7 +33,8 @@
3333 typedef enum {
3434 DLL_GET_MODULE_HANDLE, // GetModuleHandleW() APIを使用する
3535 DLL_LOAD_LIBRARY_SYSTEM, // system ディレクトリから LoadLiberaryW() APIでロード
36- DLL_LOAD_LIBRARY_CURRENT, // カレントディレクトリから LoadLiberaryW() APIでロード
36+ DLL_LOAD_LIBRARY_CURRENT, // exe,dllと同一ディレクトリから LoadLiberaryW() APIでロード
37+ DLL_LOAD_LIBRARY_SxS, // Side by Side
3738 } DLLLoadFlag;
3839
3940 typedef enum {
Show on old repository browser