* Optimized some part for multi monitor
This commit is contained in:
spx 2013-02-09 01:52:41 +09:00
parent 9ce1403cbe
commit d25ae270c4
5 changed files with 279 additions and 300 deletions

View File

@ -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<MonitorInfo>& 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<MonitorInfo>& 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<MonitorInfo>& 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<MonitorInfo>& 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);
}
}

View File

@ -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<MonitorInfo>& 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<MonitorInfo>& monitors = multimonInfo.monitors;
const int numOfMonitors = (int)CSystem::GetMonitorCount();
const MultiMonitorInfo& monitorsInfo = CSystem::GetMultiMonitorInfo();
const std::vector<MonitorInfo>& 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<MonitorInfo>& 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<MonitorInfo>& 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<MonitorInfo>& 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<MonitorInfo>& 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<std::wstring, CMeterWindow*>::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;
}

View File

@ -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);

View File

@ -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<MonitorInfo>& monitors = multimonInfo.monitors;
const size_t numOfMonitors = CSystem::GetMonitorCount();
const MultiMonitorInfo& monitorsInfo = CSystem::GetMultiMonitorInfo();
const std::vector<MonitorInfo>& 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<UINT, RECT>::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<MonitorInfo>& 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<MonitorInfo>& 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)

View File

@ -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);
}