Revision: 7717 https://osdn.net/projects/ttssh2/scm/svn/commits/7717 Author: zmatsuo Date: 2019-05-30 23:27:55 +0900 (Thu, 30 May 2019) Log Message: ----------- WM_DPICHANGEメッセージのハンドリングを改善 - r7716 はスムーズにスケーリングできない場合があった - OSが提案するウィンドウサイズが、実際のサイズと大きく異なることがある - 移動先モニタディスプレイが125%などの拡大率などの場合 - DPI比率だけでは正しいサイズが算出できない - フォントサイズが単純計算で出せない - スケーリング後、WM_DPICHANGE再度発生→拡大縮小処理→…ループが発生する - DPIに合わせて、ウィンドウサイズを計算、DPIが変化しない位置に移動するようにした Revision Links: -------------- https://osdn.net/projects/ttssh2/scm/svn/commits/7716 Modified Paths: -------------- trunk/teraterm/common/compat_win.cpp trunk/teraterm/common/compat_win.h trunk/teraterm/teraterm/vtdisp.c trunk/teraterm/teraterm/vtdisp.h trunk/teraterm/teraterm/vtwin.cpp trunk/teraterm/teraterm/vtwin.h -------------- next part -------------- Modified: trunk/teraterm/common/compat_win.cpp =================================================================== --- trunk/teraterm/common/compat_win.cpp 2019-05-28 15:23:02 UTC (rev 7716) +++ trunk/teraterm/common/compat_win.cpp 2019-05-30 14:27:55 UTC (rev 7717) @@ -44,6 +44,9 @@ 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); +HRESULT (WINAPI *pGetDpiForMonitor)(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT *dpiX, UINT *dpiY); +HMONITOR (WINAPI *pMonitorFromRect)(LPCRECT lprc, DWORD dwFlags); +BOOL (WINAPI *pAdjustWindowRectExForDpi)(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi); static const APIInfo Lists_user32[] = { { "SetLayeredWindowAttributes", (void **)&pSetLayeredWindowAttributes }, @@ -50,6 +53,8 @@ { "SetThreadDpiAwarenessContext", (void **)&pSetThreadDpiAwarenessContext }, { "IsValidDpiAwarenessContext", (void **)&pIsValidDpiAwarenessContext }, { "GetDpiForWindow", (void **)&pGetDpiForWindow }, + { "MonitorFromRect", (void **)&pMonitorFromRect }, + { "AdjustWindowRectExForDpi", (void **)&pAdjustWindowRectExForDpi }, { NULL }, }; @@ -66,10 +71,16 @@ { NULL }, }; +static const APIInfo Lists_Shcore[] = { + { "GetDpiForMonitor", (void **)&pGetDpiForMonitor }, + { 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 }, }; Modified: trunk/teraterm/common/compat_win.h =================================================================== --- trunk/teraterm/common/compat_win.h 2019-05-28 15:23:02 UTC (rev 7716) +++ trunk/teraterm/common/compat_win.h 2019-05-30 14:27:55 UTC (rev 7717) @@ -48,6 +48,15 @@ DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); #endif +#if !defined(DPI_ENUMS_DECLARED) +typedef enum MONITOR_DPI_TYPE { + MDT_EFFECTIVE_DPI = 0, + MDT_ANGULAR_DPI = 1, + MDT_RAW_DPI = 2, + MDT_DEFAULT = MDT_EFFECTIVE_DPI +} MONITOR_DPI_TYPE; +#endif + #if !defined(WM_DPICHANGED) #define WM_DPICHANGED 0x02E0 #endif @@ -60,9 +69,12 @@ 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); extern DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT dpiContext); extern BOOL (WINAPI *pIsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT dpiContext); extern UINT (WINAPI *pGetDpiForWindow)(HWND hwnd); +extern HRESULT (WINAPI *pGetDpiForMonitor)(HMONITOR hmonitor, MONITOR_DPI_TYPE dpiType, UINT *dpiX, UINT *dpiY); +extern BOOL (WINAPI *pAdjustWindowRectExForDpi)(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, DWORD dwExStyle, UINT dpi); 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); Modified: trunk/teraterm/teraterm/vtdisp.c =================================================================== --- trunk/teraterm/teraterm/vtdisp.c 2019-05-28 15:23:02 UTC (rev 7716) +++ trunk/teraterm/teraterm/vtdisp.c 2019-05-30 14:27:55 UTC (rev 7717) @@ -3899,10 +3899,3 @@ } return color; } - -void DpiChanged(void) -{ - ChangeFont(); - DispChangeWinSize(WinWidth,WinHeight); - ChangeCaret(); -} Modified: trunk/teraterm/teraterm/vtdisp.h =================================================================== --- trunk/teraterm/teraterm/vtdisp.h 2019-05-28 15:23:02 UTC (rev 7716) +++ trunk/teraterm/teraterm/vtdisp.h 2019-05-30 14:27:55 UTC (rev 7717) @@ -116,7 +116,6 @@ void DispGetRootWinSize(int *x, int *y, BOOL inPixels); int DispFindClosestColor(int red, int green, int blue); void UpdateBGBrush(void); -void DpiChanged(void); extern int WinWidth, WinHeight; extern HFONT VTFont[AttrFontMask+1]; Modified: trunk/teraterm/teraterm/vtwin.cpp =================================================================== --- trunk/teraterm/teraterm/vtwin.cpp 2019-05-28 15:23:02 UTC (rev 7716) +++ trunk/teraterm/teraterm/vtwin.cpp 2019-05-30 14:27:55 UTC (rev 7717) @@ -802,6 +802,7 @@ FirstPaint = TRUE; ScrollLock = FALSE; // \x8F\x89\x8A\xFA\x92l\x82͖\xB3\x8C\xF8 (2006.11.14 yutaka) Alpha = 255; + IgnoreSizeMessage = FALSE; /* Initialize scroll buffer */ InitBuffer(); @@ -2769,6 +2770,9 @@ void CVTWindow::OnSize(UINT nType, int cx, int cy) { + if (IgnoreSizeMessage) { + return; + } RECT R; int w, h; @@ -6304,16 +6308,99 @@ FreeTTDLG(); } -LRESULT CVTWindow::OnDpiChanged(WPARAM, LPARAM lParam) +LRESULT CVTWindow::OnDpiChanged(WPARAM wp, LPARAM) { - const RECT *SuggestedWindowRect = (RECT *)lParam; - // \x92\xF1\x88Ă\xB3\x82ꂽ\x88ʒu\x82Ɉړ\xAE\x82\xB7\x82\xE9 - // \x83T\x83C\x83Y\x82\xCDDpiChange()\x81\xA8DispChangeWinSize()\x82Őݒ肳\x82\xEA\x82\xE9 + const UINT NewDPI = LOWORD(wp); + // \x8C\xBB\x8D݂̃E\x83B\x83\x93\x83h\x83E\x83T\x83C\x83Y + RECT CurrentWindowRect; + ::GetWindowRect(m_hWnd, &CurrentWindowRect); + const int CurrentWindowWidth = CurrentWindowRect.right - CurrentWindowRect.left; + const int CurrentWindowHeight = CurrentWindowRect.bottom - CurrentWindowRect.top; + + // \x83|\x83C\x83\x93\x83^\x82̈ʒu + POINT MouseCursorScreen; + GetCursorPos(&MouseCursorScreen); + POINT MouseCursorInWindow = MouseCursorScreen; + MouseCursorInWindow.x -= CurrentWindowRect.left; + MouseCursorInWindow.y -= CurrentWindowRect.top; + + // \x90V\x82\xB5\x82\xA2DPI\x82ɍ\x87\x82킹\x82ăt\x83H\x83\x93\x83g\x82\xAC\x81A + // \x83N\x83\x89\x83C\x83A\x83\x93\x83g\x97̈\xE6\x82̃T\x83C\x83Y\x82\xF0\x8C\x88\x92肷\x82\xE9 + ChangeFont(); + ScreenWidth = WinWidth*FontWidth; + ScreenHeight = WinHeight*FontHeight; + //AdjustScrollBar(); + + // \x83X\x83N\x83\x8A\x81[\x83\x93\x83T\x83C\x83Y(=Client Area\x82̃T\x83C\x83Y)\x82\xA9\x82\xE7\x83E\x83B\x83\x93\x83h\x83E\x83T\x83C\x83Y\x82\xF0\x8EZ\x8Fo + const LONG_PTR Style = ::GetWindowLongPtr(m_hWnd, GWL_STYLE); + const LONG_PTR ExStyle = ::GetWindowLongPtr(m_hWnd, GWL_EXSTYLE); + RECT Rect = {0, 0, ScreenWidth, ScreenHeight}; + pAdjustWindowRectExForDpi(&Rect, Style, TRUE/*menu*/, ExStyle, NewDPI); + const int NewWindowWidth = Rect.right - Rect.left; + const int NewWindowHeight = Rect.bottom - Rect.top; + + // \x90V\x82\xB5\x82\xA2\x83E\x83B\x83\x93\x83h\x83E\x97̈\xE6\x8C\xF3\x95\xE2 + RECT NewWindowRect[5]; + + // \x83^\x83C\x83g\x83\x8B\x83o\x81[\x8F\xE3\x82̃|\x83C\x83\x93\x83^\x88ʒu\x82\xAA\x82Ȃ\xE9\x82ׂ\xAD\x82\xB8\x82\xEA\x82Ȃ\xA2\x90V\x82\xB5\x82\xA2\x88ʒu + int t1 = (int)MouseCursorInWindow.y * (int)NewWindowHeight / (int)CurrentWindowHeight; + NewWindowRect[0].top = + CurrentWindowRect.top - + (t1 - (int)MouseCursorInWindow.y); + t1 = (int)MouseCursorInWindow.x * (int)NewWindowWidth / (int)CurrentWindowWidth; + NewWindowRect[0].left = + CurrentWindowRect.left - + (t1 - (int)MouseCursorInWindow.x); + NewWindowRect[0].bottom = NewWindowRect[0].top + NewWindowHeight; + NewWindowRect[0].right = NewWindowRect[0].left + NewWindowWidth; + + // \x8C\xBB\x8D݈ʒu\x82\xA9\x82\xE7\x8F\xE3\x89E\x8A\xF1\x82\xB9 + NewWindowRect[1].top = CurrentWindowRect.top; + NewWindowRect[1].bottom = CurrentWindowRect.top + NewWindowHeight; + NewWindowRect[1].left = CurrentWindowRect.right - NewWindowWidth; + NewWindowRect[1].right = CurrentWindowRect.right; + + // \x8C\xBB\x8D݈ʒu\x82\xA9\x82\xE7\x8F㍶\x8A\xF1\x82\xB9 + NewWindowRect[2].top = CurrentWindowRect.top; + NewWindowRect[2].bottom = CurrentWindowRect.top + NewWindowHeight; + NewWindowRect[2].left = CurrentWindowRect.left; + NewWindowRect[2].right = CurrentWindowRect.left + NewWindowWidth; + + // \x8C\xBB\x8D݈ʒu\x82\xA9\x82牺\x89E\x8A\xF1\x82\xB9 + NewWindowRect[3].top = CurrentWindowRect.bottom - NewWindowHeight; + NewWindowRect[3].bottom = CurrentWindowRect.top; + NewWindowRect[3].left = CurrentWindowRect.right - NewWindowWidth; + NewWindowRect[3].right = CurrentWindowRect.right; + + // \x8C\xBB\x8D݈ʒu\x82\xA9\x82牺\x8D\xB6\x8A\xF1\x82\xB9 + NewWindowRect[4].top = CurrentWindowRect.bottom - NewWindowHeight; + NewWindowRect[4].bottom = CurrentWindowRect.top; + NewWindowRect[4].left = CurrentWindowRect.left; + NewWindowRect[4].right = CurrentWindowRect.left + NewWindowWidth; + + // \x8Am\x94F + const RECT *NewRect = &NewWindowRect[0]; + for (int i=0; i < _countof(NewWindowRect); i++) { + const RECT *r = &NewWindowRect[i]; + HMONITOR hMonitor = pMonitorFromRect(r, MONITOR_DEFAULTTONULL); + UINT dpiX; + UINT dpiY; + pGetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); + if (NewDPI == dpiX) { + NewRect = r; + break; + } + } + + IgnoreSizeMessage = TRUE; ::SetWindowPos(m_hWnd, NULL, - SuggestedWindowRect->left, SuggestedWindowRect->top, - 0, 0, - SWP_NOSIZE | SWP_NOZORDER); - DpiChanged(); + NewRect->left, NewRect->top, + NewWindowWidth, NewWindowHeight, + SWP_NOZORDER); + IgnoreSizeMessage = FALSE; + + ChangeCaret(); + return TRUE; } Modified: trunk/teraterm/teraterm/vtwin.h =================================================================== --- trunk/teraterm/teraterm/vtwin.h 2019-05-28 15:23:02 UTC (rev 7716) +++ trunk/teraterm/teraterm/vtwin.h 2019-05-30 14:27:55 UTC (rev 7717) @@ -61,6 +61,9 @@ BYTE Alpha; void SetWindowAlpha(BYTE alpha); + // DPI + BOOL IgnoreSizeMessage; + protected: public: