Revision: 7507 http://sourceforge.jp/projects/ttssh2/scm/svn/commits/7507 Author: zmatsuo Date: 2019-03-23 02:19:15 +0900 (Sat, 23 Mar 2019) Log Message: ----------- teraterm/common/tipwin.cpp,h を追加 teraterm/teraterm/sizetip.c から分離 ttssh2/ttxssh/auth.c passphraseに制御コードを入力すると tooltip が出るようにした 特に CTRL+V のときは特に SHIFT+Insert を案内するようにした(未i18n化) [From Clipboard]ボタンを追加した Modified Paths: -------------- trunk/teraterm/teraterm/CMakeLists.txt trunk/teraterm/teraterm/sizetip.c trunk/teraterm/teraterm/ttermpro.vcproj trunk/ttssh2/ttxssh/CMakeLists.txt trunk/ttssh2/ttxssh/auth.c trunk/ttssh2/ttxssh/resource.h trunk/ttssh2/ttxssh/ttxssh.rc trunk/ttssh2/ttxssh/ttxssh.vcproj Added Paths: ----------- trunk/teraterm/common/tipwin.cpp trunk/teraterm/common/tipwin.h -------------- next part -------------- Added: trunk/teraterm/common/tipwin.cpp =================================================================== --- trunk/teraterm/common/tipwin.cpp (rev 0) +++ trunk/teraterm/common/tipwin.cpp 2019-03-22 17:19:15 UTC (rev 7507) @@ -0,0 +1,289 @@ +// Import from PuTTY 0.60 windows/sizetip.c +/* + * PuTTY is copyright 1997-2004 Simon Tatham. + * + * Portions copyright Robert de Bath, Joris van Rantwijk, Delian + * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, + * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus + * Kuhn, Colin Watson, Christopher Staite, and CORE SDI S.A. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE + * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +/* + * Copyright (C) 2008-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. + */ +/* based on windows/sizetip.c from PuTTY 0.60 */ + +#include <windows.h> +#include <stdio.h> +#include <tchar.h> +#include <commctrl.h> // for CCSIZEOF_STRUCT() +#include <assert.h> + +#include "TipWin.h" + +#define FRAME_WIDTH 6 + +static ATOM tip_class = 0; + +typedef struct tagTipWinData { + HFONT tip_font; + COLORREF tip_bg; + COLORREF tip_text; + HWND tip_wnd; + HWND hParentWnd; + int tip_enabled; + const TCHAR *str; + size_t str_len; + RECT str_rect; + RECT rect; + int px; + int py; + BOOL auto_destroy; +} TipWin; + +static void CalcStrRect(TipWin *pTipWin) +{ + HDC hdc = CreateCompatibleDC(NULL); + SelectObject(hdc, pTipWin->tip_font); + pTipWin->str_rect.top = 0; + pTipWin->str_rect.left = 0; + DrawText(hdc, pTipWin->str, pTipWin->str_len, + &pTipWin->str_rect, DT_LEFT|DT_CALCRECT); + DeleteDC(hdc); +} + +static LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg, + WPARAM wParam, LPARAM lParam) +{ + TipWin *pTipWin = (TipWin *)GetWindowLongPtr(hWnd, GWLP_USERDATA); + + switch (nMsg) { + case WM_CREATE: { + CREATESTRUCTA *create_st = (CREATESTRUCTA *)lParam; + pTipWin = (TipWin *)create_st->lpCreateParams; + SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)pTipWin); + pTipWin->tip_wnd = hWnd; + break; + } + + case WM_ERASEBKGND: + return TRUE; + + case WM_PAINT: + { + HBRUSH hbr; + HGDIOBJ holdbr; + RECT cr; + HDC hdc; + + PAINTSTRUCT ps; + hdc = BeginPaint(hWnd, &ps); + + SelectObject(hdc, pTipWin->tip_font); + SelectObject(hdc, GetStockObject(BLACK_PEN)); + + hbr = CreateSolidBrush(pTipWin->tip_bg); + holdbr = SelectObject(hdc, hbr); + + GetClientRect(hWnd, &cr); + Rectangle(hdc, cr.left, cr.top, cr.right, cr.bottom); + + SetTextColor(hdc, pTipWin->tip_text); + SetBkColor(hdc, pTipWin->tip_bg); + + { + RECT rect = pTipWin->str_rect; + rect.left = rect.left + FRAME_WIDTH; + rect.right = rect.right + FRAME_WIDTH; + rect.top = rect.top + FRAME_WIDTH; + rect.bottom = rect.bottom + FRAME_WIDTH; + DrawText(hdc, pTipWin->str, pTipWin->str_len, &rect, DT_LEFT); + } + + SelectObject(hdc, holdbr); + DeleteObject(hbr); + + EndPaint(hWnd, &ps); + } + return 0; + + case WM_NCHITTEST: + return HTTRANSPARENT; + + case WM_DESTROY: + DeleteObject(pTipWin->tip_font); + pTipWin->tip_font = NULL; + break; + + case WM_SETTEXT: + { + LPCTSTR str = (LPCTSTR) lParam; + const int str_width = pTipWin->str_rect.right - pTipWin->str_rect.left; + const int str_height = pTipWin->str_rect.bottom - pTipWin->str_rect.top; + + free((void *)(pTipWin->str)); + pTipWin->str_len = _tcslen(str); + pTipWin->str = _tcsdup(str); + CalcStrRect(pTipWin); + + SetWindowPos(hWnd, NULL, + 0, 0, + str_width + FRAME_WIDTH * 2, str_height + FRAME_WIDTH * 2, + SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); + InvalidateRect(hWnd, NULL, FALSE); + + } + break; + + case WM_NCDESTROY: + if (pTipWin->auto_destroy) { + free((void *)pTipWin->str); + free(pTipWin); + } + break; + default: + break; + } + + return DefWindowProc(hWnd, nMsg, wParam, lParam); +} + +// todo: dlglib.c\x82ɓ\xAF\x93\x99\x82ȃR\x81[\x83h\x82\xA0\x82\xE8 +void GetMessageboxFont(LOGFONT *logfont) +{ + NONCLIENTMETRICS nci; + const int st_size = CCSIZEOF_STRUCT(NONCLIENTMETRICS, lfMessageFont); + BOOL r; + + memset(&nci, 0, sizeof(nci)); + nci.cbSize = st_size; + r = SystemParametersInfo(SPI_GETNONCLIENTMETRICS, st_size, &nci, 0); + assert(r == TRUE); + *logfont = nci.lfStatusFont; +} + +static void register_class(HINSTANCE hInst) +{ + if (!tip_class) { + WNDCLASS wc; + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = SizeTipWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInst; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName = _T("SizeTipClass"); + + tip_class = RegisterClass(&wc); + } +} + +/* Create the tip window */ +static void create_tipwin(TipWin *pTipWin, HINSTANCE hInst, int cx, int cy) +{ + const TCHAR *str = pTipWin->str; + HWND hParnetWnd = pTipWin->hParentWnd; + const int str_width = pTipWin->str_rect.right - pTipWin->str_rect.left; + const int str_height = pTipWin->str_rect.bottom - pTipWin->str_rect.top; + pTipWin->tip_wnd = + CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, + MAKEINTRESOURCE(tip_class), + str, WS_POPUP, + cx, cy, + str_width + FRAME_WIDTH * 2, str_height + FRAME_WIDTH * 2, + hParnetWnd, NULL, hInst, pTipWin); + assert(pTipWin->tip_wnd != NULL); +} + +TipWin *TipWinCreate(HWND src, int cx, int cy, const TCHAR *str) +{ + TipWin *pTipWin; + HINSTANCE hInst = (HINSTANCE)GetWindowLongPtr(src, GWLP_HINSTANCE); + LOGFONT logfont; + + register_class(hInst); + pTipWin = (TipWin *)malloc(sizeof(TipWin)); + if (pTipWin == NULL) return NULL; + pTipWin->str_len = _tcslen(str); + pTipWin->str = _tcsdup(str); + pTipWin->px = cx; + pTipWin->py = cy; + pTipWin->tip_bg = GetSysColor(COLOR_INFOBK); + pTipWin->tip_text = GetSysColor(COLOR_INFOTEXT); + GetMessageboxFont(&logfont); + pTipWin->tip_font = CreateFontIndirect(&logfont); + CalcStrRect(pTipWin); + pTipWin->hParentWnd = src; + create_tipwin(pTipWin, hInst, cx, cy); + + pTipWin->hParentWnd = src; + pTipWin->auto_destroy = TRUE; + ShowWindow(pTipWin->tip_wnd, SW_SHOWNOACTIVATE); + return pTipWin; +} + +void TipWinSetPos(int x, int y) +{ +} + +void TipWinSetText(TipWin *tWin, TCHAR *text) +{ + if (tWin != NULL) { + HWND tip_wnd = tWin->tip_wnd; + SetWindowText(tip_wnd, text); + } +} + +void TipWinDestroy(TipWin *tWin) +{ + if (tWin != NULL) { + HWND tip_wnd = tWin->tip_wnd; + DestroyWindow(tip_wnd); + } +} + Added: trunk/teraterm/common/tipwin.h =================================================================== --- trunk/teraterm/common/tipwin.h (rev 0) +++ trunk/teraterm/common/tipwin.h 2019-03-22 17:19:15 UTC (rev 7507) @@ -0,0 +1,17 @@ + +#include <windows.h> +#include <tchar.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct tagTipWinData TipWin; + +TipWin *TipWinCreate(HWND src, int cx, int cy, const TCHAR *str); +void TipWinSetText(TipWin *tWin, TCHAR *text); +void TipWinDestroy(TipWin *tWin); + +#ifdef __cplusplus +} +#endif Modified: trunk/teraterm/teraterm/CMakeLists.txt =================================================================== --- trunk/teraterm/teraterm/CMakeLists.txt 2019-03-22 14:38:12 UTC (rev 7506) +++ trunk/teraterm/teraterm/CMakeLists.txt 2019-03-22 17:19:15 UTC (rev 7507) @@ -33,6 +33,8 @@ ../common/dllutil.h ../common/codeconv.h ../common/codeconv.cpp + ../common/tipwin.h + ../common/tipwin.cpp # ../teraterm/unisym2decsp.map ../teraterm/uni2sjis.map Modified: trunk/teraterm/teraterm/sizetip.c =================================================================== --- trunk/teraterm/teraterm/sizetip.c 2019-03-22 14:38:12 UTC (rev 7506) +++ trunk/teraterm/teraterm/sizetip.c 2019-03-22 17:19:15 UTC (rev 7507) @@ -1,33 +1,5 @@ -// Import from PuTTY 0.60 windows/sizetip.c -/* - * PuTTY is copyright 1997-2004 Simon Tatham. - * - * Portions copyright Robert de Bath, Joris van Rantwijk, Delian - * Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas Barry, - * Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, Markus - * Kuhn, Colin Watson, Christopher Staite, and CORE SDI S.A. - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE - * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -/* - * Copyright (C) 2008-2018 TeraTerm Project +/* + * Copyright (C) 2008-2019 TeraTerm Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,6 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* original idea from PuTTY 0.60 windows/sizetip.c */ #include "teraterm.h" #include "tttypes.h" @@ -61,91 +34,58 @@ #include <windows.h> #include <stdio.h> +#include <tchar.h> -// -// \x83\x8A\x83T\x83C\x83Y\x83c\x81[\x83\x8B\x83`\x83b\x83v (based on PuTTY sizetip.c) -// -static ATOM tip_class = 0; -static HFONT tip_font; -static COLORREF tip_bg; -static COLORREF tip_text; -static HWND tip_wnd = NULL; +#include "TipWin.h" + +static TipWin *SizeTip; static int tip_enabled = 0; -static LRESULT CALLBACK SizeTipWndProc(HWND hWnd, UINT nMsg, - WPARAM wParam, LPARAM lParam) +/** + * point を + * スクリーンからはみ出している場合、入るように補正する + * NearestMonitor が TRUE のとき、最も近いモニタ + * FALSEのとき、マウスのあるモニタに移動させる + * ディスプレイの端から FrameWidth(pixel) より離れるようにする + */ +static void FixPosFromFrame(POINT *point, int FrameWidth, BOOL NearestMonitor) { + if (HasMultiMonitorSupport()) { + // マルチモニタがサポートされている場合 + HMONITOR hm; + MONITORINFO mi; - switch (nMsg) { - case WM_ERASEBKGND: - return TRUE; - - case WM_PAINT: - { - HBRUSH hbr; - HGDIOBJ holdbr; - RECT cr; - int wtlen; - LPTSTR wt; - HDC hdc; - - PAINTSTRUCT ps; - hdc = BeginPaint(hWnd, &ps); - - SelectObject(hdc, tip_font); - SelectObject(hdc, GetStockObject(BLACK_PEN)); - - hbr = CreateSolidBrush(tip_bg); - holdbr = SelectObject(hdc, hbr); - - GetClientRect(hWnd, &cr); - Rectangle(hdc, cr.left, cr.top, cr.right, cr.bottom); - - wtlen = GetWindowTextLength(hWnd); - wt = (LPTSTR) malloc((wtlen + 1) * sizeof(TCHAR)); - GetWindowText(hWnd, wt, wtlen + 1); - - SetTextColor(hdc, tip_text); - SetBkColor(hdc, tip_bg); - - TextOut(hdc, cr.left + 3, cr.top + 3, wt, wtlen); - - free(wt); - - SelectObject(hdc, holdbr); - DeleteObject(hbr); - - EndPaint(hWnd, &ps); + hm = MonitorFromPoint(*point, MONITOR_DEFAULTTONULL); + if (hm == NULL) { + if (NearestMonitor) { + // 最も近いモニタに表示する + hm = MonitorFromPoint(*point, MONITOR_DEFAULTTONEAREST); + } else { + // スクリーンからはみ出している場合はマウスのあるモニタに表示する + GetCursorPos(point); + hm = MonitorFromPoint(*point, MONITOR_DEFAULTTONEAREST); } - return 0; + } - case WM_NCHITTEST: - return HTTRANSPARENT; - - case WM_DESTROY: - DeleteObject(tip_font); - tip_font = NULL; - break; - - case WM_SETTEXT: - { - LPCTSTR str = (LPCTSTR) lParam; - SIZE sz; - HDC hdc = CreateCompatibleDC(NULL); - - SelectObject(hdc, tip_font); - GetTextExtentPoint32(hdc, str, strlen(str), &sz); - - SetWindowPos(hWnd, NULL, 0, 0, sz.cx + 6, sz.cy + 6, - SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE); - InvalidateRect(hWnd, NULL, FALSE); - - DeleteDC(hdc); - } - break; + mi.cbSize = sizeof(MONITORINFO); + GetMonitorInfo(hm, &mi); + if (point->x < mi.rcMonitor.left + FrameWidth) { + point->x = mi.rcMonitor.left + FrameWidth; + } + if (point->y < mi.rcMonitor.top + FrameWidth) { + point->y = mi.rcMonitor.top + FrameWidth; + } } - - return DefWindowProc(hWnd, nMsg, wParam, lParam); + else + { + // マルチモニタがサポートされていない場合 + if (point->x < FrameWidth) { + point->x = FrameWidth; + } + if (point->y < FrameWidth) { + point->y = FrameWidth; + } + } } void UpdateSizeTip(HWND src, int cx, int cy) @@ -155,130 +95,34 @@ if (!tip_enabled) return; - if (!tip_wnd) { - NONCLIENTMETRICS nci; - - /* First make sure the window class is registered */ - - if (!tip_class) { - WNDCLASS wc; - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = SizeTipWndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInst; - wc.hIcon = NULL; - wc.hCursor = NULL; - wc.hbrBackground = NULL; - wc.lpszMenuName = NULL; - wc.lpszClassName = "SizeTipClass"; - - tip_class = RegisterClass(&wc); - } -#if 0 - /* Default values based on Windows Standard color scheme */ - - tip_font = GetStockObject(SYSTEM_FONT); - tip_bg = RGB(255, 255, 225); - tip_text = RGB(0, 0, 0); -#endif - - /* Prepare other GDI objects and drawing info */ - - tip_bg = GetSysColor(COLOR_INFOBK); - tip_text = GetSysColor(COLOR_INFOTEXT); - - memset(&nci, 0, sizeof(NONCLIENTMETRICS)); - nci.cbSize = sizeof(NONCLIENTMETRICS); - SystemParametersInfo(SPI_GETNONCLIENTMETRICS, - sizeof(NONCLIENTMETRICS), &nci, 0); - tip_font = CreateFontIndirect(&nci.lfStatusFont); - } - /* Generate the tip text */ - sprintf(str, "%dx%d", cx, cy); + _stprintf_s(str, _countof(str), _T("%dx%d"), cx, cy); - if (!tip_wnd) { - HDC hdc; - SIZE sz; + if (SizeTip == NULL) { RECT wr; - int ix, iy; - HMONITOR hm; - - /* calculate the tip's size */ - - hdc = CreateCompatibleDC(NULL); - GetTextExtentPoint32(hdc, str, strlen(str), &sz); - DeleteDC(hdc); - + POINT point; + // ウィンドウの位置を取得 GetWindowRect(src, &wr); - - ix = wr.left; - iy = wr.top - sz.cy; - - if (HasMultiMonitorSupport()) { - // \x83}\x83\x8B\x83`\x83\x82\x83j\x83^\x82\xAA\x83T\x83|\x81[\x83g\x82\xB3\x82\xEA\x82Ă\xA2\x82\xE9\x8Fꍇ - POINT p; - MONITORINFO mi; - - p.x = ix; - p.y = iy; - - hm = MonitorFromPoint(p, MONITOR_DEFAULTTONULL); - - if (hm == NULL) { -#if 1 - // \x83c\x81[\x83\x8B\x83`\x83b\x83v\x82\xAA\x83X\x83N\x83\x8A\x81[\x83\x93\x82\xA9\x82\xE7\x82͂ݏo\x82\xB5\x82Ă\xA2\x82\xE9\x8Fꍇ\x82̓}\x83E\x83X\x82̂\xA0\x82郂\x83j\x83^\x82ɕ\\x8E\xA6\x82\xB7\x82\xE9 - GetCursorPos(&p); - hm = MonitorFromPoint(p, MONITOR_DEFAULTTONEAREST); -#else - // \x83c\x81[\x83\x8B\x83`\x83b\x83v\x82\xAA\x83X\x83N\x83\x8A\x81[\x83\x93\x82\xA9\x82\xE7\x82͂ݏo\x82\xB5\x82Ă\xA2\x82\xE9\x8Fꍇ\x82͍ł\xE0\x8B߂\xA2\x83\x82\x83j\x83^\x82ɕ\\x8E\xA6\x82\xB7\x82\xE9 - hm = MonitorFromPoint(p, MONITOR_DEFAULTTONEAREST); -#endif - } - - mi.cbSize = sizeof(MONITORINFO); - GetMonitorInfo(hm, &mi); - if (ix < mi.rcMonitor.left + 16) { - ix = mi.rcMonitor.left + 16; - } - if (iy < mi.rcMonitor.top + 16) { - iy = mi.rcMonitor.top + 16; - } - } - else { - // \x83}\x83\x8B\x83`\x83\x82\x83j\x83^\x82\xAA\x83T\x83|\x81[\x83g\x82\xB3\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x8Fꍇ - if (ix < 16) { - ix = 16; - } - if (iy < 16) { - iy = 16; - } - } - - /* Create the tip window */ - - tip_wnd = - CreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_TOPMOST, - MAKEINTRESOURCE(tip_class), str, WS_POPUP, ix, - iy, sz.cx, sz.cy, NULL, NULL, hInst, NULL); - - ShowWindow(tip_wnd, SW_SHOWNOACTIVATE); - + // sizetipを出す位置は、ウィンドウ左上-(8,16) + point.x = wr.left - 16; + point.y = wr.top - 8; + FixPosFromFrame(&point, 16, FALSE); + cx = point.x; + cy = point.y; + SizeTip = TipWinCreate(src, cx, cy, str); } else { - /* Tip already exists, just set the text */ - - SetWindowText(tip_wnd, str); + TipWinSetText(SizeTip, str); + //SetWindowText(tip_wnd, str); } } void EnableSizeTip(int bEnable) { - if (tip_wnd && !bEnable) { - DestroyWindow(tip_wnd); - tip_wnd = NULL; + if (SizeTip && !bEnable) { + TipWinDestroy(SizeTip); + SizeTip = NULL; } tip_enabled = bEnable; Modified: trunk/teraterm/teraterm/ttermpro.vcproj =================================================================== --- trunk/teraterm/teraterm/ttermpro.vcproj 2019-03-22 14:38:12 UTC (rev 7506) +++ trunk/teraterm/teraterm/ttermpro.vcproj 2019-03-22 17:19:15 UTC (rev 7507) @@ -401,6 +401,10 @@ RelativePath="..\common\codeconv.cpp" > </File> + <File + RelativePath="..\common\tipwin.cpp" + > + </File> </Filter> <Filter Name="Header Files" Modified: trunk/ttssh2/ttxssh/CMakeLists.txt =================================================================== --- trunk/ttssh2/ttxssh/CMakeLists.txt 2019-03-22 14:38:12 UTC (rev 7506) +++ trunk/ttssh2/ttxssh/CMakeLists.txt 2019-03-22 17:19:15 UTC (rev 7507) @@ -18,6 +18,8 @@ ../../teraterm/common/servicenames.h ../../teraterm/common/codeconv.cpp ../../teraterm/common/codeconv.h + ../../teraterm/common/tipwin.cpp + ../../teraterm/common/tipwin.h ) source_group( Modified: trunk/ttssh2/ttxssh/auth.c =================================================================== --- trunk/ttssh2/ttxssh/auth.c 2019-03-22 14:38:12 UTC (rev 7506) +++ trunk/ttssh2/ttxssh/auth.c 2019-03-22 17:19:15 UTC (rev 7507) @@ -41,6 +41,7 @@ #include "resource.h" #include "keyfiles.h" #include "libputty.h" +#include "tipwin.h" #define AUTH_START_USER_AUTH_ON_ERROR_END 1 @@ -64,6 +65,7 @@ IDC_SSHUSERHOSTS, IDC_SSHUSETIS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, IDC_SSHUSEPAGEANT, -1 }; +static TipWin *tipwin; LRESULT CALLBACK password_wnd_proc(HWND control, UINT msg, WPARAM wParam, LPARAM lParam) @@ -71,12 +73,39 @@ switch (msg) { case WM_CHAR: if ((GetKeyState(VK_CONTROL) & 0x8000) != 0) { - char chars[] = { (char) wParam, 0 }; + TCHAR chars[] = { (TCHAR) wParam, 0 }; SendMessage(control, EM_REPLACESEL, (WPARAM) TRUE, - (LPARAM) (char *) chars); + (LPARAM) (TCHAR *) chars); + + if (tipwin == NULL) { + TCHAR *s; + if (wParam == 'V' - 'A' + 1) { + s = _T("\x90\xA7\x8C䕶\x8E\x9A\x82\xF0\x93\xFC\x97͂\xB5\x82Ă\xA2\x82܂\xB7") + _T("\n") + _T("\x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x82\xA9\x82\xE7\x82̓\\x82\xE8\x95t\x82\xAF\x82̃V\x83\x87\x81[\x83g\x83J\x83b\x83g\x82\xCDCTRL+Insert\x82ł\xB7"); + } else { + s = _T("\x90\xA7\x8C䕶\x8E\x9A\x82\xF0\x93\xFC\x97͂\xB5\x82Ă\xA2\x82܂\xB7"); + } + RECT rect; + GetWindowRect(control, &rect); + tipwin = TipWinCreate(control, rect.left, rect.bottom, s); + } + return 0; + } else { + if (tipwin != NULL) { + TipWinDestroy(tipwin); + tipwin = NULL; + } } + break; + case WM_NCDESTROY: + if (tipwin != NULL) { + TipWinDestroy(tipwin); + tipwin = NULL; + } + break; } return CallWindowProc((WNDPROC) GetWindowLong(control, GWL_USERDATA), @@ -106,6 +135,7 @@ EnableWindow(GetDlgItem(dlg, IDC_SSHPASSWORDCAPTION), (!TIS_enabled && !PAGEANT_enabled)); EnableWindow(GetDlgItem(dlg, IDC_SSHPASSWORD), (!TIS_enabled && !PAGEANT_enabled)); + EnableWindow(GetDlgItem(dlg, IDC_FROM_CLIPBOARD), (!TIS_enabled && !PAGEANT_enabled)); for (i = IDC_CHOOSERSAFILE; i <= IDC_RSAFILENAME; i++) { EnableWindow(GetDlgItem(dlg, i), RSA_enabled); @@ -286,6 +316,7 @@ if (pvar->ssh2_autologin == 1) { EnableWindow(GetDlgItem(dlg, IDC_SSHPASSWORD), FALSE); EnableWindow(GetDlgItem(dlg, IDC_SSHPASSWORDCAPTION), FALSE); + EnableWindow(GetDlgItem(dlg, IDC_FROM_CLIPBOARD), FALSE); } } @@ -312,6 +343,7 @@ } else if (pvar->ssh2_authmethod == SSH_AUTH_TIS) { CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL, IDC_SSHUSETIS); EnableWindow(GetDlgItem(dlg, IDC_SSHPASSWORD), FALSE); + EnableWindow(GetDlgItem(dlg, IDC_FROM_CLIPBOARD), FALSE); SetDlgItemText(dlg, IDC_SSHPASSWORD, ""); // /auth=pageant \x82\xF0\x92lj\xC1 @@ -318,6 +350,7 @@ } else if (pvar->ssh2_authmethod == SSH_AUTH_PAGEANT) { CheckRadioButton(dlg, IDC_SSHUSEPASSWORD, MAX_AUTH_CONTROL, IDC_SSHUSEPAGEANT); EnableWindow(GetDlgItem(dlg, IDC_SSHPASSWORD), FALSE); + EnableWindow(GetDlgItem(dlg, IDC_FROM_CLIPBOARD), FALSE); SetDlgItemText(dlg, IDC_SSHPASSWORD, ""); } else { @@ -676,6 +709,46 @@ return TRUE; } +/** + * \x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x82\xA9\x82\xE7ANSI\x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8E擾\x82\xB7\x82\xE9 + * \x95\xB6\x8E\x9A\x97\xAA\x95K\x97v\x82ȂƂ\xAB\x82\xCDstrlen()\x82\xB7\x82邱\x82\xC6 + * @param hWnd + * @param emtpy TRUE\x82̂Ƃ\xAB\x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x82\xF0\x8B\xF3\x82ɂ\xB7\x82\xE9 + * @retval \x95\xB6\x8E\x9A\x97\xF1\x82ւ̃|\x83C\x83\x93\x83^ \x8Eg\x97p\x8C\xE3free()\x82\xB7\x82邱\x82\xC6 + * \x95\xB6\x8E\x9A\x82\xAA\x82Ȃ\xA2(\x82܂\xBD\x82̓G\x83\x89\x81[\x8E\x9E)\x82\xCDNULL + */ +char *GetClipboardTextA(HWND hWnd, BOOL empty) +{ + HGLOBAL hGlobal; + const char *lpStr; + size_t length; + char *pool; + + OpenClipboard(hWnd); + hGlobal = (HGLOBAL)GetClipboardData(CF_TEXT); + if (hGlobal == NULL) { + CloseClipboard(); + return NULL; + } + lpStr = (const char *)GlobalLock(hGlobal); + length = GlobalSize(hGlobal); + if (length == 0) { + pool = NULL; + } else { + pool = (char *)malloc(length + 1); // +1 for terminator + memcpy(pool, lpStr, length); + pool[length] = '\0'; + } + GlobalUnlock(hGlobal); + if (empty) { + EmptyClipboard(); + } + CloseClipboard(); + + return pool; +} + + BOOL autologin_sent_none; static BOOL CALLBACK auth_dlg_proc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) @@ -929,6 +1002,17 @@ pvar->session_settings.ForwardAgent = IsDlgButtonChecked(dlg, IDC_FORWARD_AGENT); return TRUE; + case IDC_FROM_CLIPBOARD: { + char *clipboard = GetClipboardTextA(dlg, TRUE); + if (clipboard != NULL) { + SetDlgItemTextA(dlg, IDC_SSHPASSWORD, clipboard); + free(clipboard); + SendMessage(dlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(dlg, IDOK), TRUE); + return FALSE; + } + return TRUE; + } + default: return FALSE; } Modified: trunk/ttssh2/ttxssh/resource.h =================================================================== --- trunk/ttssh2/ttxssh/resource.h 2019-03-22 14:38:12 UTC (rev 7506) +++ trunk/ttssh2/ttxssh/resource.h 2019-03-22 17:19:15 UTC (rev 7507) @@ -227,14 +227,15 @@ #define IDC_SSHDYNFROMPORT 1228 #define IDC_SSHFWDLOCALDYNAMIC_LISTEN 1229 #define IDC_SSHDYNLISTENADDR 1230 +#define IDC_FROM_CLIPBOARD 1231 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 114 +#define _APS_NEXT_RESOURCE_VALUE 115 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1231 +#define _APS_NEXT_CONTROL_VALUE 1232 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif Modified: trunk/ttssh2/ttxssh/ttxssh.rc =================================================================== --- trunk/ttssh2/ttxssh/ttxssh.rc 2019-03-22 14:38:12 UTC (rev 7506) +++ trunk/ttssh2/ttxssh/ttxssh.rc 2019-03-22 17:19:15 UTC (rev 7507) @@ -59,6 +59,7 @@ EDITTEXT IDC_SSHUSERNAME,75,29,145,12,ES_AUTOHSCROLL RTEXT "&Passphrase:",IDC_SSHPASSWORDCAPTION,14,48,56,8,0,WS_EX_RIGHT EDITTEXT IDC_SSHPASSWORD,75,46,145,12,ES_PASSWORD | ES_AUTOHSCROLL + PUSHBUTTON "&From Clipboard",IDC_FROM_CLIPBOARD,225,46,60,14 CONTROL "Remember password in &memory",IDC_REMEMBER_PASSWORD, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,75,61,132,10 CONTROL "F&orward agent",IDC_FORWARD_AGENT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,75,74,132,10 Modified: trunk/ttssh2/ttxssh/ttxssh.vcproj =================================================================== --- trunk/ttssh2/ttxssh/ttxssh.vcproj 2019-03-22 14:38:12 UTC (rev 7506) +++ trunk/ttssh2/ttxssh/ttxssh.vcproj 2019-03-22 17:19:15 UTC (rev 7507) @@ -452,6 +452,10 @@ > </File> <File + RelativePath="..\..\teraterm\common\tipwin.cpp" + > + </File> + <File RelativePath="x11util.c" > </File>