[Ttssh2-commit] [7457] ttermpro.exe と同一フォルダの TSPECIAL1.TTF を読み込めるようにした

scmno****@osdn***** scmno****@osdn*****
2019年 3月 3日 (日) 01:19:00 JST


Revision: 7457
          http://sourceforge.jp/projects/ttssh2/scm/svn/commits/7457
Author:   zmatsuo
Date:     2019-03-03 01:19:00 +0900 (Sun, 03 Mar 2019)
Log Message:
-----------
ttermpro.exe と同一フォルダの TSPECIAL1.TTF を読み込めるようにした
GetProcAddress()を一括して行う仕組みを作った(dllutil.cpp,h)
TCHAR考慮

Modified Paths:
--------------
    trunk/teraterm/teraterm/CMakeLists.txt
    trunk/teraterm/teraterm/teraterm.cpp
    trunk/teraterm/teraterm/ttermpro.vcproj
    trunk/teraterm/teraterm/vtdisp.c
    trunk/teraterm/teraterm/vtwin.cpp

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

-------------- next part --------------
Added: trunk/teraterm/common/compat_win.cpp
===================================================================
--- trunk/teraterm/common/compat_win.cpp	                        (rev 0)
+++ trunk/teraterm/common/compat_win.cpp	2019-03-02 16:19:00 UTC (rev 7457)
@@ -0,0 +1,81 @@
+/*
+ * (C) 2019 TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* compat_win */
+
+#include <windows.h>
+#include <tchar.h>
+#include "compat_win.h"
+
+#include "dllutil.h"
+
+BOOL (WINAPI *pAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
+BOOL (WINAPI *pEnumDisplayMonitors)(HDC,LPCRECT,MONITORENUMPROC,LPARAM);
+DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT dpiContext);
+UINT (WINAPI *pGetDpiForWindow)(HWND hwnd);
+BOOL (WINAPI *pSetLayeredWindowAttributes)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
+int (WINAPI *pAddFontResourceExA)(LPCSTR name, DWORD fl, PVOID res);
+int (WINAPI *pAddFontResourceExW)(LPCWSTR name, DWORD fl, PVOID res);
+BOOL (WINAPI *pRemoveFontResourceExA)(LPCSTR name, DWORD fl, PVOID pdv);
+BOOL (WINAPI *pRemoveFontResourceExW)(LPCWSTR name, DWORD fl, PVOID pdv);
+
+static const APIInfo Lists_user32[] = {
+	{ "SetLayeredWindowAttributes", (void **)&pSetLayeredWindowAttributes },
+	{ "SetThreadDpiAwarenessContext", (void **)&pSetThreadDpiAwarenessContext },
+	{ "GetDpiForWindow", (void **)&pGetDpiForWindow },
+	{ NULL },
+};
+
+static const APIInfo Lists_msimg32[] = {
+	{ "AlphaBlend", (void **)&pAlphaBlend },
+	{ NULL },
+};
+
+static const APIInfo Lists_gdi32[] = {
+	{ "AddFontResourceExA", (void **)&pAddFontResourceExA },
+	{ "RemoveFontResourceExA", (void **)&pRemoveFontResourceExA },
+	{ "AddFontResourceExW", (void **)&pAddFontResourceExW },
+	{ "RemoveFontResourceExW", (void **)&pRemoveFontResourceExW },
+	{ NULL },
+};
+
+static const DllInfo DllInfos[] = {
+	{ _T("user32.dll"), DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_user32 },
+	{ _T("msimg32.dll"), DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_msimg32 },
+	{ _T("gdi32.dll"), DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_gdi32 },
+	{ NULL },
+};
+
+void WinCompatInit()
+{
+	static BOOL done = FALSE;
+	if (done) return;
+	done = TRUE;
+
+	DLLGetApiAddressFromLists(DllInfos);
+}

