diff --git a/src/Config/Config.cpp b/src/Config/Config.cpp index 3df754ac9..6659030d4 100644 --- a/src/Config/Config.cpp +++ b/src/Config/Config.cpp @@ -1637,13 +1637,14 @@ void LoadSettings() if (!Globals.CmdLnFlag_PosParam /*|| g_bStickyWinPos*/) { WININFO winInfo = g_IniWinInfo; - WCHAR tchPosX[64], tchPosY[64], tchSizeX[64], tchSizeY[64], tchMaximized[64], tchZoom[64]; + WCHAR tchPosX[64], tchPosY[64], tchSizeX[64], tchSizeY[64], tchMaximized[64], tchZoom[64], tchDPI[64]; StringCchPrintf(tchPosX, COUNTOF(tchPosX), L"%ix%i PosX", ResX, ResY); StringCchPrintf(tchPosY, COUNTOF(tchPosY), L"%ix%i PosY", ResX, ResY); StringCchPrintf(tchSizeX, COUNTOF(tchSizeX), L"%ix%i SizeX", ResX, ResY); StringCchPrintf(tchSizeY, COUNTOF(tchSizeY), L"%ix%i SizeY", ResX, ResY); StringCchPrintf(tchMaximized, COUNTOF(tchMaximized), L"%ix%i Maximized", ResX, ResY); StringCchPrintf(tchZoom, COUNTOF(tchZoom), L"%ix%i Zoom", ResX, ResY); + StringCchPrintf(tchDPI, COUNTOF(tchDPI), L"%ix%i DPI", ResX, ResY); winInfo.x = IniSectionGetInt(IniSecWindow, tchPosX, g_IniWinInfo.x); winInfo.y = IniSectionGetInt(IniSecWindow, tchPosY, g_IniWinInfo.y); @@ -1655,6 +1656,7 @@ void LoadSettings() winInfo.zoom = (winInfo.zoom + 10) * 10; } winInfo.zoom = clampi(winInfo.zoom, SC_MIN_ZOOM_LEVEL, SC_MAX_ZOOM_LEVEL); + winInfo.dpi = IniSectionGetInt(IniSecWindow, tchDPI, g_IniWinInfo.dpi); if ((winInfo.x == CW_USEDEFAULT) || (winInfo.y == CW_USEDEFAULT) || (winInfo.cx == CW_USEDEFAULT) || (winInfo.cy == CW_USEDEFAULT)) { @@ -2046,13 +2048,14 @@ bool SaveWindowPositionSettings(bool bClearSettings) int const ResX = GetSystemMetrics(SM_CXVIRTUALSCREEN); int const ResY = GetSystemMetrics(SM_CYVIRTUALSCREEN); - WCHAR tchPosX[64], tchPosY[64], tchSizeX[64], tchSizeY[64], tchMaximized[64], tchZoom[64]; + WCHAR tchPosX[64], tchPosY[64], tchSizeX[64], tchSizeY[64], tchMaximized[64], tchZoom[64], tchDPI[64]; StringCchPrintf(tchPosX, COUNTOF(tchPosX), L"%ix%i PosX", ResX, ResY); StringCchPrintf(tchPosY, COUNTOF(tchPosY), L"%ix%i PosY", ResX, ResY); StringCchPrintf(tchSizeX, COUNTOF(tchSizeX), L"%ix%i SizeX", ResX, ResY); StringCchPrintf(tchSizeY, COUNTOF(tchSizeY), L"%ix%i SizeY", ResX, ResY); StringCchPrintf(tchMaximized, COUNTOF(tchMaximized), L"%ix%i Maximized", ResX, ResY); - StringCchPrintf(tchZoom, COUNTOF(tchMaximized), L"%ix%i Zoom", ResX, ResY); + StringCchPrintf(tchDPI, COUNTOF(tchDPI), L"%ix%i DPI", ResX, ResY); + StringCchPrintf(tchZoom, COUNTOF(tchZoom), L"%ix%i Zoom", ResX, ResY); if (bClearSettings) { IniSectionDelete(Constants.Window_Section, tchPosX, false); @@ -2061,6 +2064,7 @@ bool SaveWindowPositionSettings(bool bClearSettings) IniSectionDelete(Constants.Window_Section, tchSizeY, false); IniSectionDelete(Constants.Window_Section, tchMaximized, false); IniSectionDelete(Constants.Window_Section, tchZoom, false); + IniSectionDelete(Constants.Window_Section, tchDPI, false); } else { // overwrite last saved window position IniSectionSetInt(Constants.Window_Section, tchPosX, winInfo.x); @@ -2068,7 +2072,9 @@ bool SaveWindowPositionSettings(bool bClearSettings) IniSectionSetInt(Constants.Window_Section, tchSizeX, winInfo.cx); IniSectionSetInt(Constants.Window_Section, tchSizeY, winInfo.cy); IniSectionSetBool(Constants.Window_Section, tchMaximized, winInfo.max); + IniSectionSetBool(Constants.Window_Section, tchMaximized, winInfo.max); IniSectionSetInt(Constants.Window_Section, tchZoom, winInfo.zoom); + IniSectionSetInt(Constants.Window_Section, tchDPI, winInfo.dpi); // set current window position as new initial window g_IniWinInfo = winInfo; } diff --git a/src/Dialogs.c b/src/Dialogs.c index 2c252ee65..7e9f78d40 100644 --- a/src/Dialogs.c +++ b/src/Dialogs.c @@ -4225,6 +4225,23 @@ bool WarnIndentationDlg(HWND hwnd, EditFileIOStatus* fioStatus) } +//============================================================================= +// +// RelAdjustRectForDPI() +// +// +void RelAdjustRectForDPI(LPRECT rc, const UINT oldDPI, const UINT newDPI) { + float const scale = (float)newDPI / (float)(oldDPI != 0 ? oldDPI : 1); + LONG const oldWidth = (rc->right - rc->left); + LONG const oldHeight = (rc->bottom - rc->top); + LONG const newWidth = lroundf((float)oldWidth * scale); + LONG const newHeight = lroundf((float)oldHeight * scale); + rc->left -= (newWidth - oldWidth) >> 1; + rc->right = rc->left + newWidth; + rc->top -= (newHeight - oldHeight) >> 1; + rc->bottom = rc->top + newHeight; +} + //============================================================================= // @@ -4253,7 +4270,6 @@ bool GetMonitorInfoFromRect(const LPRECT rc, MONITORINFO *hMonitorInfo) { // ---------------------------------------------------------------------------- - //============================================================================= // // WinInfoToScreenCoord() @@ -4329,6 +4345,7 @@ void FitIntoMonitorGeometry(LPRECT pRect, WININFO *pWinInfo, SCREEN_MODE mode, b pWinInfo->cx = (mi.rcMonitor.right - mi.rcMonitor.left); pWinInfo->cy = (mi.rcMonitor.bottom - mi.rcMonitor.top); pWinInfo->max = true; + //~pWinInfo->dpi = Scintilla_GetWindowDPI(hwnd); // don't change } else { WININFO wi = *pWinInfo; WinInfoToScreenCoord(&wi); @@ -4369,6 +4386,7 @@ void FitIntoMonitorGeometry(LPRECT pRect, WININFO *pWinInfo, SCREEN_MODE mode, b pWinInfo->y = wi.y - (mi.rcWork.top - mi.rcMonitor.top); pWinInfo->cx = wi.cx; pWinInfo->cy = wi.cy; + //~pWinInfo->dpi = Scintilla_GetWindowDPI(hwnd); // don't change } } // ---------------------------------------------------------------------------- @@ -4415,6 +4433,7 @@ WININFO GetMyWindowPlacement(HWND hwnd, MONITORINFO *hMonitorInfo, const int off wi.cy = wndpl.rcNormalPosition.bottom - wndpl.rcNormalPosition.top; wi.max = IsZoomed(hwnd) || (wndpl.flags & WPF_RESTORETOMAXIMIZED); wi.zoom = SciCall_GetZoom(); + wi.dpi = Scintilla_GetWindowDPI(hwnd); if (Settings2.LaunchInstanceFullVisible) { RECT rci; @@ -4440,6 +4459,7 @@ WINDOWPLACEMENT WindowPlacementFromInfo(HWND hwnd, const WININFO* pWinInfo, SCRE if (pWinInfo) { RECT rc = { 0 }; RectFromWinInfo(pWinInfo, &rc); + winfo = *pWinInfo; FitIntoMonitorGeometry(&rc, &winfo, mode, false); if (pWinInfo->max) { diff --git a/src/Dialogs.h b/src/Dialogs.h index 1ad42a77c..c7f1d330c 100644 --- a/src/Dialogs.h +++ b/src/Dialogs.h @@ -61,6 +61,7 @@ bool SelectDefLineEndingDlg(HWND hwnd,LPARAM piOption); bool WarnLineEndingDlg(HWND hwnd, EditFileIOStatus* fioStatus); bool WarnIndentationDlg(HWND hwnd, EditFileIOStatus* fioStatus); +void RelAdjustRectForDPI(LPRECT rc, const UINT oldDPI, const UINT newDPI); bool GetMonitorInfoFromRect(const LPRECT rc, MONITORINFO *hMonitorInfo); void WinInfoToScreenCoord(WININFO* pWinInfo); WININFO GetMyWindowPlacement(HWND hwnd, MONITORINFO *hMonitorInfo, const int offset); diff --git a/src/Notepad3.c b/src/Notepad3.c index 7048714a5..7f08ecdc8 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -1117,8 +1117,9 @@ int WINAPI wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, // WININFO GetFactoryDefaultWndPos(const int flagsPos) { + HWND const hwnd = GetDesktopWindow(); RECT rc; - GetWindowRect(GetDesktopWindow(), &rc); + GetWindowRect(hwnd, &rc); MONITORINFO mi; GetMonitorInfoFromRect(&rc, &mi); WININFO winfo = INIT_WININFO; @@ -1128,6 +1129,7 @@ WININFO GetFactoryDefaultWndPos(const int flagsPos) winfo.x = (flagsPos == 3) ? mi.rcMonitor.left : winfo.cx; winfo.max = 0; winfo.zoom = 100; + winfo.dpi = Scintilla_GetWindowDPI(hwnd); return winfo; } // ---------------------------------------------------------------------------- @@ -1155,8 +1157,9 @@ WININFO GetWinInfoByFlag(const int flagsPos) } else if (flagsPos == 3) { winfo = GetFactoryDefaultWndPos(flagsPos); } else if ((flagsPos >= 4) && (flagsPos < 256)) { + HWND const hwnd = GetDesktopWindow(); RECT rc; - GetWindowRect(GetDesktopWindow(), &rc); + GetWindowRect(hwnd, &rc); MONITORINFO mi; GetMonitorInfoFromRect(&rc, &mi); @@ -1198,11 +1201,13 @@ WININFO GetWinInfoByFlag(const int flagsPos) winfo.max = true; winfo.zoom = 100; } + winfo.dpi = Scintilla_GetWindowDPI(hwnd); + } else { // ( > 256) restore window, move upper left corner to Work Area - MONITORINFO mi; RECT rc = { 0 }; RectFromWinInfo(&winfo, &rc); + MONITORINFO mi; GetMonitorInfoFromRect(&rc, &mi); WININFO wi = winfo; wi.cx = wi.cy = 16; // really small @@ -1215,6 +1220,26 @@ WININFO GetWinInfoByFlag(const int flagsPos) } +//============================================================================= +// +// _StatusCalcPaneSizeh() +// +static SIZE _StatusCalcPaneSize(HWND hwnd, LPCWSTR lpsz) { + HDC const hdc = GetDC(hwnd); + HGDIOBJ const hfont = (HGDIOBJ)SendMessage(hwnd, WM_GETFONT, 0, 0); + HGDIOBJ const hfold = SelectObject(hdc, hfont); + int const mmode = SetMapMode(hdc, MM_TEXT); + + SIZE size = { 0L, 0L }; + GetTextExtentPoint32(hdc, lpsz, (int)StringCchLenW(lpsz, 0), &size); + + SetMapMode(hdc, mmode); + SelectObject(hdc, hfold); + ReleaseDC(hwnd, hdc); + + return size; +} + //============================================================================= // @@ -1424,14 +1449,12 @@ HWND InitInstance(const HINSTANCE hInstance, LPCWSTR pszCmdLine, int nCmdShow) hInstance, NULL); + SnapToWinInfoPos(Globals.hwndMain, g_IniWinInfo, SCR_NORMAL); + if (g_IniWinInfo.max) { nCmdShow = SW_SHOWMAXIMIZED; } - if (Settings.AlwaysOnTop) { - SetWindowPos(Globals.hwndMain, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - } - SetDialogIconNP3(Globals.hwndMain); InitWindowCommon(Globals.hwndMain, true); @@ -1712,6 +1735,11 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case WM_ENDSESSION: return MsgEndSession(hwnd, umsg, wParam, lParam); + case WM_SYSCOLORCHANGE: + // update Scintilla colors + SendMessage(Globals.hwndEdit, WM_SYSCOLORCHANGE, wParam, lParam); + // [[FallThrough]] + // Reinitialize theme-dependent values and resize windows case WM_THEMECHANGED: return MsgThemeChanged(hwnd, wParam, lParam); @@ -1722,18 +1750,12 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case WM_SIZE: return MsgSize(hwnd, wParam, lParam); - // update Scintilla colors - case WM_SYSCOLORCHANGE: - Style_ResetCurrentLexer(Globals.hwndEdit); - UpdateUI(); - SendMessage(Globals.hwndEdit, WM_SYSCOLORCHANGE, wParam, lParam); - break; #ifdef D_NP3_WIN10_DARK_MODE case WM_SETTINGCHANGE: { if (IsColorSchemeChangeMessage(lParam)) { RefreshTitleBarThemeColor(hwnd); - SendMessage(Globals.hwndEdit, WM_THEMECHANGED, 0, 0); + PostMessage(Globals.hwndEdit, WM_THEMECHANGED, 0, 0); } } break; @@ -2735,11 +2757,11 @@ void CreateBars(HWND hwnd, HINSTANCE hInstance) s_cyReBar = (rc.bottom - rc.top); s_cyReBarFrame = s_bIsAppThemed ? 0 : 2; // (!) frame color is same as INITIAL title-bar ??? - // ------------------- // Create Statusbar // ------------------- - DWORD const dwStatusbarStyle = SBT_NOBORDERS | (Settings.ShowStatusbar ? (WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE) : (WS_CHILD | WS_CLIPSIBLINGS)); + DWORD const dwStatusbarStyle = SBT_NOBORDERS | SBT_OWNERDRAW | + (Settings.ShowStatusbar ? (WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE) : (WS_CHILD | WS_CLIPSIBLINGS)); if (Globals.hwndStatus) { DestroyWindow(Globals.hwndStatus); @@ -2747,15 +2769,15 @@ void CreateBars(HWND hwnd, HINSTANCE hInstance) //~Globals.hwndStatus = CreateStatusWindow(dwStatusbarStyle, NULL, hwnd, IDC_STATUSBAR); Globals.hwndStatus = CreateWindowEx( - WS_EX_COMPOSITED, // => double-buffering avoids flickering - STATUSCLASSNAME, // name of status bar class - (PCTSTR)NULL, // no text when first created - dwStatusbarStyle, // creates a visible child window - 0, 0, 0, 0, // ignores size and position - hwnd, // handle to parent window - (HMENU)IDC_STATUSBAR, // child window identifier - hInstance, // handle to application instance - NULL); // no window creation data + WS_EX_COMPOSITED, // => double-buffering avoids flickering + STATUSCLASSNAME, // name of status bar class + (PCTSTR)NULL, // no text when first created + dwStatusbarStyle, // creates a visible child window + 0, 0, 0, 0, // ignores size and position + hwnd, // handle to parent window + (HMENU)IDC_STATUSBAR, // child window identifier + hInstance, // handle to application instance + NULL); // no window creation data InitWindowCommon(Globals.hwndStatus, true); // (!) themed = true : resize grip @@ -6409,7 +6431,6 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) case CMD_COPYPATHNAME: { - WCHAR *pszCopy; WCHAR tchUntitled[32] = { L'\0' }; if (StrIsNotEmpty(Paths.CurrentFile)) { @@ -6436,7 +6457,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) break; case CMD_FULLSCRWINPOS: { - WININFO const wi = GetMyWindowPlacement(Globals.hwndMain, NULL, 0); + WININFO wi = GetMyWindowPlacement(Globals.hwndMain, NULL, 0); SnapToWinInfoPos(hwnd, wi, SCR_FULL_SCREEN); } break; @@ -8626,28 +8647,6 @@ static void _UpdateToolbarDelayed() -//============================================================================= -// -// _StatusCalcPaneWidth() -// -static LONG _StatusCalcPaneWidth(HWND hwnd, LPCWSTR lpsz) -{ - HDC const hdc = GetDC(hwnd); - HGDIOBJ const hfont = (HGDIOBJ)SendMessage(hwnd, WM_GETFONT, 0, 0); - HGDIOBJ const hfold = SelectObject(hdc, hfont); - int const mmode = SetMapMode(hdc, MM_TEXT); - - SIZE size = { 0L, 0L }; - GetTextExtentPoint32(hdc, lpsz, (int)StringCchLenW(lpsz,0), &size); - - SetMapMode(hdc, mmode); - SelectObject(hdc, hfold); - ReleaseDC(hwnd, hdc); - - return (size.cx + 8L); -} - - //============================================================================= // // _CalculateStatusbarSections @@ -8673,7 +8672,8 @@ static void _CalculateStatusbarSections(int vSectionWidth[], sectionTxt_t tchSt for (int i = 0; i < STATUS_SECTOR_COUNT; ++i) { if (g_iStatusbarVisible[i]) { if (g_iStatusbarWidthSpec[i] == 0) { // dynamic optimized - vSectionWidth[i] = _StatusCalcPaneWidth(Globals.hwndStatus, tchStatusBar[i]); + SIZE const size = _StatusCalcPaneSize(Globals.hwndStatus, tchStatusBar[i]); + vSectionWidth[i] = (size.cx + 8L); } else if (g_iStatusbarWidthSpec[i] < -1) { // fixed pixel count vSectionWidth[i] = -(g_iStatusbarWidthSpec[i]); } @@ -8701,7 +8701,8 @@ static void _CalculateStatusbarSections(int vSectionWidth[], sectionTxt_t tchSt int iTotalMinWidth = 0; for (int i = 0; i < STATUS_SECTOR_COUNT; ++i) { if (bIsPropSection[i]) { - int const iMinWidth = _StatusCalcPaneWidth(Globals.hwndStatus, tchStatusBar[i]); + SIZE const size = _StatusCalcPaneSize(Globals.hwndStatus, tchStatusBar[i]); + int const iMinWidth = (size.cx + 8L); vMinWidth[i] = iMinWidth; iTotalMinWidth += iMinWidth; } @@ -9278,8 +9279,10 @@ static void _UpdateStatusbarDelayed(bool bForceRedraw) Settings.ShowStatusbar = false; } - SendMessage(Globals.hwndStatus, SB_SETPARTS, (WPARAM)cnt, (LPARAM)aStatusbarSections); + SIZE const size = _StatusCalcPaneSize(Globals.hwndStatus, L"X"); + SendMessage(Globals.hwndStatus, SB_SETMINHEIGHT, MAKEWPARAM(size.cy + 2, 0), 0); + SendMessage(Globals.hwndStatus, SB_SETPARTS, (WPARAM)cnt, (LPARAM)aStatusbarSections); cnt = 0; for (int i = 0; i < STATUS_SECTOR_COUNT; ++i) { int const id = g_vSBSOrder[i]; @@ -9287,6 +9290,8 @@ static void _UpdateStatusbarDelayed(bool bForceRedraw) StatusSetText(Globals.hwndStatus, cnt++, tchStatusBar[id]); } } + + PostMessage(Globals.hwndStatus, WM_SIZE, 0, 0); } // -------------------------------------------------------------------------- @@ -11123,6 +11128,12 @@ void SnapToWinInfoPos(HWND hwnd, const WININFO winInfo, SCREEN_MODE mode) if (GetDoAnimateMinimize()) { DrawAnimatedRects(hWindow, IDANI_CAPTION, &rcCurrent, &wndpl.rcNormalPosition); } + if (hwnd) { + UINT const dpi = Scintilla_GetWindowDPI(hwnd); + if (dpi != winInfo.dpi) { + RelAdjustRectForDPI(&wndpl.rcNormalPosition, winInfo.dpi, dpi); + } + } SetWindowPlacement(hWindow, &wndpl); // 1st set correct screen (DPI Aware) SetWindowPlacement(hWindow, &wndpl); // 2nd resize position to correct DPI settings } diff --git a/src/TypeDefs.h b/src/TypeDefs.h index a14794199..c3b2e3672 100644 --- a/src/TypeDefs.h +++ b/src/TypeDefs.h @@ -84,9 +84,10 @@ typedef struct _wi int cy; bool max; int zoom; + UINT dpi; } WININFO; -#define INIT_WININFO { CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, false, 100 } +#define INIT_WININFO { CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, false, 100, USER_DEFAULT_SCREEN_DPI } typedef enum { SCR_NORMAL = 0, SCR_FULL_SCREEN = 1 } SCREEN_MODE;