diff --git a/Library/ConfigParser.cpp b/Library/ConfigParser.cpp index 2ce7dd2d..f2e3abfd 100644 --- a/Library/ConfigParser.cpp +++ b/Library/ConfigParser.cpp @@ -387,15 +387,18 @@ void CConfigParser::SetMultiMonitorVariables(bool reset) c_MonitorVariables[variable] = value; }; - WCHAR buffer[32]; - RECT workArea, scrArea; - if (!reset && c_MonitorVariables.empty()) { reset = true; // Set all variables } - SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0); + const size_t numOfMonitors = CSystem::GetMonitorCount(); // intentional + const MultiMonitorInfo& monitorsInfo = CSystem::GetMultiMonitorInfo(); + const std::vector& monitors = monitorsInfo.monitors; + + WCHAR buffer[32]; + const RECT workArea = monitors[monitorsInfo.primary - 1].work; + const RECT scrArea = monitors[monitorsInfo.primary - 1].screen; _itow_s(workArea.left, buffer, 10); setMonitorVariable(L"WORKAREAX", buffer); @@ -412,11 +415,6 @@ void CConfigParser::SetMultiMonitorVariables(bool reset) if (reset) { - scrArea.left = 0; - scrArea.top = 0; - scrArea.right = GetSystemMetrics(SM_CXSCREEN); - scrArea.bottom = GetSystemMetrics(SM_CYSCREEN); - _itow_s(scrArea.left, buffer, 10); setMonitorVariable(L"SCREENAREAX", buffer); setMonitorVariable(L"PSCREENAREAX", buffer); @@ -430,57 +428,52 @@ void CConfigParser::SetMultiMonitorVariables(bool reset) setMonitorVariable(L"SCREENAREAHEIGHT", buffer); setMonitorVariable(L"PSCREENAREAHEIGHT", buffer); - _itow_s(GetSystemMetrics(SM_XVIRTUALSCREEN), buffer, 10); + _itow_s(monitorsInfo.vsL, buffer, 10); setMonitorVariable(L"VSCREENAREAX", buffer); - _itow_s(GetSystemMetrics(SM_YVIRTUALSCREEN), buffer, 10); + _itow_s(monitorsInfo.vsT, buffer, 10); setMonitorVariable(L"VSCREENAREAY", buffer); - _itow_s(GetSystemMetrics(SM_CXVIRTUALSCREEN), buffer, 10); + _itow_s(monitorsInfo.vsW, buffer, 10); setMonitorVariable(L"VSCREENAREAWIDTH", buffer); - _itow_s(GetSystemMetrics(SM_CYVIRTUALSCREEN), buffer, 10); + _itow_s(monitorsInfo.vsH, buffer, 10); setMonitorVariable(L"VSCREENAREAHEIGHT", buffer); } - if (CSystem::GetMonitorCount() > 0) + int i = 1; + for (auto iter = monitors.cbegin(); iter != monitors.cend(); ++iter, ++i) { - const MultiMonitorInfo& multimonInfo = CSystem::GetMultiMonitorInfo(); - const std::vector& monitors = multimonInfo.monitors; + WCHAR buffer2[64]; - for (size_t i = 0, isize = monitors.size(); i < isize; ++i) + const RECT work = ((*iter).active) ? (*iter).work : workArea; + + _itow_s(work.left, buffer, 10); + _snwprintf_s(buffer2, _TRUNCATE, L"WORKAREAX@%i", i); + setMonitorVariable(buffer2, buffer); + _itow_s(work.top, buffer, 10); + _snwprintf_s(buffer2, _TRUNCATE, L"WORKAREAY@%i", i); + setMonitorVariable(buffer2, buffer); + _itow_s(work.right - work.left, buffer, 10); + _snwprintf_s(buffer2, _TRUNCATE, L"WORKAREAWIDTH@%i", i); + setMonitorVariable(buffer2, buffer); + _itow_s(work.bottom - work.top, buffer, 10); + _snwprintf_s(buffer2, _TRUNCATE, L"WORKAREAHEIGHT@%i", i); + setMonitorVariable(buffer2, buffer); + + if (reset) { - WCHAR buffer2[64]; + const RECT screen = ((*iter).active) ? (*iter).screen : scrArea; - const RECT work = (monitors[i].active) ? monitors[i].work : workArea; - - _itow_s(work.left, buffer, 10); - _snwprintf_s(buffer2, _TRUNCATE, L"WORKAREAX@%i", (int)i + 1); + _itow_s(screen.left, buffer, 10); + _snwprintf_s(buffer2, _TRUNCATE, L"SCREENAREAX@%i", i); setMonitorVariable(buffer2, buffer); - _itow_s(work.top, buffer, 10); - _snwprintf_s(buffer2, _TRUNCATE, L"WORKAREAY@%i", (int)i + 1); + _itow_s(screen.top, buffer, 10); + _snwprintf_s(buffer2, _TRUNCATE, L"SCREENAREAY@%i", i); setMonitorVariable(buffer2, buffer); - _itow_s(work.right - work.left, buffer, 10); - _snwprintf_s(buffer2, _TRUNCATE, L"WORKAREAWIDTH@%i", (int)i + 1); + _itow_s(screen.right - screen.left, buffer, 10); + _snwprintf_s(buffer2, _TRUNCATE, L"SCREENAREAWIDTH@%i", i); setMonitorVariable(buffer2, buffer); - _itow_s(work.bottom - work.top, buffer, 10); - _snwprintf_s(buffer2, _TRUNCATE, L"WORKAREAHEIGHT@%i", (int)i + 1); + _itow_s(screen.bottom - screen.top, buffer, 10); + _snwprintf_s(buffer2, _TRUNCATE, L"SCREENAREAHEIGHT@%i", i); setMonitorVariable(buffer2, buffer); - - if (reset) - { - const RECT screen = (monitors[i].active) ? monitors[i].screen : scrArea; - - _itow_s(screen.left, buffer, 10); - _snwprintf_s(buffer2, _TRUNCATE, L"SCREENAREAX@%i", (int)i + 1); - setMonitorVariable(buffer2, buffer); - _itow_s(screen.top, buffer, 10); - _snwprintf_s(buffer2, _TRUNCATE, L"SCREENAREAY@%i", (int)i + 1); - setMonitorVariable(buffer2, buffer); - _itow_s(screen.right - screen.left, buffer, 10); - _snwprintf_s(buffer2, _TRUNCATE, L"SCREENAREAWIDTH@%i", (int)i + 1); - setMonitorVariable(buffer2, buffer); - _itow_s(screen.bottom - screen.top, buffer, 10); - _snwprintf_s(buffer2, _TRUNCATE, L"SCREENAREAHEIGHT@%i", (int)i + 1); - setMonitorVariable(buffer2, buffer); - } } } } @@ -493,113 +486,79 @@ void CConfigParser::SetAutoSelectedMonitorVariables(CMeterWindow* meterWindow) { if (meterWindow) { + const int numOfMonitors = (int)CSystem::GetMonitorCount(); + const MultiMonitorInfo& monitorsInfo = CSystem::GetMultiMonitorInfo(); + const std::vector& monitors = monitorsInfo.monitors; + WCHAR buffer[32]; + int w1, w2, s1, s2; + int screenIndex; - if (CSystem::GetMonitorCount() > 0) + // Set X / WIDTH + screenIndex = monitorsInfo.primary; + if (meterWindow->GetXScreenDefined()) { - int w1, w2, s1, s2; - int screenIndex; - - const MultiMonitorInfo& multimonInfo = CSystem::GetMultiMonitorInfo(); - const std::vector& monitors = multimonInfo.monitors; - - // Set X / WIDTH - screenIndex = multimonInfo.primary; - if (meterWindow->GetXScreenDefined()) + int i = meterWindow->GetXScreen(); + if (i >= 0 && (i == 0 || i <= numOfMonitors && monitors[i - 1].active)) { - int i = meterWindow->GetXScreen(); - if (i >= 0 && (i == 0 || i <= (int)monitors.size() && monitors[i-1].active)) - { - screenIndex = i; - } + screenIndex = i; } + } - if (screenIndex == 0) - { - s1 = w1 = multimonInfo.vsL; - s2 = w2 = multimonInfo.vsW; - } - else - { - w1 = monitors[screenIndex-1].work.left; - w2 = monitors[screenIndex-1].work.right - monitors[screenIndex-1].work.left; - s1 = monitors[screenIndex-1].screen.left; - s2 = monitors[screenIndex-1].screen.right - monitors[screenIndex-1].screen.left; - } - - _itow_s(w1, buffer, 10); - SetBuiltInVariable(L"WORKAREAX", buffer); - _itow_s(w2, buffer, 10); - SetBuiltInVariable(L"WORKAREAWIDTH", buffer); - _itow_s(s1, buffer, 10); - SetBuiltInVariable(L"SCREENAREAX", buffer); - _itow_s(s2, buffer, 10); - SetBuiltInVariable(L"SCREENAREAWIDTH", buffer); - - // Set Y / HEIGHT - screenIndex = multimonInfo.primary; - if (meterWindow->GetYScreenDefined()) - { - int i = meterWindow->GetYScreen(); - if (i >= 0 && (i == 0 || i <= (int)monitors.size() && monitors[i-1].active)) - { - screenIndex = i; - } - } - - if (screenIndex == 0) - { - s1 = w1 = multimonInfo.vsL; - s2 = w2 = multimonInfo.vsW; - } - else - { - w1 = monitors[screenIndex-1].work.top; - w2 = monitors[screenIndex-1].work.bottom - monitors[screenIndex-1].work.top; - s1 = monitors[screenIndex-1].screen.top; - s2 = monitors[screenIndex-1].screen.bottom - monitors[screenIndex-1].screen.top; - } - - _itow_s(w1, buffer, 10); - SetBuiltInVariable(L"WORKAREAY", buffer); - _itow_s(w2, buffer, 10); - SetBuiltInVariable(L"WORKAREAHEIGHT", buffer); - _itow_s(s1, buffer, 10); - SetBuiltInVariable(L"SCREENAREAY", buffer); - _itow_s(s2, buffer, 10); - SetBuiltInVariable(L"SCREENAREAHEIGHT", buffer); + if (screenIndex == 0) + { + s1 = w1 = monitorsInfo.vsL; + s2 = w2 = monitorsInfo.vsW; } else { - RECT r; - - // Set default WORKAREA - SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); - - _itow_s(r.left, buffer, 10); - SetBuiltInVariable(L"WORKAREAX", buffer); - _itow_s(r.top, buffer, 10); - SetBuiltInVariable(L"WORKAREAY", buffer); - _itow_s(r.right - r.left, buffer, 10); - SetBuiltInVariable(L"WORKAREAWIDTH", buffer); - _itow_s(r.bottom - r.top, buffer, 10); - SetBuiltInVariable(L"WORKAREAHEIGHT", buffer); - - // Set default SCREENAREA - r.left = 0; - r.top = 0; - r.right = GetSystemMetrics(SM_CXSCREEN); - r.bottom = GetSystemMetrics(SM_CYSCREEN); - - _itow_s(r.left, buffer, 10); - SetBuiltInVariable(L"SCREENAREAX", buffer); - _itow_s(r.top, buffer, 10); - SetBuiltInVariable(L"SCREENAREAY", buffer); - _itow_s(r.right - r.left, buffer, 10); - SetBuiltInVariable(L"SCREENAREAWIDTH", buffer); - _itow_s(r.bottom - r.top, buffer, 10); - SetBuiltInVariable(L"SCREENAREAHEIGHT", buffer); + w1 = monitors[screenIndex - 1].work.left; + w2 = monitors[screenIndex - 1].work.right - monitors[screenIndex - 1].work.left; + s1 = monitors[screenIndex - 1].screen.left; + s2 = monitors[screenIndex - 1].screen.right - monitors[screenIndex - 1].screen.left; } + + _itow_s(w1, buffer, 10); + SetBuiltInVariable(L"WORKAREAX", buffer); + _itow_s(w2, buffer, 10); + SetBuiltInVariable(L"WORKAREAWIDTH", buffer); + _itow_s(s1, buffer, 10); + SetBuiltInVariable(L"SCREENAREAX", buffer); + _itow_s(s2, buffer, 10); + SetBuiltInVariable(L"SCREENAREAWIDTH", buffer); + + // Set Y / HEIGHT + screenIndex = monitorsInfo.primary; + if (meterWindow->GetYScreenDefined()) + { + int i = meterWindow->GetYScreen(); + if (i >= 0 && (i == 0 || i <= numOfMonitors && monitors[i - 1].active)) + { + screenIndex = i; + } + } + + if (screenIndex == 0) + { + s1 = w1 = monitorsInfo.vsL; + s2 = w2 = monitorsInfo.vsW; + } + else + { + w1 = monitors[screenIndex - 1].work.top; + w2 = monitors[screenIndex - 1].work.bottom - monitors[screenIndex - 1].work.top; + s1 = monitors[screenIndex - 1].screen.top; + s2 = monitors[screenIndex - 1].screen.bottom - monitors[screenIndex - 1].screen.top; + } + + _itow_s(w1, buffer, 10); + SetBuiltInVariable(L"WORKAREAY", buffer); + _itow_s(w2, buffer, 10); + SetBuiltInVariable(L"WORKAREAHEIGHT", buffer); + _itow_s(s1, buffer, 10); + SetBuiltInVariable(L"SCREENAREAY", buffer); + _itow_s(s2, buffer, 10); + SetBuiltInVariable(L"SCREENAREAHEIGHT", buffer); } } diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index 0584bd02..822cbc91 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -527,6 +527,9 @@ void CMeterWindow::SetMouseLeaveEvent(bool cancel) void CMeterWindow::MapCoordsToScreen(int& x, int& y, int w, int h) { + const size_t numOfMonitors = CSystem::GetMonitorCount(); // intentional + const std::vector& monitors = CSystem::GetMultiMonitorInfo().monitors; + // Check that the window is inside the screen area POINT pt = {x + w / 2, y + h / 2}; for (int i = 0; i < 5; ++i) @@ -558,29 +561,28 @@ void CMeterWindow::MapCoordsToScreen(int& x, int& y, int w, int h) break; } - HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL); - - if (hMonitor != NULL) + for (auto iter = monitors.cbegin(); iter != monitors.cend(); ++iter) { - MONITORINFO mi; - mi.cbSize = sizeof(mi); - GetMonitorInfo(hMonitor, &mi); + if (!(*iter).active) continue; - x = min(x, mi.rcMonitor.right - m_WindowW); - x = max(x, mi.rcMonitor.left); - y = min(y, mi.rcMonitor.bottom - m_WindowH); - y = max(y, mi.rcMonitor.top); - return; + const RECT r = (*iter).screen; + if (pt.x >= r.left && pt.x < r.right && pt.y >= r.top && pt.y < r.bottom) + { + x = min(x, r.right - w); + x = max(x, r.left); + y = min(y, r.bottom - h); + y = max(y, r.top); + return; + } } } // No monitor found for the window -> Use the default work area - RECT workArea; - SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0); // Store the old value - x = min(x, workArea.right - m_WindowW); - x = max(x, workArea.left); - y = min(y, workArea.bottom - m_WindowH); - y = max(y, workArea.top); + const RECT r = monitors[CSystem::GetMultiMonitorInfo().primary - 1].work; + x = min(x, r.right - w); + x = max(x, r.left); + y = min(y, r.bottom - h); + y = max(y, r.top); } /* @@ -591,12 +593,7 @@ void CMeterWindow::MoveWindow(int x, int y) { SetWindowPos(m_Window, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); - ScreenToWindow(); - - if (m_SavePosition) - { - WriteOptions(OPTION_POSITION); - } + SavePositionIfAppropriate(); } /* @@ -1466,22 +1463,17 @@ void CMeterWindow::SetOption(const std::wstring& section, const std::wstring& op */ void CMeterWindow::WindowToScreen() { - if (CSystem::GetMonitorCount() == 0) - { - Log(LOG_ERROR, L"No monitors (WindowToScreen)"); - return; - } - std::wstring::size_type index, index2; int pixel = 0; float num; int screenx, screeny, screenh, screenw; - const MultiMonitorInfo& multimonInfo = CSystem::GetMultiMonitorInfo(); - const std::vector& monitors = multimonInfo.monitors; + const int numOfMonitors = (int)CSystem::GetMonitorCount(); + const MultiMonitorInfo& monitorsInfo = CSystem::GetMultiMonitorInfo(); + const std::vector& monitors = monitorsInfo.monitors; // Clear position flags - m_WindowXScreen = m_WindowYScreen = multimonInfo.primary; // Default to primary screen + m_WindowXScreen = m_WindowYScreen = monitorsInfo.primary; // Default to primary screen m_WindowXScreenDefined = m_WindowYScreenDefined = false; m_WindowXFromRight = m_WindowYFromBottom = false; // Default to from left/top m_WindowXPercentage = m_WindowYPercentage = false; // Default to pixels @@ -1565,7 +1557,7 @@ void CMeterWindow::WindowToScreen() if (!screenStr.empty()) { int screenIndex = _wtoi(screenStr.c_str()); - if (screenIndex >= 0 && (screenIndex == 0 || screenIndex <= (int)monitors.size() && monitors[screenIndex-1].active)) + if (screenIndex >= 0 && (screenIndex == 0 || screenIndex <= numOfMonitors && monitors[screenIndex - 1].active)) { m_WindowXScreen = screenIndex; m_WindowXScreenDefined = true; @@ -1576,13 +1568,13 @@ void CMeterWindow::WindowToScreen() } if (m_WindowXScreen == 0) { - screenx = multimonInfo.vsL; - screenw = multimonInfo.vsW; + screenx = monitorsInfo.vsL; + screenw = monitorsInfo.vsW; } else { - screenx = monitors[m_WindowXScreen-1].screen.left; - screenw = monitors[m_WindowXScreen-1].screen.right - monitors[m_WindowXScreen-1].screen.left; + screenx = monitors[m_WindowXScreen - 1].screen.left; + screenw = monitors[m_WindowXScreen - 1].screen.right - monitors[m_WindowXScreen - 1].screen.left; } if (m_WindowXPercentage) //is a percentage { @@ -1627,7 +1619,7 @@ void CMeterWindow::WindowToScreen() if (!screenStr.empty()) { int screenIndex = _wtoi(screenStr.c_str()); - if (screenIndex >= 0 && (screenIndex == 0 || screenIndex <= (int)monitors.size() && monitors[screenIndex-1].active)) + if (screenIndex >= 0 && (screenIndex == 0 || screenIndex <= numOfMonitors && monitors[screenIndex - 1].active)) { m_WindowYScreen = screenIndex; m_WindowYScreenDefined = true; @@ -1636,13 +1628,13 @@ void CMeterWindow::WindowToScreen() } if (m_WindowYScreen == 0) { - screeny = multimonInfo.vsT; - screenh = multimonInfo.vsH; + screeny = monitorsInfo.vsT; + screenh = monitorsInfo.vsH; } else { - screeny = monitors[m_WindowYScreen-1].screen.top; - screenh = monitors[m_WindowYScreen-1].screen.bottom - monitors[m_WindowYScreen-1].screen.top; + screeny = monitors[m_WindowYScreen - 1].screen.top; + screenh = monitors[m_WindowYScreen - 1].screen.bottom - monitors[m_WindowYScreen - 1].screen.top; } if (m_WindowYPercentage) //is a percentage { @@ -1675,14 +1667,9 @@ void CMeterWindow::ScreenToWindow() float num; int screenx, screeny, screenh, screenw; - const MultiMonitorInfo& multimonInfo = CSystem::GetMultiMonitorInfo(); - const std::vector& monitors = multimonInfo.monitors; - - if (monitors.empty()) - { - Log(LOG_ERROR, L"No monitors (ScreenToWindow)"); - return; - } + const size_t numOfMonitors = CSystem::GetMonitorCount(); + const MultiMonitorInfo& monitorsInfo = CSystem::GetMultiMonitorInfo(); + const std::vector& monitors = monitorsInfo.monitors; // Correct to auto-selected screen if (m_AutoSelectScreen) @@ -1692,11 +1679,11 @@ void CMeterWindow::ScreenToWindow() if (hMonitor != NULL) { - for (size_t i = 0, isize = monitors.size(); i < isize; ++i) + int screenIndex = 1; + for (auto iter = monitors.cbegin(); iter != monitors.cend(); ++iter, ++screenIndex) { - if (monitors[i].active && monitors[i].handle == hMonitor) + if ((*iter).active && (*iter).handle == hMonitor) { - int screenIndex = (int)i + 1; bool reset = (!m_WindowXScreenDefined || !m_WindowYScreenDefined || m_WindowXScreen != screenIndex || m_WindowYScreen != screenIndex); @@ -1717,13 +1704,13 @@ void CMeterWindow::ScreenToWindow() if (m_WindowXScreen == 0) { - screenx = multimonInfo.vsL; - screenw = multimonInfo.vsW; + screenx = monitorsInfo.vsL; + screenw = monitorsInfo.vsW; } else { - screenx = monitors[m_WindowXScreen-1].screen.left; - screenw = monitors[m_WindowXScreen-1].screen.right - monitors[m_WindowXScreen-1].screen.left; + screenx = monitors[m_WindowXScreen - 1].screen.left; + screenw = monitors[m_WindowXScreen - 1].screen.right - monitors[m_WindowXScreen - 1].screen.left; } if (m_WindowXFromRight) { @@ -1746,7 +1733,7 @@ void CMeterWindow::ScreenToWindow() } if (m_WindowXFromRight) { - _snwprintf_s(buffer, _TRUNCATE, L"%sR", buffer); + wcscat_s(buffer, L"R"); } if (m_WindowXScreenDefined) { @@ -1758,13 +1745,13 @@ void CMeterWindow::ScreenToWindow() if (m_WindowYScreen == 0) { - screeny = multimonInfo.vsT; - screenh = multimonInfo.vsH; + screeny = monitorsInfo.vsT; + screenh = monitorsInfo.vsH; } else { - screeny = monitors[m_WindowYScreen-1].screen.top; - screenh = monitors[m_WindowYScreen-1].screen.bottom - monitors[m_WindowYScreen-1].screen.top; + screeny = monitors[m_WindowYScreen - 1].screen.top; + screenh = monitors[m_WindowYScreen - 1].screen.bottom - monitors[m_WindowYScreen - 1].screen.top; } if (m_WindowYFromBottom) { @@ -1787,7 +1774,7 @@ void CMeterWindow::ScreenToWindow() } if (m_WindowYFromBottom) { - _snwprintf_s(buffer, _TRUNCATE, L"%sB", buffer); + wcscat_s(buffer, L"B"); } if (m_WindowYScreenDefined) { @@ -1904,13 +1891,16 @@ void CMeterWindow::WriteOptions(INT setting) if (setting & OPTION_POSITION) { + ScreenToWindow(); + // If position needs to be save, do so. if (m_SavePosition) { - ScreenToWindow(); WritePrivateProfileString(section, L"WindowX", m_WindowX.c_str(), iniFile); WritePrivateProfileString(section, L"WindowY", m_WindowY.c_str(), iniFile); } + + if (setting == OPTION_POSITION) return; } if (setting & OPTION_ALPHAVALUE) @@ -3389,35 +3379,30 @@ LRESULT CMeterWindow::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam) case IDM_SKIN_FROMRIGHT: m_WindowXFromRight = !m_WindowXFromRight; - ScreenToWindow(); - WriteOptions(OPTION_POSITION); + SavePositionIfAppropriate(); break; case IDM_SKIN_FROMBOTTOM: m_WindowYFromBottom = !m_WindowYFromBottom; - ScreenToWindow(); - WriteOptions(OPTION_POSITION); + SavePositionIfAppropriate(); break; case IDM_SKIN_XPERCENTAGE: m_WindowXPercentage = !m_WindowXPercentage; - ScreenToWindow(); - WriteOptions(OPTION_POSITION); + SavePositionIfAppropriate(); break; case IDM_SKIN_YPERCENTAGE: m_WindowYPercentage = !m_WindowYPercentage; - ScreenToWindow(); - WriteOptions(OPTION_POSITION); + SavePositionIfAppropriate(); break; case IDM_SKIN_MONITOR_AUTOSELECT: m_AutoSelectScreen = !m_AutoSelectScreen; - ScreenToWindow(); WriteOptions(OPTION_POSITION | OPTION_AUTOSELECTSCREEN); break; @@ -3430,6 +3415,7 @@ LRESULT CMeterWindow::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam) } else if (wParam == IDM_SKIN_MONITOR_PRIMARY || wParam >= ID_MONITOR_FIRST && wParam <= ID_MONITOR_LAST) { + const int numOfMonitors = (int)CSystem::GetMonitorCount(); const MultiMonitorInfo& monitorsInfo = CSystem::GetMultiMonitorInfo(); const std::vector& monitors = monitorsInfo.monitors; @@ -3446,7 +3432,7 @@ LRESULT CMeterWindow::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam) screenDefined = true; } - if (screenIndex >= 0 && (screenIndex == 0 || screenIndex <= (int)monitors.size() && monitors[screenIndex-1].active)) + if (screenIndex >= 0 && (screenIndex == 0 || screenIndex <= numOfMonitors && monitors[screenIndex - 1].active)) { m_AutoSelectScreen = false; @@ -3454,7 +3440,6 @@ LRESULT CMeterWindow::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam) m_WindowXScreenDefined = m_WindowYScreenDefined = screenDefined; m_Parser.ResetMonitorVariables(this); // Set present monitor variables - ScreenToWindow(); WriteOptions(OPTION_POSITION | OPTION_AUTOSELECTSCREEN); } } @@ -3530,16 +3515,30 @@ void CMeterWindow::SetKeepOnScreen(bool b) m_KeepOnScreen = b; WriteOptions(OPTION_KEEPONSCREEN); + MoveWindowIfAppropriate(); +} + +/* +** Helper function for setting KeepOnScreen +** +*/ +bool CMeterWindow::MoveWindowIfAppropriate() +{ if (m_KeepOnScreen) { int x = m_ScreenX; int y = m_ScreenY; + MapCoordsToScreen(x, y, m_WindowW, m_WindowH); + if (x != m_ScreenX || y != m_ScreenY) { MoveWindow(x, y); + return true; } } + + return false; } /* @@ -3562,6 +3561,23 @@ void CMeterWindow::SetSavePosition(bool b) WriteOptions(OPTION_POSITION | OPTION_SAVEPOSITION); } +/* +** Helper function for setting SavePosition +** +*/ +void CMeterWindow::SavePositionIfAppropriate() +{ + if (m_SavePosition) + { + WriteOptions(OPTION_POSITION); + } + else + { + ScreenToWindow(); + CDialogManage::UpdateSkins(this); + } +} + /* ** Helper function for setting SnapEdges ** @@ -3615,12 +3631,7 @@ LRESULT CMeterWindow::OnSysCommand(UINT uMsg, WPARAM wParam, LPARAM lParam) if (m_Dragged) { - ScreenToWindow(); - - if (m_SavePosition) - { - WriteOptions(OPTION_POSITION); - } + SavePositionIfAppropriate(); POINT pos = CSystem::GetCursorPosition(); MapWindowPoints(NULL, m_Window, &pos, 1); @@ -3741,27 +3752,30 @@ LRESULT CMeterWindow::OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lPara // only process movement (ignore anything without winpos values) if (wp->cx != 0 && wp->cy != 0) { - RECT workArea; + // Search display monitor that has the largest area of intersection with the window + const size_t numOfMonitors = CSystem::GetMonitorCount(); // intentional + const std::vector& monitors = CSystem::GetMultiMonitorInfo().monitors; - //HMONITOR hMonitor = MonitorFromWindow(m_Window, MONITOR_DEFAULTTONULL); // returns incorrect monitor when the window is "On Desktop" - RECT windowRect = {wp->x, wp->y, (wp->x + m_WindowW), (wp->y + m_WindowH)}; - HMONITOR hMonitor = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONULL); + const RECT windowRect = {wp->x, wp->y, wp->x + (m_WindowW ? m_WindowW : 1), wp->y + (m_WindowH ? m_WindowH : 1)}; + const RECT* workArea = NULL; - if (hMonitor != NULL) + size_t maxSize = 0; + for (auto iter = monitors.cbegin(); iter != monitors.cend(); ++iter) { - MONITORINFO mi; - mi.cbSize = sizeof(mi); - GetMonitorInfo(hMonitor, &mi); - workArea = mi.rcWork; - } - else - { - GetClientRect(GetDesktopWindow(), &workArea); + RECT r; + if ((*iter).active && IntersectRect(&r, &windowRect, &(*iter).screen)) + { + size_t size = (r.right - r.left) * (r.bottom - r.top); + if (size > maxSize) + { + workArea = &(*iter).work; + maxSize = size; + } + } } // Snap to other windows - std::map::const_iterator iter = Rainmeter->GetAllMeterWindows().begin(); - for ( ; iter != Rainmeter->GetAllMeterWindows().end(); ++iter) + for (auto iter = Rainmeter->GetAllMeterWindows().cbegin(); iter != Rainmeter->GetAllMeterWindows().cend(); ++iter) { if ((*iter).second != this) { @@ -3769,13 +3783,17 @@ LRESULT CMeterWindow::OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lPara } } - int w = workArea.right - m_WindowW; - int h = workArea.bottom - m_WindowH; + // Snap to work area if window is on the appropriate screen + if (workArea) + { + int w = workArea->right - m_WindowW; + int h = workArea->bottom - m_WindowH; - if ((wp->x < SNAPDISTANCE + workArea.left) && (wp->x > workArea.left - SNAPDISTANCE)) wp->x = workArea.left; - if ((wp->y < SNAPDISTANCE + workArea.top) && (wp->y > workArea.top - SNAPDISTANCE)) wp->y = workArea.top; - if ((wp->x < SNAPDISTANCE + w) && (wp->x > -SNAPDISTANCE + w)) wp->x = w; - if ((wp->y < SNAPDISTANCE + h) && (wp->y > -SNAPDISTANCE + h)) wp->y = h; + if ((wp->x < SNAPDISTANCE + workArea->left) && (wp->x > workArea->left - SNAPDISTANCE)) wp->x = workArea->left; + if ((wp->y < SNAPDISTANCE + workArea->top) && (wp->y > workArea->top - SNAPDISTANCE)) wp->y = workArea->top; + if ((wp->x < SNAPDISTANCE + w) && (wp->x > -SNAPDISTANCE + w)) wp->x = w; + if ((wp->y < SNAPDISTANCE + h) && (wp->y > -SNAPDISTANCE + h)) wp->y = h; + } } } @@ -3785,7 +3803,7 @@ LRESULT CMeterWindow::OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lPara } } - return DefWindowProc(m_Window, uMsg, wParam, lParam); + return 0; } void CMeterWindow::SnapToWindow(CMeterWindow* window, LPWINDOWPOS wp) @@ -4643,13 +4661,11 @@ LRESULT CMeterWindow::OnDelayedMove(UINT uMsg, WPARAM wParam, LPARAM lParam) // Move the window to correct position ResizeWindow(true); - if (m_KeepOnScreen) + if (!MoveWindowIfAppropriate()) { - MapCoordsToScreen(m_ScreenX, m_ScreenY, m_WindowW, m_WindowH); + ScreenToWindow(); } - SetWindowPos(m_Window, NULL, m_ScreenX, m_ScreenY, m_WindowW, m_WindowH, SWP_NOZORDER | SWP_NOACTIVATE); - return 0; } diff --git a/Library/MeterWindow.h b/Library/MeterWindow.h index cf242f38..6c5aa481 100644 --- a/Library/MeterWindow.h +++ b/Library/MeterWindow.h @@ -326,8 +326,10 @@ private: void HandleButtons(POINT pos, BUTTONPROC proc, bool execute = true); void SetClickThrough(bool b); void SetKeepOnScreen(bool b); + bool MoveWindowIfAppropriate(); void SetWindowDraggable(bool b); void SetSavePosition(bool b); + void SavePositionIfAppropriate(); void SetSnapEdges(bool b); void SetWindowHide(HIDEMODE hide); void SetWindowZPosition(ZPOSITION zpos); diff --git a/Library/Rainmeter.cpp b/Library/Rainmeter.cpp index caefe3a0..85db93f9 100644 --- a/Library/Rainmeter.cpp +++ b/Library/Rainmeter.cpp @@ -2450,7 +2450,7 @@ void CRainmeter::ReadGeneralSettings(const std::wstring& iniFile) m_DesktopWorkAreaChanged = true; } - for (UINT i = 1; i <= CSystem::GetMonitorCount(); ++i) + for (UINT i = 1, isize = CSystem::GetMonitorCount(); i <= isize; ++i) { _snwprintf_s(buffer, _TRUNCATE, L"DesktopWorkArea@%i", i); const std::wstring& area = parser.ReadString(L"Rainmeter", buffer, L""); @@ -2663,9 +2663,10 @@ void CRainmeter::UpdateDesktopWorkArea(bool reset) { if (!m_OldDesktopWorkAreas.empty()) { - for (size_t i = 0, isize = m_OldDesktopWorkAreas.size(); i < isize; ++i) + int i = 1; + for (auto iter = m_OldDesktopWorkAreas.cbegin(); iter != m_OldDesktopWorkAreas.cend(); ++iter, ++i) { - RECT r = m_OldDesktopWorkAreas[i]; + RECT r = (*iter); BOOL result = SystemParametersInfo(SPI_SETWORKAREA, 0, &r, 0); @@ -2676,7 +2677,7 @@ void CRainmeter::UpdateDesktopWorkArea(bool reset) { format += L" => FAIL"; } - LogWithArgs(LOG_DEBUG, format.c_str(), (int)i + 1, r.left, r.top, r.right, r.bottom, r.right - r.left, r.bottom - r.top); + LogWithArgs(LOG_DEBUG, format.c_str(), i, r.left, r.top, r.right, r.bottom, r.right - r.left, r.bottom - r.top); } } changed = true; @@ -2684,13 +2685,14 @@ void CRainmeter::UpdateDesktopWorkArea(bool reset) } else { - const MultiMonitorInfo& multimonInfo = CSystem::GetMultiMonitorInfo(); - const std::vector& monitors = multimonInfo.monitors; + const size_t numOfMonitors = CSystem::GetMonitorCount(); + const MultiMonitorInfo& monitorsInfo = CSystem::GetMultiMonitorInfo(); + const std::vector& monitors = monitorsInfo.monitors; if (m_OldDesktopWorkAreas.empty()) { // Store old work areas for changing them back - for (size_t i = 0; i < CSystem::GetMonitorCount(); ++i) + for (size_t i = 0; i < numOfMonitors; ++i) { m_OldDesktopWorkAreas.push_back(monitors[i].work); } @@ -2701,18 +2703,18 @@ void CRainmeter::UpdateDesktopWorkArea(bool reset) LogWithArgs(LOG_DEBUG, L"DesktopWorkAreaType: %s", m_DesktopWorkAreaType ? L"Margin" : L"Default"); } - for (UINT i = 0; i <= CSystem::GetMonitorCount(); ++i) + for (UINT i = 0; i <= numOfMonitors; ++i) { std::map::const_iterator it = m_DesktopWorkAreas.find(i); if (it != m_DesktopWorkAreas.end()) { - RECT r = it->second; + RECT r = (*it).second; // Move rect to correct offset if (m_DesktopWorkAreaType) { RECT margin = r; - r = (i == 0) ? monitors[multimonInfo.primary - 1].screen : monitors[i - 1].screen; + r = (i == 0) ? monitors[monitorsInfo.primary - 1].screen : monitors[i - 1].screen; r.left += margin.left; r.top += margin.top; r.right -= margin.right; @@ -3380,34 +3382,32 @@ void CRainmeter::CreateMonitorMenu(HMENU monitorMenu, CMeterWindow* meterWindow) int screenIndex = meterWindow->GetXScreen(); // for the "Specified monitor" (@n) - if (CSystem::GetMonitorCount() > 0) + const size_t numOfMonitors = CSystem::GetMonitorCount(); // intentional + const std::vector& monitors = CSystem::GetMultiMonitorInfo().monitors; + + int i = 1; + for (auto iter = monitors.cbegin(); iter != monitors.cend(); ++iter, ++i) { - const MultiMonitorInfo& multimonInfo = CSystem::GetMultiMonitorInfo(); - const std::vector& monitors = multimonInfo.monitors; + WCHAR buffer[64]; + size_t len = _snwprintf_s(buffer, _TRUNCATE, L"@%i: ", i); - for (int i = 0, isize = (int)monitors.size(); i < isize; ++i) + std::wstring item(buffer, len); + + if ((*iter).monitorName.size() > 32) { - WCHAR buffer[64]; - size_t len = _snwprintf_s(buffer, _TRUNCATE, L"@%i: ", i + 1); - - std::wstring item(buffer, len); - - if (monitors[i].monitorName.size() > 32) - { - item.append(monitors[i].monitorName, 0, 32); - item += L"..."; - } - else - { - item += monitors[i].monitorName; - } - - InsertMenu(monitorMenu, - i + 3, - MF_BYPOSITION | ((screenDefined && screenIndex == i + 1) ? MF_CHECKED : MF_UNCHECKED) | ((!monitors[i].active) ? MF_GRAYED : MF_ENABLED), - ID_MONITOR_FIRST + i + 1, - item.c_str()); + item.append((*iter).monitorName, 0, 32); + item += L"..."; } + else + { + item += (*iter).monitorName; + } + + InsertMenu(monitorMenu, + i + 2, + MF_BYPOSITION | ((screenDefined && screenIndex == i) ? MF_CHECKED : MF_UNCHECKED) | ((!(*iter).active) ? MF_GRAYED : MF_ENABLED), + ID_MONITOR_FIRST + i, + item.c_str()); } if (!screenDefined) diff --git a/Library/System.cpp b/Library/System.cpp index 77604fd9..40167146 100644 --- a/Library/System.cpp +++ b/Library/System.cpp @@ -179,13 +179,13 @@ BOOL CALLBACK MyInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonit if (m->useEnumDisplayDevices) { - for (size_t i = 0, isize = m->monitors.size(); i < isize; ++i) + for (auto iter = m->monitors.begin(); iter != m->monitors.end(); ++iter) { - if (m->monitors[i].handle == NULL && _wcsicmp(info.szDevice, m->monitors[i].deviceName.c_str()) == 0) + if ((*iter).handle == NULL && _wcsicmp(info.szDevice, (*iter).deviceName.c_str()) == 0) { - m->monitors[i].handle = hMonitor; - m->monitors[i].screen = *lprcMonitor; - m->monitors[i].work = info.rcWork; + (*iter).handle = hMonitor; + (*iter).screen = *lprcMonitor; + (*iter).work = info.rcWork; break; } } @@ -490,18 +490,19 @@ void CSystem::SetMultiMonitorInfo() c_Monitors.vsL, c_Monitors.vsT, c_Monitors.vsL + c_Monitors.vsW, c_Monitors.vsT + c_Monitors.vsH, c_Monitors.vsW, c_Monitors.vsH); - for (size_t i = 0, isize = monitors.size(); i < isize; ++i) + int i = 1; + for (auto iter = monitors.cbegin(); iter != monitors.cend(); ++iter, ++i) { - if (monitors[i].active) + if ((*iter).active) { - LogWithArgs(LOG_DEBUG, L"@%i: %s (active), MonitorName: %s", (int)i + 1, monitors[i].deviceName.c_str(), monitors[i].monitorName.c_str()); + LogWithArgs(LOG_DEBUG, L"@%i: %s (active), MonitorName: %s", i, (*iter).deviceName.c_str(), (*iter).monitorName.c_str()); LogWithArgs(LOG_DEBUG, L" L=%i, T=%i, R=%i, B=%i (W=%i, H=%i)", - monitors[i].screen.left, monitors[i].screen.top, monitors[i].screen.right, monitors[i].screen.bottom, - monitors[i].screen.right - monitors[i].screen.left, monitors[i].screen.bottom - monitors[i].screen.top); + (*iter).screen.left, (*iter).screen.top, (*iter).screen.right, (*iter).screen.bottom, + (*iter).screen.right - (*iter).screen.left, (*iter).screen.bottom - (*iter).screen.top); } else { - LogWithArgs(LOG_DEBUG, L"@%i: %s (inactive), MonitorName: %s", (int)i + 1, monitors[i].deviceName.c_str(), monitors[i].monitorName.c_str()); + LogWithArgs(LOG_DEBUG, L"@%i: %s (inactive), MonitorName: %s", i, (*iter).deviceName.c_str(), (*iter).monitorName.c_str()); } } Log(LOG_DEBUG, L"------------------------------"); @@ -522,19 +523,20 @@ void CSystem::UpdateWorkareaInfo() return; } - for (size_t i = 0, isize = monitors.size(); i < isize; ++i) + int i = 1; + for (auto iter = monitors.begin(); iter != monitors.end(); ++iter, ++i) { - if (monitors[i].active && monitors[i].handle != NULL) + if ((*iter).active && (*iter).handle != NULL) { MONITORINFO info = {sizeof(MONITORINFO)}; - GetMonitorInfo(monitors[i].handle, &info); + GetMonitorInfo((*iter).handle, &info); - monitors[i].work = info.rcWork; + (*iter).work = info.rcWork; if (Rainmeter->GetDebug()) { LogWithArgs(LOG_DEBUG, L"WorkArea@%i : L=%i, T=%i, R=%i, B=%i (W=%i, H=%i)", - (int)i + 1, + i, info.rcWork.left, info.rcWork.top, info.rcWork.right, info.rcWork.bottom, info.rcWork.right - info.rcWork.left, info.rcWork.bottom - info.rcWork.top); }