Added: trunk/teraterm/common/compat_win.h
===================================================================
--- trunk/teraterm/common/compat_win.h	                        (rev 0)
+++ trunk/teraterm/common/compat_win.h	2019-03-02 16:19:00 UTC (rev 7457)
@@ -0,0 +1,72 @@
+/*
+ * (C) 2018 TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* compat_win */
+
+#pragma once
+
+#include <windows.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE)
+#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE          ((DPI_AWARENESS_CONTEXT)-2)
+#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE     ((DPI_AWARENESS_CONTEXT)-3)
+#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2  ((DPI_AWARENESS_CONTEXT)-4)
+DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
+#endif
+
+#if !defined(WM_DPICHANGED)
+#define WM_DPICHANGED                   0x02E0
+#endif
+
+extern BOOL (WINAPI *pAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
+extern BOOL (WINAPI *pEnumDisplayMonitors)(HDC,LPCRECT,MONITORENUMPROC,LPARAM);
+extern DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT dpiContext);
+extern UINT (WINAPI *pGetDpiForWindow)(HWND hwnd);
+extern BOOL (WINAPI *pSetLayeredWindowAttributes)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
+extern int (WINAPI *pAddFontResourceExA)(LPCSTR name, DWORD fl, PVOID res);
+extern int (WINAPI *pAddFontResourceExW)(LPCWSTR name, DWORD fl, PVOID res);
+extern BOOL (WINAPI *pRemoveFontResourceExA)(LPCSTR name, DWORD fl, PVOID pdv);
+extern BOOL (WINAPI *pRemoveFontResourceExW)(LPCWSTR name, DWORD fl, PVOID pdv);
+
+#ifdef UNICODE
+#define pAddFontResourceEx		pAddFontResourceExW
+#define pRemoveFontResourceEx	pRemoveFontResourceExW
+#else
+#define pAddFontResourceEx		pAddFontResourceExA
+#define pRemoveFontResourceEx	pRemoveFontResourceExA
+#endif // !UNICODE
+
+void WinCompatInit();
+
+#ifdef __cplusplus
+}
+#endif

