Revision: 8244 https://osdn.net/projects/ttssh2/scm/svn/commits/8244 Author: zmatsuo Date: 2019-10-03 00:06:44 +0900 (Thu, 03 Oct 2019) Log Message: ----------- drag and drop 時に文字化けしないよう修正 - ファイル名の処理などは Unicode で行う - Win32 API の呼び出し時に Unicode と ANSI 文字列を変換する層を追加 - common/layer_for_unicode.cpp,h Modified Paths: -------------- branches/unicode_buf/teraterm/common/compat_win.cpp branches/unicode_buf/teraterm/common/compat_win.h branches/unicode_buf/teraterm/teraterm/CMakeLists.txt branches/unicode_buf/teraterm/teraterm/dnddlg.cpp branches/unicode_buf/teraterm/teraterm/dnddlg.h branches/unicode_buf/teraterm/teraterm/vtwin.cpp branches/unicode_buf/teraterm/teraterm/vtwin.h Added Paths: ----------- branches/unicode_buf/teraterm/common/layer_for_unicode.cpp branches/unicode_buf/teraterm/common/layer_for_unicode.h -------------- next part -------------- Modified: branches/unicode_buf/teraterm/common/compat_win.cpp =================================================================== --- branches/unicode_buf/teraterm/common/compat_win.cpp 2019-10-02 15:06:32 UTC (rev 8243) +++ branches/unicode_buf/teraterm/common/compat_win.cpp 2019-10-02 15:06:44 UTC (rev 8244) @@ -34,6 +34,9 @@ #include "dllutil.h" +UINT (WINAPI *pDragQueryFileW)(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch); +DWORD (WINAPI *pGetFileAttributesW)(LPCWSTR lpFileName); +BOOL (WINAPI *pSetDlgItemTextW)(HWND hDlg, int nIDDlgItem, LPCWSTR lpString); 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); @@ -55,12 +58,13 @@ { "GetDpiForWindow", (void **)&pGetDpiForWindow }, { "MonitorFromRect", (void **)&pMonitorFromRect }, { "AdjustWindowRectExForDpi", (void **)&pAdjustWindowRectExForDpi }, - { NULL }, + { "SetDlgItemTextW", (void **)&pSetDlgItemTextW }, + { NULL, NULL }, }; static const APIInfo Lists_msimg32[] = { { "AlphaBlend", (void **)&pAlphaBlend }, - { NULL }, + { NULL, NULL }, }; static const APIInfo Lists_gdi32[] = { @@ -68,20 +72,32 @@ { "RemoveFontResourceExA", (void **)&pRemoveFontResourceExA }, { "AddFontResourceExW", (void **)&pAddFontResourceExW }, { "RemoveFontResourceExW", (void **)&pRemoveFontResourceExW }, - { NULL }, + { NULL, NULL }, }; static const APIInfo Lists_Shcore[] = { { "GetDpiForMonitor", (void **)&pGetDpiForMonitor }, - { NULL }, + { NULL, NULL }, }; +static const APIInfo Lists_kernel32[] = { + { "GetFileAttributesW", (void **)&pGetFileAttributesW }, + { NULL, NULL }, +}; + +static const APIInfo Lists_shell32[] = { + { "DragQueryFileW", (void **)&pDragQueryFileW }, + { NULL, 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 }, { _T("Shcore.dll"), DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_Shcore }, - { NULL }, + { _T("kernel32.dll"), DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_kernel32 }, + { _T("shell32.dll"), DLL_LOAD_LIBRARY_SYSTEM, DLL_ACCEPT_NOT_EXIST, Lists_shell32 }, + { NULL, DLL_GET_MODULE_HANDLE, DLL_ACCEPT_NOT_EXIST, NULL }, }; void WinCompatInit() Modified: branches/unicode_buf/teraterm/common/compat_win.h =================================================================== --- branches/unicode_buf/teraterm/common/compat_win.h 2019-10-02 15:06:32 UTC (rev 8243) +++ branches/unicode_buf/teraterm/common/compat_win.h 2019-10-02 15:06:44 UTC (rev 8244) @@ -67,6 +67,9 @@ #define OPENFILENAME_SIZE_VERSION_400A 76 #endif +extern UINT (WINAPI *pDragQueryFileW)(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch); +extern DWORD (WINAPI *pGetFileAttributesW)(LPCWSTR lpFileName); +extern BOOL (WINAPI *pSetDlgItemTextW)(HWND hDlg, int nIDDlgItem, LPCWSTR lpString); extern BOOL (WINAPI *pAlphaBlend)(HDC,int,int,int,int,HDC,int,int,int,int,BLENDFUNCTION); extern BOOL (WINAPI *pEnumDisplayMonitors)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); extern HMONITOR (WINAPI *pMonitorFromRect)(LPCRECT lprc, DWORD dwFlags); Added: branches/unicode_buf/teraterm/common/layer_for_unicode.cpp =================================================================== --- branches/unicode_buf/teraterm/common/layer_for_unicode.cpp (rev 0) +++ branches/unicode_buf/teraterm/common/layer_for_unicode.cpp 2019-10-02 15:06:44 UTC (rev 8244) @@ -0,0 +1,103 @@ +/* + * Copyright (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. + */ + +/* + * W to A Wrapper + * + * API\x96\xBC\x82\xCDW\x94ł̓\xAA\x82\xC9 '_' \x82\xF0\x95t\x82\xAF\x82\xBD\x82\xE0\x82̂\xF0\x8Eg\x97p\x82\xB7\x82\xE9 + */ + +#include <windows.h> + +#include "codeconv.h" +#include "compat_win.h" + +#include "layer_for_unicode.h" + +BOOL _SetDlgItemTextW(HWND hDlg, int nIDDlgItem, LPCWSTR lpString) +{ + if (pSetDlgItemTextW != NULL) { + return pSetDlgItemTextW(hDlg, nIDDlgItem, lpString); + } + + char *strA = ToCharW(lpString); + BOOL retval = SetDlgItemTextA(hDlg, nIDDlgItem, strA); + free(strA); + return retval; +} + +UINT _DragQueryFileW(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch) +{ + if (pDragQueryFileW != NULL) { + return DragQueryFileW(hDrop, iFile, lpszFile, cch); + } + + UINT retval; + if (iFile == 0xffffffff) { + // \x83t\x83@\x83C\x83\x8B\x90\x94\x96₢\x8D\x87\x82킹 + retval = DragQueryFileA(hDrop, iFile, NULL, 0); + } + else if (lpszFile == NULL) { + // \x83t\x83@\x83C\x83\x8B\x96\xBC\x82̕\xB6\x8E\x9A\x90\x94\x96₢\x8D\x87\x82킹 + char FileNameA[MAX_PATH]; + retval = DragQueryFileA(hDrop, iFile, FileNameA, MAX_PATH); + if (retval != 0) { + wchar_t *FileNameW = ToWcharA(FileNameA); + retval = (UINT)(wcslen(FileNameW) + 1); + free(FileNameW); + } + } + else { + // \x83t\x83@\x83C\x83\x8B\x96\xBC\x8E擾 + char FileNameA[MAX_PATH]; + retval = DragQueryFileA(hDrop, iFile, FileNameA, MAX_PATH); + if (retval != 0) { + wchar_t *FileNameW = ToWcharA(FileNameA); + wcscpy_s(lpszFile, cch, FileNameW); + free(FileNameW); + } + } + return retval; +} + +DWORD _GetFileAttributesW(LPCWSTR lpFileName) +{ + if (pGetFileAttributesW != NULL) { + return GetFileAttributesW(lpFileName); + } + + char *FileNameA; + if (lpFileName == NULL) { + FileNameA = NULL; + } else { + FileNameA = ToCharW(lpFileName); + } + const DWORD attr = GetFileAttributesA(FileNameA); + free(FileNameA); + return attr; +} Copied: branches/unicode_buf/teraterm/common/layer_for_unicode.h (from rev 8243, branches/unicode_buf/teraterm/teraterm/dnddlg.h) =================================================================== --- branches/unicode_buf/teraterm/common/layer_for_unicode.h (rev 0) +++ branches/unicode_buf/teraterm/common/layer_for_unicode.h 2019-10-02 15:06:44 UTC (rev 8244) @@ -0,0 +1,49 @@ +/* + * Copyright (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. + */ + +/* + * W to A Wrapper + * + * API\x96\xBC\x82\xCDW\x94ł̓\xAA\x82\xC9 '_' \x82\xF0\x95t\x82\xAF\x82\xBD\x82\xE0\x82̂\xF0\x8Eg\x97p\x82\xB7\x82\xE9 + */ + +#pragma once + +#include <windows.h> + +#ifdef __cplusplus +extern "C" { +#endif + +BOOL _SetDlgItemTextW(HWND hDlg, int nIDDlgItem, LPCWSTR lpString); +DWORD _GetFileAttributesW(LPCWSTR lpFileName); +UINT _DragQueryFileW(HDROP hDrop, UINT iFile, LPWSTR lpszFile, UINT cch); + +#ifdef __cplusplus +} +#endif Modified: branches/unicode_buf/teraterm/teraterm/CMakeLists.txt =================================================================== --- branches/unicode_buf/teraterm/teraterm/CMakeLists.txt 2019-10-02 15:06:32 UTC (rev 8243) +++ branches/unicode_buf/teraterm/teraterm/CMakeLists.txt 2019-10-02 15:06:44 UTC (rev 8244) @@ -44,6 +44,8 @@ ../common/codeconv.cpp ../common/tipwin.h ../common/tipwin.cpp + ../common/layer_for_unicode.h + ../common/layer_for_unicode.cpp # ../teraterm/unisym2decsp.map ../teraterm/uni2sjis.map Modified: branches/unicode_buf/teraterm/teraterm/dnddlg.cpp =================================================================== --- branches/unicode_buf/teraterm/teraterm/dnddlg.cpp 2019-10-02 15:06:32 UTC (rev 8243) +++ branches/unicode_buf/teraterm/teraterm/dnddlg.cpp 2019-10-02 15:06:44 UTC (rev 8244) @@ -37,9 +37,10 @@ #include "i18n.h" #include "ttlib.h" #include "dlglib.h" +#include "layer_for_unicode.h" struct DrapDropDlgParam { - const TCHAR *TargetFilename; + const wchar_t *TargetFilename; enum drop_type DropType; unsigned char DropTypePaste; bool ScpEnable; @@ -92,7 +93,7 @@ SetDlgTexts(hDlgWnd, TextInfos, _countof(TextInfos), Param->UILanguageFile); // target file - SetDlgItemText(hDlgWnd, IDC_FILENAME_EDIT, Param->TargetFilename); + _SetDlgItemTextW(hDlgWnd, IDC_FILENAME_EDIT, Param->TargetFilename); // checkbox CheckRadioButton(hDlgWnd, IDC_SCP_RADIO, IDC_PASTE_RADIO, @@ -243,7 +244,7 @@ enum drop_type ShowDropDialogBox( HINSTANCE hInstance, HWND hWndParent, - const TCHAR *TargetFilename, + const wchar_t *TargetFilename, enum drop_type DefaultDropType, int RemaingFileCount, bool EnableSCP, @@ -268,7 +269,7 @@ Param.ScpSendDirSize = _countof(pts->ScpSendDir); Param.UILanguageFile = pts->UILanguageFile; - int ret = TTDialogBoxParam( + INT_PTR ret = TTDialogBoxParam( hInstance, MAKEINTRESOURCE(IDD_DAD_DIALOG), hWndParent, (DLGPROC)OnDragDropDlgProc, (LPARAM)&Param); Modified: branches/unicode_buf/teraterm/teraterm/dnddlg.h =================================================================== --- branches/unicode_buf/teraterm/teraterm/dnddlg.h 2019-10-02 15:06:32 UTC (rev 8243) +++ branches/unicode_buf/teraterm/teraterm/dnddlg.h 2019-10-02 15:06:44 UTC (rev 8244) @@ -42,7 +42,7 @@ enum drop_type ShowDropDialogBox( HINSTANCE hInstance, HWND hWndParent, - const TCHAR *TargetFilename, + const wchar_t *TargetFilename, enum drop_type DefaultDropType, int RemaingFileCount, bool EnableSCP, Modified: branches/unicode_buf/teraterm/teraterm/vtwin.cpp =================================================================== --- branches/unicode_buf/teraterm/teraterm/vtwin.cpp 2019-10-02 15:06:32 UTC (rev 8243) +++ branches/unicode_buf/teraterm/teraterm/vtwin.cpp 2019-10-02 15:06:44 UTC (rev 8244) @@ -89,6 +89,8 @@ #if UNICODE_DEBUG #include "tipwin.h" #endif +#include "codeconv.h" +#include "layer_for_unicode.h" #include "initguid.h" //#include "Usbiodef.h" @@ -1913,24 +1915,19 @@ DeleteNotifyIcon(&cv); } -static void EscapeFilename(const char *src, char *dest) +static void EscapeFilename(const wchar_t *src, wchar_t *dest) { -#define ESCAPE_CHARS " ;&()$!`'[]{}#^~" - const char *s = src; - char *d = dest; +#define ESCAPE_CHARS L" ;&()$!`'[]{}#^~" + const wchar_t *s = src; + wchar_t *d = dest; while (*s) { - if (isleadbyte(*s)) { // multi-byte - *d++ = *s++; - *d++ = *s++; - continue; - } - char c = *s++; - if (c == '\\') { + wchar_t c = *s++; + if (c == L'\\') { // \x83p\x83X\x82̋\xE6\x90\xE8\x82\xF0 \ -> / \x82\xD6 *d = '/'; - } else if (strchr(ESCAPE_CHARS, c) != NULL) { + } else if (wcschr(ESCAPE_CHARS, c) != NULL) { // \x83G\x83X\x83P\x81[\x83v\x82\xAA\x95K\x97v\x82ȕ\xB6\x8E\x9A - *d++ = '\\'; + *d++ = L'\\'; *d = c; } else { *d = c; @@ -1940,24 +1937,22 @@ *d = '\0'; // null-terminate } -static void PasteString(PComVar cv, const char *str, bool escape) +static void PasteString(PComVar cv, const wchar_t *str, bool escape) { - PCHAR ptr = (PCHAR)str; - char *tmpbuf = NULL; + wchar_t *ptr = (wchar_t *)str; + wchar_t *tmpbuf = NULL; if (escape) { - size_t len = strlen(str) * 2; - tmpbuf = (char *)malloc(len); + const size_t len = wcslen(str) * sizeof(wchar_t) * 2; + tmpbuf = (wchar_t *)malloc(len); EscapeFilename(str, tmpbuf); ptr = tmpbuf; } // console\x82֑\x97\x90M - while (*ptr) { - CommTextOut(cv, ptr, 1); - if (ts.LocalEcho > 0) { - CommTextEcho(cv, ptr, 1); - } - ptr++; + const size_t len = wcslen(ptr); + CommTextOutW(cv, ptr, len); + if (ts.LocalEcho > 0) { + CommTextEchoW(cv, ptr, len); } if (tmpbuf != NULL) free(tmpbuf); @@ -1964,7 +1959,7 @@ } /* \x93\xFC\x97͂̓t\x83@\x83C\x83\x8B\x82̂\xDD(\x83t\x83H\x83\x8B\x83_\x82͊܂܂\xEA\x82Ȃ\xA2) */ -static bool SendScp(char *Filenames[], int FileCount, const char *SendDir) +static bool SendScp(wchar_t *Filenames[], int FileCount, const char *SendDir) { typedef int (CALLBACK *PSSH_start_scp)(char *, char *); static PSSH_start_scp func = NULL; @@ -1988,8 +1983,9 @@ } for (int i = 0; i < FileCount; i++) { - const char *FileName = Filenames[i]; + char *FileName = ToU8W(Filenames[i]); func((char *)FileName, ts.ScpSendDir); + free(FileName); } return true; } @@ -2018,8 +2014,8 @@ int FileCount = 0; int DirectoryCount = 0; for (int i = 0; i < DropListCount; i++) { - const char *FileName = DropLists[i]; - const DWORD attr = GetFileAttributes(FileName); + const wchar_t *FileName = DropLists[i]; + const DWORD attr = _GetFileAttributesW(FileName); if (attr == INVALID_FILE_ATTRIBUTES) { FileCount++; } else if (attr & FILE_ATTRIBUTE_DIRECTORY) { @@ -2097,7 +2093,7 @@ } for (int i = 0; i < DropListCount; i++) { - const char *FileName = DropLists[i]; + const wchar_t *FileName = DropLists[i]; if (!DoSameProcess) { bool DoSameProcessNextDrop; @@ -2136,7 +2132,9 @@ case DROP_TYPE_SEND_FILE_BINARY: if (SendVar==NULL && NewFileVar(&SendVar)) { HelpId = HlpFileSend; - strncpy_s(SendVar->FullName, sizeof(SendVar->FullName), FileName, _TRUNCATE); + char *FileNameA = ToCharW(FileName); + strncpy_s(SendVar->FullName, sizeof(SendVar->FullName), FileNameA, _TRUNCATE); + free(FileNameA); SendVar->DirLen = 0; ts.TransBin = DropType == DROP_TYPE_SEND_FILE ? 0 : 1; FileSendStart(); @@ -2166,7 +2164,7 @@ PasteString(&cv, FileName, escape); if (DropListCount > 1 && i < DropListCount - 1) { - const char *separator = (DropTypePaste & DROP_TYPE_PASTE_NEWLINE) ? "\n" : " "; + const wchar_t *separator = (DropTypePaste & DROP_TYPE_PASTE_NEWLINE) ? L"\n" : L" "; PasteString(&cv, separator, false); } @@ -2177,7 +2175,7 @@ case DROP_TYPE_SCP: { // send by scp - char **FileNames = &DropLists[i]; + wchar_t **FileNames = &DropLists[i]; int FileCount = DoSameProcess ? DropListCount - i : 1; if (!SendScp(FileNames, FileCount, ts.ScpSendDir)) { goto finish; @@ -2200,14 +2198,17 @@ { const UINT ShowDialog = ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0) ? 1 : 0; - DropListCount = DragQueryFile(hDropInfo, -1, NULL, 0); - DropLists = (char **)malloc(sizeof(char *) * DropListCount); + DropListCount = _DragQueryFileW(hDropInfo, -1, NULL, 0); + DropLists = (wchar_t **)malloc(sizeof(wchar_t *) * DropListCount); for (int i = 0; i < DropListCount; i++) { - const UINT cch = DragQueryFile(hDropInfo, i, NULL, 0) + 1; - char *FileName = (char *)malloc(cch); + const UINT cch = _DragQueryFileW(hDropInfo, i, NULL, 0) + 1; + if (cch == 0) { + continue; + } + wchar_t *FileName = (wchar_t *)malloc(sizeof(wchar_t) * cch); + _DragQueryFileW(hDropInfo,i,FileName,cch); DropLists[i] = FileName; - DragQueryFile(hDropInfo,i,FileName,cch); } ::PostMessage(HVTWin, WM_USER_DROPNOTIFY, ShowDialog, 0); Modified: branches/unicode_buf/teraterm/teraterm/vtwin.h =================================================================== --- branches/unicode_buf/teraterm/teraterm/vtwin.h 2019-10-02 15:06:32 UTC (rev 8243) +++ branches/unicode_buf/teraterm/teraterm/vtwin.h 2019-10-02 15:06:44 UTC (rev 8244) @@ -55,7 +55,7 @@ SetupMenu, ControlMenu, WinMenu, HelpMenu; // drag and drop handle - TCHAR **DropLists; + wchar_t **DropLists; int DropListCount; void DropListFree();