Added: trunk/teraterm/common/dllutil.cpp
===================================================================
--- trunk/teraterm/common/dllutil.cpp	                        (rev 0)
+++ trunk/teraterm/common/dllutil.cpp	2019-03-02 16:19:00 UTC (rev 7457)
@@ -0,0 +1,284 @@
+/*
+ * (C) 2019 TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <windows.h>
+#include <tchar.h>
+#include <assert.h>
+#include <crtdbg.h>
+
+#include "dllutil.h"
+
+#ifdef _DEBUG
+#define malloc(l)     _malloc_dbg((l), _NORMAL_BLOCK, __FILE__, __LINE__)
+#define free(p)       _free_dbg((p), _NORMAL_BLOCK)
+#define _strdup(s)	  _strdup_dbg((s), _NORMAL_BLOCK, __FILE__, __LINE__)
+#endif
+
+typedef struct {
+	const TCHAR *dllName;
+	DLLLoadFlag LoadFlag;
+	HMODULE handle;
+	int refCount;
+} HandleList_t;
+
+static HandleList_t *HandleList;
+static int HandleListCount;
+
+static HMODULE GetHandle(const TCHAR *dllName, DLLLoadFlag LoadFlag)
+{
+	TCHAR dllPath[MAX_PATH];
+	HMODULE module;
+	int i;
+	HandleList_t *p;
+	int r;
+
+	if (LoadFlag == DLL_GET_MODULE_HANDLE) {
+		module = GetModuleHandle(dllName);
+		assert(module != NULL);
+		return module;
+	}
+
+	// \x88ȑO\x82Ƀ\x8D\x81[\x83h\x82\xB5\x82\xBD?
+	p = HandleList;
+	for (i = 0; i < HandleListCount; i++) {
+		if (_tcscmp(p->dllName, dllName) == 0) {
+			p->refCount++;
+			return p->handle;
+		}
+		p++;
+	}
+
+	// \x90V\x82\xBD\x82Ƀ\x8D\x81[\x83h\x82\xB7\x82\xE9
+	dllPath[0] = 0;
+	switch (LoadFlag) {
+	case DLL_LOAD_LIBRARY_SYSTEM:
+		r = GetSystemDirectory(dllPath, _countof(dllPath));
+		assert(r != 0);
+		if (r == 0) return NULL;
+		break;
+	case DLL_LOAD_LIBRARY_CURRENT:
+		r = GetModuleFileName(NULL, dllPath, _countof(dllPath));
+		assert(r != 0);
+		if (r == 0) return NULL;
+		*_tcsrchr(dllPath, _T('\\')) = 0;
+		break;
+	default:
+		return NULL;
+	}
+	_tcscat_s(dllPath, _countof(dllPath), _T("\\"));
+	_tcscat_s(dllPath, _countof(dllPath), dllName);
+	module = LoadLibrary(dllPath);
+	if (module == NULL) {
+		// \x91\xB6\x8D݂\xB5\x82Ȃ\xA2,dll\x82\xB6\x82\xE1\x82Ȃ\xA2?
+		return NULL;
+	}
+
+	// \x83\x8A\x83X\x83g\x82ɒlj\xC1
+	HandleListCount++;
+	HandleList = (HandleList_t *)realloc(HandleList, sizeof(HandleList_t)*HandleListCount);
+	p = &HandleList[i];
+	p->dllName = _tcsdup(dllName);
+	p->handle = module;
+	p->LoadFlag = LoadFlag;
+	p->refCount = 1;
+	return module;
+}
+
+static void FreeHandle(const TCHAR *dllName, DLLLoadFlag LoadFlag)
+{
+	int i;
+	HandleList_t *p;
+
+	if (LoadFlag == DLL_GET_MODULE_HANDLE) {
+		// \x82\xBB\x82̂܂ܒu\x82\xA2\x82Ă\xA8\x82\xAD
+		return;
+	}
+
+	// \x83\x8A\x83X\x83g\x82\xA9\x82\xE7\x8D폜\x82\xB7\x82\xE9
+	p = HandleList;
+	for (i = 0; i < HandleListCount; i++) {
+		if (_tcscmp(p->dllName, dllName) != 0) {
+			continue;
+		}
+
+		// \x8C\xA9\x82‚\xA9\x82\xC1\x82\xBD
+		p->refCount--;
+		if (p->refCount > 0) {
+			continue;
+		}
+
+		// free
+		FreeLibrary(p->handle);
+		free((void *)p->dllName);
+		memcpy(p, p+1, sizeof(*p) + (HandleListCount - i - 1));
+		HandleListCount--;
+		HandleList = (HandleList_t *)realloc(HandleList, sizeof(HandleList_t)*HandleListCount);
+		return;
+	}
+	// \x83\x8A\x83X\x83g\x82Ɍ\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA9\x82\xC1\x82\xBD
+}
+
+/**
+ * DLL\x93\xE0\x82̊֐\x94\x82ւ̃A\x83h\x83\x8C\x83X\x82\xF0\x8E擾\x82\xB7\x82\xE9
+ * @param[in,out]	pFunc		\x8A֐\x94\x82ւ̃A\x83h\x83\x8C\x83X
+ *								\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA2\x8E\x9E\x82\xCDNULL\x82\xAA\x91\xE3\x93\xFC\x82\xB3\x82\xEA\x82\xE9
+ * @param[in] 		FuncFlag	\x8A֐\x94\x82\xAA\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA2\x82Ƃ\xAB\x82̓\xAE\x8D\xEC
+ *					DLL_ACCEPT_NOT_EXIST	\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAD\x82Ă\xE0ok
+ *					DLL_ERROR_NOT_EXIST		\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA2\x8Fꍇ\x83G\x83\x89\x81[
+ * @retval	NO_ERROR				\x83G\x83\x89\x81[\x82Ȃ\xB5
+ * @retval	ERROR_FILE_NOT_FOUND	DLL\x82\xAA\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA2(\x95s\x90\xB3\x82ȃt\x83@\x83C\x83\x8B)
+ * @retval	ERROR_PROC_NOT_FOUND	\x8A֐\x94\x83G\x83\x93\x83g\x83\x8A\x82\xAA\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA2
+ */
+DWORD DLLGetApiAddress(const TCHAR *dllPath, DLLLoadFlag LoadFlag,
+					   const char *ApiName, void **pFunc)
+{
+	HMODULE hDll = GetHandle(dllPath, LoadFlag);
+	if (hDll == NULL) {
+		*pFunc = NULL;
+		return ERROR_FILE_NOT_FOUND;
+	} else {
+		*pFunc = GetProcAddress(hDll, ApiName);
+		if (*pFunc == NULL) {
+			return ERROR_PROC_NOT_FOUND;
+		}
+		return NO_ERROR; // = 0
+	}
+}
+
+/**
+ * DLL\x93\xE0\x82̕\xA1\x90\x94\x82̊֐\x94\x82ւ̃A\x83h\x83\x8C\x83X\x82\xF0\x8E擾\x82\xB7\x82\xE9
+ * @param[in] FuncFlag	\x8A֐\x94\x82\xAA\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA2\x82Ƃ\xAB\x82̓\xAE\x8D\xEC
+ *				DLL_ACCEPT_NOT_EXIST	\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xAD\x82Ă\xE0ok
+ *				DLL_ERROR_NOT_EXIST		\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA2\x8Fꍇ\x83G\x83\x89\x81[
+ * @retval	NO_ERROR				\x83G\x83\x89\x81[\x82Ȃ\xB5
+ * @retval	ERROR_FILE_NOT_FOUND	DLL\x82\xAA\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA2(\x95s\x90\xB3\x82ȃt\x83@\x83C\x83\x8B)
+ * @retval	ERROR_PROC_NOT_FOUND	\x8A֐\x94\x83G\x83\x93\x83g\x83\x8A\x82\xAA\x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA2
+ */
+DWORD DLLGetApiAddressFromList(const TCHAR *dllPath, DLLLoadFlag LoadFlag,
+							   DLLFuncFlag FuncFlag, const APIInfo *ApiInfo)
+{
+	HMODULE hDll = GetHandle(dllPath, LoadFlag);
+	if (hDll == NULL) {
+		while(ApiInfo->ApiName != NULL) {
+			void **func = ApiInfo->func;
+			*func = NULL;
+			ApiInfo++;
+		}
+		return ERROR_FILE_NOT_FOUND;
+	} else {
+		BOOL exist_all = TRUE;
+		const APIInfo *p = ApiInfo;
+
+		// \x83A\x83h\x83\x8C\x83X\x8E擾
+		while(p->ApiName != NULL) {
+			void **func = p->func;
+			*func = (void *)GetProcAddress(hDll, p->ApiName);
+			if (*func == NULL) {
+				exist_all = FALSE;
+			}
+			p++;
+		}
+
+		// \x82\xB7\x82ׂČ\xA9\x82‚\xA9\x82\xC1\x82\xBD or \x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA2API\x82\xAA\x82\xA0\x82\xC1\x82Ă\xE0ok
+		if (exist_all || FuncFlag == DLL_ACCEPT_NOT_EXIST) {
+			return NO_ERROR;
+		}
+
+		// \x8C\xA9\x82‚\xA9\x82\xE7\x82Ȃ\xA2API\x82\xAA\x82\xA0\x82\xC1\x82\xBD\x82̂ŃG\x83\x89\x81[
+		p = ApiInfo;
+		while(p->ApiName != NULL) {
+			void **func = p->func;
+			*func = NULL;
+			p++;
+		}
+		FreeHandle(dllPath, LoadFlag);
+		return ERROR_PROC_NOT_FOUND;
+	}
+}
+
+void DLLGetApiAddressFromLists(const DllInfo *dllInfos)
+{
+	while (dllInfos->DllName != NULL) {
+		DLLGetApiAddressFromList(dllInfos->DllName,
+								 dllInfos->LoadFlag,
+								 dllInfos->FuncFlag,
+								 dllInfos->APIInfoPtr);
+		dllInfos++;
+	}
+}
+
+static void SetupLoadLibraryPath(void)
+{
+	BOOL (WINAPI *pSetDefaultDllDirectories)(DWORD);
+	BOOL (WINAPI *pSetDllDirectoryA)(LPCSTR);
+	const TCHAR *kernel32 = _T("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,
+					 "SetDefaultDllDirectories", (void **)&pSetDefaultDllDirectories);
+	if (pSetDefaultDllDirectories != NULL) {
+		pSetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
+		return;
+	}
+
+	// SetDefaultDllDirectories() \x82\xAA\x8Eg\x82\xA6\x82Ȃ\xAD\x82Ă\xE0
+	// SetDllDirectory() \x82\xAA\x8Eg\x82\xA6\x82\xE9\x8Fꍇ\x82\xCD
+	// \x83J\x83\x8C\x83\x93\x83g\x83f\x83B\x83\x8C\x83N\x83g\x83\x8A\x82\xBE\x82\xAF\x82ł\xE0\x8C\x9F\x8D\xF5\x83p\x83X\x82\xA9\x82\xE7\x82͂\xB8\x82\xB5\x82Ă\xA8\x82\xAD\x81B
+	DLLGetApiAddress(kernel32, DLL_GET_MODULE_HANDLE,
+					 "SetDllDirectoryA", (void **)&pSetDllDirectoryA);
+	if (pSetDllDirectoryA != NULL) {
+		pSetDllDirectoryA("");
+	}
+}
+
+void DLLInit()
+{
+	HandleList = NULL;
+	HandleListCount = 0;
+	SetupLoadLibraryPath();
+}
+
+void DLLExit()
+{
+	int i;
+	for (i = 0; i < HandleListCount; i++) {
+		HandleList_t *p = &HandleList[i];
+		if (p->LoadFlag != DLL_GET_MODULE_HANDLE) {
+			FreeLibrary(p->handle);
+		}
+		free((void *)p->dllName);
+	}
+	free(HandleList);
+	HandleList = NULL;
+	HandleListCount = 0;
+}

Added: trunk/teraterm/common/dllutil.h
===================================================================
--- trunk/teraterm/common/dllutil.h	                        (rev 0)
+++ trunk/teraterm/common/dllutil.h	2019-03-02 16:19:00 UTC (rev 7457)
@@ -0,0 +1,66 @@
+/*
+ * (C) 2019 TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+	DLL_GET_MODULE_HANDLE,
+	DLL_LOAD_LIBRARY_SYSTEM,
+	DLL_LOAD_LIBRARY_CURRENT,
+} DLLLoadFlag;
+
+typedef enum {
+	DLL_ACCEPT_NOT_EXIST,
+	DLL_ERROR_NOT_EXIST,
+} DLLFuncFlag;
+
+typedef struct {
+	const char *ApiName;
+	void **func;
+} APIInfo;
+
+typedef struct {
+	const TCHAR *DllName;
+	DLLLoadFlag LoadFlag;
+	DLLFuncFlag FuncFlag;
+	const APIInfo *APIInfoPtr;
+} DllInfo;
+
+void DLLInit();
+void DLLExit();
+void DLLGetApiAddressFromLists(const DllInfo *dllInfos);
+DWORD DLLGetApiAddressFromList(const TCHAR *dllPath, DLLLoadFlag LoadFlag,
+							   DLLFuncFlag FuncFlag, const APIInfo *ApiInfo);
+DWORD DLLGetApiAddress(const TCHAR *dllPath, DLLLoadFlag LoadFlag,
+					   const char *ApiName, void **pFunc);
+
+#ifdef __cplusplus
+}
+#endif

Modified: trunk/teraterm/teraterm/CMakeLists.txt
===================================================================
--- trunk/teraterm/teraterm/CMakeLists.txt	2019-03-02 16:18:47 UTC (rev 7456)
+++ trunk/teraterm/teraterm/CMakeLists.txt	2019-03-02 16:19:00 UTC (rev 7457)
@@ -26,7 +26,11 @@
   ../common/win16api.c
   ../common/codemap.h
   ../common/compat_w95.h
+  ../common/compat_win.h
+  ../common/compat_win.cpp
   ../common/i18n.h
+  ../common/dllutil.cpp
+  ../common/dllutil.h
   ../ttpcmn/language.h
   )
 

Modified: trunk/teraterm/teraterm/teraterm.cpp
===================================================================
--- trunk/teraterm/teraterm/teraterm.cpp	2019-03-02 16:18:47 UTC (rev 7456)
+++ trunk/teraterm/teraterm/teraterm.cpp	2019-03-02 16:19:00 UTC (rev 7457)
@@ -45,15 +45,19 @@
 #include "tekwin.h"
 #include "ttdde.h"
 #include "keyboard.h"
+#include "dllutil.h"
+#include "compat_win.h"
 
 #include "teraapp.h"
 
 #include "compat_w95.h"
 
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
+#if 0
+//#ifdef _DEBUG
+//#define new DEBUG_NEW
+//#undef THIS_FILE
+//static char THIS_FILE[] = __FILE__;
+#define new ::new(_NORMAL_BLOCK, __FILE__, __LINE__)
 #endif
 
 BEGIN_MESSAGE_MAP(CTeraApp, CWinApp)
@@ -61,28 +65,95 @@
 	//}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
-CTeraApp::CTeraApp()
+typedef struct {
+	const TCHAR *FaceName;
+	bool found;
+} EnumFontInfo;
+
+static int CALLBACK EnumFontExProc(
+	ENUMLOGFONT* lpelf, NEWTEXTMETRIC* lpntm,
+	int nFontType, LPARAM lParam)
 {
-	typedef BOOL (WINAPI *pSetDllDir)(LPCSTR);
-	typedef BOOL (WINAPI *pSetDefDllDir)(DWORD);
+	EnumFontInfo *info = (EnumFontInfo *)lParam;
+	if (nFontType == DEVICE_FONTTYPE) {
+		// \x90ڑ\xB1\x82\xB3\x82ꂽ\x83f\x83o\x83C\x83X(\x83v\x83\x8A\x83\x93\x83^\x82Ȃ\xC7)\x93\xE0\x82̃t\x83H\x83\x93\x83g
+		return 1;
+	}
+	const TCHAR *FaceName = lpelf->elfLogFont.lfFaceName;
+	if (_tcscmp(info->FaceName, FaceName) == 0) {
+		info->found = true;
+		return 0;
+	}
+	return 1;
+}
 
-	HMODULE module;
-	pSetDllDir setDllDir;
-	pSetDefDllDir setDefDllDir;
+BOOL isExistFont(const TCHAR *FaceName)
+{
+	HDC hDC = GetDC(NULL);
+	LOGFONT lf;
+	memset(&lf, 0, sizeof(lf));
+	lf.lfCharSet = DEFAULT_CHARSET;// SHIFTJIS_CHARSET;
+	lf.lfPitchAndFamily = 0;
 
-	if ((module = GetModuleHandle("kernel32.dll")) != NULL) {
-		if ((setDefDllDir = (pSetDefDllDir)GetProcAddress(module, "SetDefaultDllDirectories")) != NULL) {
-			// SetDefaultDllDirectories() \x82\xAA\x8Eg\x82\xA6\x82\xE9\x8Fꍇ\x82́A\x8C\x9F\x8D\xF5\x83p\x83X\x82\xF0 %WINDOWS%\system32 \x82݂̂ɐݒ肷\x82\xE9
-			(*setDefDllDir)((DWORD)0x00000800); // LOAD_LIBRARY_SEARCH_SYSTEM32
+	EnumFontInfo info;
+	info.FaceName = FaceName;
+	info.found = false;
+	EnumFontFamiliesEx(hDC, &lf, (FONTENUMPROC)EnumFontExProc, (LPARAM)&info, 0);
+	ReleaseDC(NULL, hDC);
+	return info.found;
+}
+
+static BOOL AddFontFlag;
+static TCHAR TSpecialFont[MAX_PATH];
+
+static void LoadSpecialFont()
+{
+	if (!isExistFont(_T("Tera Special"))) {
+		int r;
+
+		if (GetModuleFileName(NULL, TSpecialFont,_countof(TSpecialFont)) == 0) {
+			AddFontFlag = FALSE;
+			return;
 		}
-		else if ((setDllDir = (pSetDllDir)GetProcAddress(module, "SetDllDirectoryA")) != NULL) {
-			// SetDefaultDllDirectories() \x82\xAA\x8Eg\x82\xA6\x82Ȃ\xAD\x82Ă\xE0\x81ASetDllDirectory() \x82\xAA\x8Eg\x82\xA6\x82\xE9\x8Fꍇ\x82\xCD
-			// \x83J\x83\x8C\x83\x93\x83g\x83f\x83B\x83\x8C\x83N\x83g\x83\x8A\x82\xBE\x82\xAF\x82ł\xE0\x8C\x9F\x8D\xF5\x83p\x83X\x82\xA9\x82\xE7\x82͂\xB8\x82\xB5\x82Ă\xA8\x82\xAD\x81B
-			(*setDllDir)("");
+		*_tcsrchr(TSpecialFont, _T('\\')) = 0;
+		_tcscat_s(TSpecialFont, _T("\\TSPECIAL1.TTF"));
+
+		if (pAddFontResourceEx != NULL) {
+			// teraterm.exe\x82݂̂ŗL\x8C\xF8\x82ȃt\x83H\x83\x93\x83g\x82ƂȂ\xE9\x81B
+			// remove\x82\xB5\x82Ȃ\xAD\x82Ă\xE0\x8FI\x97\xB9\x82\xB7\x82\xE9\x82\xC6OS\x82\xA9\x82\xE7\x82Ȃ\xAD\x82Ȃ\xE9
+			r = pAddFontResourceEx(TSpecialFont, FR_PRIVATE, NULL);
+		} else {
+			// \x83V\x83X\x83e\x83\x80\x91S\x91̂Ŏg\x82\xA6\x82\xE9\x83t\x83H\x83\x93\x83g\x82ƂȂ\xE9
+			// remove\x82\xB5\x82Ȃ\xA2\x82\xC6OS\x82\xAA\x92͂񂾂܂܂ƂȂ\xE9
+			r = AddFontResource(TSpecialFont);
 		}
+		if (r != 0) {
+			AddFontFlag = TRUE;
+		}
 	}
 }
 
+static void UnloadSpecialFont()
+{
+	if (AddFontFlag) {
+		if (pRemoveFontResourceEx != NULL) {
+			pRemoveFontResourceEx(TSpecialFont, FR_PRIVATE, NULL);
+		} else {
+			RemoveFontResource(TSpecialFont);
+		}
+	}
+}
+
+CTeraApp::CTeraApp()
+{
+#ifdef _DEBUG
+	::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
+#endif
+
+	DLLInit();
+	WinCompatInit();
+}
+
 // CTeraApp instance
 CTeraApp theApp;
 
@@ -93,6 +164,7 @@
 // CTeraApp initialization
 BOOL CTeraApp::InitInstance()
 {
+	LoadSpecialFont();
 	hInst = m_hInstance;
 	m_pMainWnd = new CVTWindow();
 	pVTWin = m_pMainWnd;
@@ -101,6 +173,8 @@
 
 int CTeraApp::ExitInstance()
 {
+	UnloadSpecialFont();
+	DLLExit();
 	return CWinApp::ExitInstance();
 }
 

Modified: trunk/teraterm/teraterm/ttermpro.vcproj
===================================================================
--- trunk/teraterm/teraterm/ttermpro.vcproj	2019-03-02 16:18:47 UTC (rev 7456)
+++ trunk/teraterm/teraterm/ttermpro.vcproj	2019-03-02 16:19:00 UTC (rev 7457)
@@ -389,6 +389,14 @@
 				RelativePath="..\common\win16api.c"
 				>
 			</File>
+			<File
+				RelativePath="..\common\compat_win.cpp"
+				>
+			</File>
+			<File
+				RelativePath="..\common\dllutil.cpp"
+				>
+			</File>
 		</Filter>
 		<Filter
 			Name="Header Files"

Modified: trunk/teraterm/teraterm/vtdisp.c
===================================================================
--- trunk/teraterm/teraterm/vtdisp.c	2019-03-02 16:18:47 UTC (rev 7456)
+++ trunk/teraterm/teraterm/vtdisp.c	2019-03-02 16:19:00 UTC (rev 7457)
@@ -36,6 +36,7 @@
 #include "ttime.h"
 #include "ttdialog.h"
 #include "ttcommon.h"
+#include "compat_win.h"
 
 #include "vtdisp.h"
 
@@ -192,17 +193,8 @@
   int  pattern;
 }WallpaperInfo;
 
-typedef struct _BGBLENDFUNCTION
-{
-    BYTE     BlendOp;
-    BYTE     BlendFlags;
-    BYTE     SourceConstantAlpha;
-    BYTE     AlphaFormat;
-}BGBLENDFUNCTION;
+static BOOL (WINAPI *BGAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION);
 
-BOOL (WINAPI *BGAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BGBLENDFUNCTION);
-BOOL (WINAPI *BGEnumDisplayMonitors)(HDC,LPCRECT,MONITORENUMPROC,LPARAM);
-
 static HBITMAP GetBitmapHandle(char *File);
 
 
@@ -530,7 +522,7 @@
   return TRUE;
 }
 
-BOOL WINAPI AlphaBlendWithoutAPI(HDC hdcDest,int dx,int dy,int width,int height,HDC hdcSrc,int sx,int sy,int sw,int sh,BGBLENDFUNCTION bf)
+static BOOL WINAPI AlphaBlendWithoutAPI(HDC hdcDest,int dx,int dy,int width,int height,HDC hdcSrc,int sx,int sy,int sw,int sh,BLENDFUNCTION bf)
 {
   HDC hdcDestWork,hdcSrcWork;
   int i,invAlpha,alpha;
@@ -1204,9 +1196,9 @@
   lws.src        = src;
   lws.hdcDest    = hdcDest;
 
-  if(BGEnumDisplayMonitors)
+  if(pEnumDisplayMonitors != NULL)
   {
-    (*BGEnumDisplayMonitors)(NULL,NULL,BGLoadWallpaperEnumFunc,(LPARAM)&lws);
+    (*pEnumDisplayMonitors)(NULL,NULL,BGLoadWallpaperEnumFunc,(LPARAM)&lws);
   }else{
     RECT rectMonitor;
 
@@ -1273,7 +1265,7 @@
 
   if(!BGInSizeMove)
   {
-    BGBLENDFUNCTION bf;
+    BLENDFUNCTION bf;
     HDC hdcSrc = NULL;
 
     //\x94w\x8Ci HDC
@@ -1473,7 +1465,6 @@
 void BGInitialize(void)
 {
   char path[MAX_PATH],config_file[MAX_PATH],tempPath[MAX_PATH];
-  char msimg32_dll[MAX_PATH],user32_dll[MAX_PATH];
 
   // VTColor \x82\xF0\x93ǂݍ\x9E\x82\xDD
   BGVTColor[0] = ts.VTColor[0];
@@ -1619,21 +1610,15 @@
 
   // AlphaBlend \x82̃A\x83h\x83\x8C\x83X\x82\xF0\x93ǂݍ\x9E\x82\xDD
   if(BGUseAlphaBlendAPI) {
-    GetSystemDirectory(msimg32_dll, sizeof(msimg32_dll));
-    strncat_s(msimg32_dll, sizeof(msimg32_dll), "\\msimg32.dll", _TRUNCATE);
-    (FARPROC)BGAlphaBlend = GetProcAddressWithDllName(msimg32_dll,"AlphaBlend");
+	if(pAlphaBlend != NULL)
+	  BGAlphaBlend = pAlphaBlend;
+	else
+	  BGAlphaBlend = AlphaBlendWithoutAPI;
   }
   else {
     BGAlphaBlend = NULL;
   }
 
-  if(!BGAlphaBlend)
-    BGAlphaBlend = AlphaBlendWithoutAPI;
-
-  //EnumDisplayMonitors \x82\xF0\x92T\x82\xB7
-  GetSystemDirectory(user32_dll, sizeof(user32_dll));
-  strncat_s(user32_dll, sizeof(user32_dll), "\\user32.dll", _TRUNCATE);
-  (FARPROC)BGEnumDisplayMonitors = GetProcAddressWithDllName(user32_dll,"EnumDisplayMonitors");
 }
 
 void BGExchangeColor() {
@@ -2810,7 +2795,7 @@
     {
       if(BGReverseTextAlpha < 255)
       {
-        BGBLENDFUNCTION bf;
+        BLENDFUNCTION bf;
         HBRUSH hbr;
 
         hbr = CreateSolidBrush(GetBkColor(hdcBGBuffer));

Modified: trunk/teraterm/teraterm/vtwin.cpp
===================================================================
--- trunk/teraterm/teraterm/vtwin.cpp	2019-03-02 16:18:47 UTC (rev 7456)
+++ trunk/teraterm/teraterm/vtwin.cpp	2019-03-02 16:19:00 UTC (rev 7457)
@@ -78,6 +78,7 @@
 #include "winjump.h"
 #include "sizetip.h"
 #include "dnddlg.h"
+#include "compat_win.h"
 
 #include "initguid.h"
 //#include "Usbiodef.h"
@@ -260,38 +261,6 @@
 	//}}AFX_MSG_MAP
 END_MESSAGE_MAP()
 
-typedef BOOL(WINAPI *_SetLayeredWindowAttributes)(HWND, COLORREF, BYTE, DWORD);
-static _SetLayeredWindowAttributes g_pSetLayeredWindowAttributes = NULL;
-
-static void MySetLayeredWindowAttributes_init()
-{
-	static HMODULE g_hmodUser32 = NULL;
-	char user32_dll[MAX_PATH];
-
-	GetSystemDirectory(user32_dll, sizeof(user32_dll));
-	strncat_s(user32_dll, sizeof(user32_dll), "\\user32.dll", _TRUNCATE);
-	if (g_hmodUser32 == NULL) {
-		g_hmodUser32 = LoadLibrary(user32_dll);
-		if (g_hmodUser32 == NULL) {
-			return;
-		}
-
-		g_pSetLayeredWindowAttributes =
-			(_SetLayeredWindowAttributes)GetProcAddress(g_hmodUser32, "SetLayeredWindowAttributes");
-	}
-}
-
-static BOOL MySetLayeredWindowAttributes(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags)
-{
-	if (g_pSetLayeredWindowAttributes == NULL) {
-		return FALSE;
-	}
-
-	return g_pSetLayeredWindowAttributes(hwnd, crKey,
-	                                     bAlpha, dwFlags);
-}
-
-
 // Tera Term\x8BN\x93\xAE\x8E\x9E\x82\xC6URL\x95\xB6\x8E\x9A\x97\xF1mouse over\x8E\x9E\x82ɌĂ΂\xEA\x82\xE9 (2005.4.2 yutaka)
 void SetMouseCursor(char *cursor)
 {
@@ -322,6 +291,9 @@
  */
 void CVTWindow::SetWindowAlpha(BYTE alpha)
 {
+	if (pSetLayeredWindowAttributes == NULL) {
+		return;	// \x83\x8C\x83C\x83\x84\x81[\x83h\x83E\x83C\x83\x93\x83h\x83E\x82̃T\x83|\x81[\x83g\x82Ȃ\xB5
+	}
 	if (Alpha == alpha) {
 		return;	// \x95ω\xBB\x82Ȃ\xB5\x82Ȃ牽\x82\xE0\x82\xB5\x82Ȃ\xA2
 	}
@@ -336,7 +308,7 @@
 	// \x8CĂяo\x82\xB5\x8C\xB3\x82ŁA\x92l\x82\xAA\x95ύX\x82\xB3\x82ꂽ\x82Ƃ\xAB\x82̂ݐݒ\xE8\x82𔽉f\x82\xB7\x82\xE9\x81B(2007.10.19 maya)
 	if (alpha < 255) {
 		::SetWindowLongPtr(HVTWin, GWL_EXSTYLE, lp | WS_EX_LAYERED);
-		MySetLayeredWindowAttributes(HVTWin, 0, alpha, LWA_ALPHA);
+		pSetLayeredWindowAttributes(HVTWin, 0, alpha, LWA_ALPHA);
 	}
 	else {
 		// \x83A\x83\x8B\x83t\x83@\x92l\x82\xAA 255 \x82̏ꍇ\x81A\x93\xA7\x96\xBE\x89\xBB\x91\xAE\x90\xAB\x82\xF0\x8D폜\x82\xB5\x82čĕ`\x89悷\x82\xE9\x81B(2007.10.22 maya)
@@ -684,10 +656,6 @@
 	int fuLoad = LR_DEFAULTCOLOR;
 	BOOL isFirstInstance;
 
-#ifdef _DEBUG
-  ::_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
-#endif
-
 	// \x97\xE1\x8AO\x83n\x83\x93\x83h\x83\x89\x82̃t\x83b\x83N (2007.9.30 yutaka)
 	SetUnhandledExceptionFilter(ApplicationFaultHandler);
 
@@ -786,7 +754,6 @@
 	FirstPaint = TRUE;
 	ScrollLock = FALSE;  // \x8F\x89\x8A\xFA\x92l\x82͖\xB3\x8C\xF8 (2006.11.14 yutaka)
 	Alpha = 255;
-	MySetLayeredWindowAttributes_init();
 
 	/* Initialize scroll buffer */
 	InitBuffer();
@@ -2583,7 +2550,7 @@
 {
 	int line, i;
 
-	if (g_pSetLayeredWindowAttributes != NULL) {
+	if (pSetLayeredWindowAttributes != NULL) {
 		BOOL InTitleBar;
 		POINT point = pt;
 		GetPositionOnWindow(HVTWin, &point,


Ttssh2-commit メーリングリストの案内