* Changed the way to get the information of the multiple display monitors.

This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)

-----

* Added the "Display Monitor" submenu in [Skins Menu]-[Position].

These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)

- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.

AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.

-----

* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.

The following variables are for the virtual screen.

 #VSCREENAREAX# is the X-position of the left-side of the virtual screen.
 #VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
 #VSCREENAREAWIDTH# is the width of the virtual screen.
 #VSCREENAREAHEIGHT# is the height of the virtual screen.

The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.

 #WORKAREAX# is the X-position of the left-side of the work area.
 #WORKAREAY# is the Y-position of the top-side of the work area.
 #WORKAREAWIDTH# is the width of the work area.
 #WORKAREAHEIGHT# is the height of the work area.
 #SCREENAREAX# is the X-position of the left-side of the monitor screen.
 #SCREENAREAY# is the Y-position of the top-side of the monitor screen.
 #SCREENAREAWIDTH# is the width of the display resolution.
 #SCREENAREAHEIGHT# is the height of the display resolution.

The following variables are for the PRIMARY monitor.

 #PWORKAREAX# is the X-position of the left-side of the work area.
 #PWORKAREAY# is the Y-position of the top-side of the work area.
 #PWORKAREAWIDTH# is the width of the work area.
 #PWORKAREAHEIGHT# is the height of the work area.
 #PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
 #PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
 #PSCREENAREAWIDTH# is the width of the display resolution.
 #PSCREENAREAHEIGHT# is the height of the display resolution.

The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)

 #WORKAREAX@n# is the X-position of the left-side of the work area.
 #WORKAREAY@n# is the Y-position of the top-side of the work area.
 #WORKAREAWIDTH@n# is the width of the work area.
 #WORKAREAHEIGHT@n# is the height of the work area.
 #SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
 #SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
 #SCREENAREAWIDTH@n# is the width of the display resolution.
 #SCREENAREAHEIGHT@n# is the height of the display resolution.

-----

* Other related changes:

- Fixed the problem that the primary monitor isn't recognized correctly.

- Fixed the problem that the information of the multiple display monitors is refreshed excessively.

- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.

- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.

- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)

-----

* Other changes:

- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.

- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.

- Fixed the problem that the Meter's hit-test code checks outside the area.

- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
This commit is contained in:
spx 2009-12-18 05:58:37 +00:00
parent 15353ea701
commit cc3ad487a7
12 changed files with 1558 additions and 296 deletions

View File

@ -26,6 +26,8 @@ extern CRainmeter* Rainmeter;
using namespace Gdiplus;
std::map<std::wstring, std::wstring> CConfigParser::c_MonitorVariables;
/*
** CConfigParser
**
@ -53,7 +55,7 @@ CConfigParser::~CConfigParser()
**
**
*/
void CConfigParser::Initialize(LPCTSTR filename, CRainmeter* pRainmeter)
void CConfigParser::Initialize(LPCTSTR filename, CRainmeter* pRainmeter, CMeterWindow* meterWindow)
{
m_Filename = filename;
@ -64,45 +66,41 @@ void CConfigParser::Initialize(LPCTSTR filename, CRainmeter* pRainmeter)
m_Sections.clear();
// Set the default variables. Do this before the ini file is read so that the paths can be used with @include
SetDefaultVariables(pRainmeter, meterWindow);
// Set the SCREENAREA/WORKAREA variables
if (c_MonitorVariables.empty())
{
SetMultiMonitorVariables(true);
}
// Set the SCREENAREA/WORKAREA variables for present monitor
SetAutoSelectedMonitorVariables(meterWindow);
ReadIniFile(m_Filename);
ReadVariables();
}
/*
** SetDefaultVariables
**
**
*/
void CConfigParser::SetDefaultVariables(CRainmeter* pRainmeter, CMeterWindow* meterWindow)
{
if (pRainmeter)
{
SetVariable(L"PROGRAMPATH", pRainmeter->GetPath());
SetVariable(L"SETTINGSPATH", pRainmeter->GetSettingsPath());
SetVariable(L"SKINSPATH", pRainmeter->GetSkinPath());
SetVariable(L"PLUGINSPATH", pRainmeter->GetPluginPath());
SetVariable(L"CURRENTPATH", CRainmeter::ExtractPath(filename));
// Set "CURRENTCONFIG" if the path to \Skins is contained in "filename", so it is not set by reading Rainmeter.ini
if (_wcsnicmp(filename, pRainmeter->GetSkinPath().c_str(), pRainmeter->GetSkinPath().length()) == 0)
{
std::wstring cPath = CRainmeter::ExtractPath(filename);
cPath = cPath.substr(pRainmeter->GetSkinPath().length(),
cPath.length()-pRainmeter->GetSkinPath().length()-1);
SetVariable(L"CURRENTCONFIG", cPath);
}
SetVariable(L"CURRENTPATH", CRainmeter::ExtractPath(m_Filename));
SetVariable(L"ADDONSPATH", pRainmeter->GetPath() + L"Addons\\");
RECT workArea;
SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);
TCHAR buffer[256];
swprintf(buffer, L"%i", workArea.left);
SetVariable(L"WORKAREAX", buffer);
swprintf(buffer, L"%i", workArea.top);
SetVariable(L"WORKAREAY", buffer);
swprintf(buffer, L"%i", workArea.right - workArea.left);
SetVariable(L"WORKAREAWIDTH", buffer);
swprintf(buffer, L"%i", workArea.bottom - workArea.top);
SetVariable(L"WORKAREAHEIGHT", buffer);
swprintf(buffer, L"%i", GetSystemMetrics(SM_CXSCREEN));
SetVariable(L"SCREENAREAWIDTH", buffer);
swprintf(buffer, L"%i", GetSystemMetrics(SM_CYSCREEN));
SetVariable(L"SCREENAREAHEIGHT", buffer);
}
ReadIniFile(m_Filename);
ReadVariables();
if (meterWindow)
{
SetVariable(L"CURRENTCONFIG", meterWindow->GetSkinName());
}
}
/*
@ -136,6 +134,235 @@ void CConfigParser::SetVariable(const std::wstring& strVariable, const std::wstr
m_Variables[strTmp] = strValue;
}
/*
** ResetVariables
**
**
*/
void CConfigParser::ResetVariables(CRainmeter* pRainmeter, CMeterWindow* meterWindow)
{
m_Variables.clear();
// Set the default variables. Do this before the ini file is read so that the paths can be used with @include
SetDefaultVariables(pRainmeter, meterWindow);
// Set the SCREENAREA/WORKAREA variables
if (c_MonitorVariables.empty())
{
SetMultiMonitorVariables(true);
}
// Set the SCREENAREA/WORKAREA variables for present monitor
SetAutoSelectedMonitorVariables(meterWindow);
ReadVariables();
}
/*
** SetMultiMonitorVariables
**
** Sets new values for the SCREENAREA/WORKAREA variables.
**
*/
void CConfigParser::SetMultiMonitorVariables(bool reset)
{
TCHAR buffer[256];
RECT workArea, scrArea;
if (!reset && c_MonitorVariables.empty())
{
reset = true; // Set all variables
}
SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);
swprintf(buffer, L"%i", workArea.left);
SetMonitorVariable(L"WORKAREAX", buffer);
SetMonitorVariable(L"PWORKAREAX", buffer);
swprintf(buffer, L"%i", workArea.top);
SetMonitorVariable(L"WORKAREAY", buffer);
SetMonitorVariable(L"PWORKAREAY", buffer);
swprintf(buffer, L"%i", workArea.right - workArea.left);
SetMonitorVariable(L"WORKAREAWIDTH", buffer);
SetMonitorVariable(L"PWORKAREAWIDTH", buffer);
swprintf(buffer, L"%i", workArea.bottom - workArea.top);
SetMonitorVariable(L"WORKAREAHEIGHT", buffer);
SetMonitorVariable(L"PWORKAREAHEIGHT", buffer);
if (reset)
{
scrArea.left = 0;
scrArea.top = 0;
scrArea.right = GetSystemMetrics(SM_CXSCREEN);
scrArea.bottom = GetSystemMetrics(SM_CYSCREEN);
swprintf(buffer, L"%i", scrArea.left);
SetMonitorVariable(L"SCREENAREAX", buffer);
SetMonitorVariable(L"PSCREENAREAX", buffer);
swprintf(buffer, L"%i", scrArea.top);
SetMonitorVariable(L"SCREENAREAY", buffer);
SetMonitorVariable(L"PSCREENAREAY", buffer);
swprintf(buffer, L"%i", scrArea.right - scrArea.left);
SetMonitorVariable(L"SCREENAREAWIDTH", buffer);
SetMonitorVariable(L"PSCREENAREAWIDTH", buffer);
swprintf(buffer, L"%i", scrArea.bottom - scrArea.top);
SetMonitorVariable(L"SCREENAREAHEIGHT", buffer);
SetMonitorVariable(L"PSCREENAREAHEIGHT", buffer);
swprintf(buffer, L"%i", GetSystemMetrics(SM_XVIRTUALSCREEN));
SetMonitorVariable(L"VSCREENAREAX", buffer);
swprintf(buffer, L"%i", GetSystemMetrics(SM_YVIRTUALSCREEN));
SetMonitorVariable(L"VSCREENAREAY", buffer);
swprintf(buffer, L"%i", GetSystemMetrics(SM_CXVIRTUALSCREEN));
SetMonitorVariable(L"VSCREENAREAWIDTH", buffer);
swprintf(buffer, L"%i", GetSystemMetrics(SM_CYVIRTUALSCREEN));
SetMonitorVariable(L"VSCREENAREAHEIGHT", buffer);
}
if (CMeterWindow::GetMonitorCount() > 0)
{
const MULTIMONITOR_INFO& multimonInfo = CMeterWindow::GetMultiMonitorInfo();
const std::vector<MONITOR_INFO>& monitors = multimonInfo.monitors;
for (size_t i = 0; i < monitors.size(); i++)
{
TCHAR buffer2[256];
const RECT work = (monitors[i].active) ? monitors[i].work : workArea;
swprintf(buffer, L"%i", work.left);
swprintf(buffer2, L"WORKAREAX@%i", i + 1);
SetMonitorVariable(buffer2, buffer);
swprintf(buffer, L"%i", work.top);
swprintf(buffer2, L"WORKAREAY@%i", i + 1);
SetMonitorVariable(buffer2, buffer);
swprintf(buffer, L"%i", work.right - work.left);
swprintf(buffer2, L"WORKAREAWIDTH@%i", i + 1);
SetMonitorVariable(buffer2, buffer);
swprintf(buffer, L"%i", work.bottom - work.top);
swprintf(buffer2, L"WORKAREAHEIGHT@%i", i + 1);
SetMonitorVariable(buffer2, buffer);
if (reset)
{
const RECT screen = (monitors[i].active) ? monitors[i].screen : scrArea;
swprintf(buffer, L"%i", screen.left);
swprintf(buffer2, L"SCREENAREAX@%i", i + 1);
SetMonitorVariable(buffer2, buffer);
swprintf(buffer, L"%i", screen.top);
swprintf(buffer2, L"SCREENAREAY@%i", i + 1);
SetMonitorVariable(buffer2, buffer);
swprintf(buffer, L"%i", screen.right - screen.left);
swprintf(buffer2, L"SCREENAREAWIDTH@%i", i + 1);
SetMonitorVariable(buffer2, buffer);
swprintf(buffer, L"%i", screen.bottom - screen.top);
swprintf(buffer2, L"SCREENAREAHEIGHT@%i", i + 1);
SetMonitorVariable(buffer2, buffer);
}
}
}
}
/**
** Sets a new value for the SCREENAREA/WORKAREA variable.
**
** \param strVariable
** \param strValue
*/
void CConfigParser::SetMonitorVariable(const std::wstring& strVariable, const std::wstring& strValue)
{
// DebugLog(L"MonitorVariable: %s=%s (size=%i)", strVariable.c_str(), strValue.c_str(), c_MonitorVariables.size());
std::wstring strTmp(strVariable);
std::transform(strTmp.begin(), strTmp.end(), strTmp.begin(), ::tolower);
c_MonitorVariables[strTmp] = strValue;
}
/*
** SetAutoSelectedMonitorVariables
**
** Sets new SCREENAREA/WORKAREA variables for present monitor.
**
*/
void CConfigParser::SetAutoSelectedMonitorVariables(CMeterWindow* meterWindow)
{
if (meterWindow)
{
if (CMeterWindow::GetMonitorCount() > 0)
{
TCHAR buffer[256];
int w1, w2, s1, s2;
const MULTIMONITOR_INFO& multimonInfo = CMeterWindow::GetMultiMonitorInfo();
const std::vector<MONITOR_INFO>& monitors = multimonInfo.monitors;
if (meterWindow->GetXScreenDefined())
{
int screenIndex = meterWindow->GetXScreen();
if (screenIndex >= 0 && (screenIndex == 0 || screenIndex <= (int)monitors.size() &&
screenIndex != multimonInfo.primary && monitors[screenIndex-1].active))
{
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;
}
swprintf(buffer, L"%i", w1);
SetVariable(L"WORKAREAX", buffer);
swprintf(buffer, L"%i", w2);
SetVariable(L"WORKAREAWIDTH", buffer);
swprintf(buffer, L"%i", s1);
SetVariable(L"SCREENAREAX", buffer);
swprintf(buffer, L"%i", s2);
SetVariable(L"SCREENAREAWIDTH", buffer);
}
}
if (meterWindow->GetYScreenDefined())
{
int screenIndex = meterWindow->GetYScreen();
if (screenIndex >= 0 && (screenIndex == 0 || screenIndex <= (int)monitors.size() &&
screenIndex != multimonInfo.primary && monitors[screenIndex-1].active))
{
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;
}
swprintf(buffer, L"%i", w1);
SetVariable(L"WORKAREAY", buffer);
swprintf(buffer, L"%i", w2);
SetVariable(L"WORKAREAHEIGHT", buffer);
swprintf(buffer, L"%i", s1);
SetVariable(L"SCREENAREAY", buffer);
swprintf(buffer, L"%i", s2);
SetVariable(L"SCREENAREAHEIGHT", buffer);
}
}
}
}
}
/**
** Replaces environment and internal variables in the given string.
**
@ -145,6 +372,11 @@ void CConfigParser::ReplaceVariables(std::wstring& result)
{
CRainmeter::ExpandEnvironmentVariables(result);
if (c_MonitorVariables.empty())
{
SetMultiMonitorVariables(true);
}
// Check for variables (#VAR#)
size_t start = 0;
size_t end = std::wstring::npos;
@ -171,7 +403,17 @@ void CConfigParser::ReplaceVariables(std::wstring& result)
}
else
{
start = end;
std::map<std::wstring, std::wstring>::iterator iter2 = c_MonitorVariables.find(strTmp);
if (iter2 != c_MonitorVariables.end())
{
// SCREENAREA/WORKAREA variable found, replace it with the value
result.replace(result.begin() + pos, result.begin() + end + 1, (*iter2).second);
start = pos + (*iter2).second.length();
}
else
{
start = end;
}
}
}
else

View File

@ -28,6 +28,7 @@
#include "ccalc-0.5.1/mparser.h"
class CRainmeter;
class CMeterWindow;
class CMeasure;
class CConfigParser
@ -36,11 +37,13 @@ public:
CConfigParser();
~CConfigParser();
void Initialize(LPCTSTR filename, CRainmeter* pRainmeter);
void Initialize(LPCTSTR filename, CRainmeter* pRainmeter, CMeterWindow* meterWindow = NULL);
void AddMeasure(CMeasure* pMeasure);
void SetVariable(const std::wstring& strVariable, const std::wstring& strValue);
void SetStyleTemplate(const std::wstring& strStyle) { m_StyleTemplate = strStyle; }
void ResetVariables(CRainmeter* pRainmeter, CMeterWindow* meterWindow = NULL);
const std::wstring& ReadString(LPCTSTR section, LPCTSTR key, LPCTSTR defValue, bool bReplaceMeasures = true);
double ReadFloat(LPCTSTR section, LPCTSTR key, double defValue);
double ReadFormula(LPCTSTR section, LPCTSTR key, double defValue);
@ -53,7 +56,11 @@ public:
static std::vector<std::wstring> Tokenize(const std::wstring& str, const std::wstring delimiters);
static void ClearMultiMonitorVariables() { c_MonitorVariables.clear(); }
static void UpdateWorkareaVariables() { SetMultiMonitorVariables(false); }
private:
void SetDefaultVariables(CRainmeter* pRainmeter, CMeterWindow* meterWindow);
void ReadVariables();
void ReplaceVariables(std::wstring& result);
Gdiplus::Color ParseColor(LPCTSTR string);
@ -63,6 +70,11 @@ private:
const std::wstring& GetValue(const std::wstring& strSection, const std::wstring& strKey, const std::wstring& strDefault);
std::vector<std::wstring> GetKeys(const std::wstring& strSection);
void SetAutoSelectedMonitorVariables(CMeterWindow* meterWindow);
static void SetMultiMonitorVariables(bool reset);
static void SetMonitorVariable(const std::wstring& strVariable, const std::wstring& strValue);
std::map<std::wstring, std::wstring> m_Variables;
std::wstring m_Filename;
@ -74,6 +86,8 @@ private:
std::vector<std::wstring> m_Sections; // The sections must be an ordered array
stdext::hash_map<std::wstring, std::vector<std::wstring> > m_Keys;
stdext::hash_map<std::wstring, std::wstring> m_Values;
static std::map<std::wstring, std::wstring> c_MonitorVariables;
};
#endif

View File

@ -194,7 +194,7 @@ int CMeter::GetY(bool abs)
*/
bool CMeter::HitTest(int x, int y)
{
if (x >= GetX() && x <= GetX() + GetW() && y >= GetY() && y <= GetY() + GetH())
if (x >= GetX() && x < GetX() + GetW() && y >= GetY() && y < GetY() + GetH())
{
return true;
}
@ -269,6 +269,9 @@ void CMeter::ReadConfig(const WCHAR* section)
m_RightMouseUpAction = parser.ReadString(section, L"RightMouseUpAction", L"", false);
m_LeftMouseUpAction = parser.ReadString(section, L"LeftMouseUpAction", L"", false);
m_MiddleMouseUpAction = parser.ReadString(section, L"MiddleMouseUpAction", L"", false);
m_RightMouseDoubleClickAction = parser.ReadString(section, L"RightMouseDoubleClickAction", L"", false);
m_LeftMouseDoubleClickAction = parser.ReadString(section, L"LeftMouseDoubleClickAction", L"", false);
m_MiddleMouseDoubleClickAction = parser.ReadString(section, L"MiddleMouseDoubleClickAction", L"", false);
m_MouseOverAction = parser.ReadString(section, L"MouseOverAction", L"", false);
m_MouseLeaveAction = parser.ReadString(section, L"MouseLeaveAction", L"", false);
@ -278,9 +281,9 @@ void CMeter::ReadConfig(const WCHAR* section)
m_MouseActionCursor = 0!= parser.ReadInt(section, L"MouseActionCursor", 1);
m_HasMouseAction =
( !m_MiddleMouseUpAction.empty() || !m_MiddleMouseDownAction.empty()
|| !m_LeftMouseUpAction.empty() || !m_LeftMouseDownAction.empty()
|| !m_RightMouseUpAction.empty() || !m_RightMouseDownAction.empty() );
( !m_LeftMouseUpAction.empty() || !m_LeftMouseDownAction.empty() || !m_LeftMouseDoubleClickAction.empty()
|| !m_MiddleMouseUpAction.empty() || !m_MiddleMouseDownAction.empty() || !m_MiddleMouseDoubleClickAction.empty()
|| !m_RightMouseUpAction.empty() || !m_RightMouseDownAction.empty() || !m_RightMouseDoubleClickAction.empty() );
m_MeasureName = parser.ReadString(section, L"MeasureName", L"");

View File

@ -52,10 +52,13 @@ public:
std::wstring& GetRightMouseDownAction() { return m_RightMouseDownAction; };
std::wstring& GetRightMouseUpAction() { return m_RightMouseUpAction; };
std::wstring& GetRightMouseDoubleClickAction() { return m_RightMouseDoubleClickAction; };
std::wstring& GetLeftMouseDownAction() { return m_LeftMouseDownAction; };
std::wstring& GetLeftMouseUpAction() { return m_LeftMouseUpAction; };
std::wstring& GetLeftMouseDoubleClickAction() { return m_LeftMouseDoubleClickAction; };
std::wstring& GetMiddleMouseDownAction() { return m_MiddleMouseDownAction; };
std::wstring& GetMiddleMouseUpAction() { return m_MiddleMouseUpAction; };
std::wstring& GetMiddleMouseDoubleClickAction() { return m_MiddleMouseDoubleClickAction; };
std::wstring& GetMouseOverAction() { return m_MouseOverAction; };
std::wstring& GetMouseLeaveAction() { return m_MouseLeaveAction; };
@ -112,12 +115,15 @@ protected:
static int c_OldX;
static int c_OldY;
std::wstring m_RightMouseDownAction; // Actions for left and right mouse buttons
std::wstring m_RightMouseDownAction; // Actions for left and right and middle mouse buttons
std::wstring m_RightMouseUpAction;
std::wstring m_RightMouseDoubleClickAction;
std::wstring m_LeftMouseDownAction;
std::wstring m_LeftMouseUpAction;
std::wstring m_LeftMouseDoubleClickAction;
std::wstring m_MiddleMouseDownAction;
std::wstring m_MiddleMouseUpAction;
std::wstring m_MiddleMouseDoubleClickAction;
std::wstring m_MouseOverAction;
std::wstring m_MouseLeaveAction;

View File

@ -226,8 +226,8 @@ bool CMeterButton::MouseUp(POINT pos, CMeterWindow* window)
if (m_State == BUTTON_STATE_DOWN)
{
if (m_Clicked &&
pos.x >= x && pos.x <= x + m_W &&
pos.y >= y && pos.y <= y + m_H)
pos.x >= x && pos.x < x + m_W &&
pos.y >= y && pos.y < y + m_H)
{
Color color;
m_Bitmap->GetPixel(pos.x - x + m_W * m_State, pos.y - y, &color);
@ -252,8 +252,8 @@ bool CMeterButton::MouseDown(POINT pos)
int x = GetX();
int y = GetY();
if (pos.x >= x && pos.x <= x + m_W &&
pos.y >= y && pos.y <= y + m_H)
if (pos.x >= x && pos.x < x + m_W &&
pos.y >= y && pos.y < y + m_H)
{
Color color;
m_Bitmap->GetPixel(pos.x - x + m_W * m_State, pos.y - y, &color);
@ -275,8 +275,8 @@ bool CMeterButton::MouseMove(POINT pos)
if (m_Clicked == true)
{
if (pos.x >= x && pos.x <= x + m_W &&
pos.y >= y && pos.y <= y + m_H)
if (pos.x >= x && pos.x < x + m_W &&
pos.y >= y && pos.y < y + m_H)
{
Color color;
m_Bitmap->GetPixel(pos.x - x + m_W * m_State, pos.y - y, &color);
@ -307,8 +307,8 @@ bool CMeterButton::MouseMove(POINT pos)
}
else
{
if (pos.x >= x && pos.x <= x + m_W &&
pos.y >= y && pos.y <= y + m_H)
if (pos.x >= x && pos.x < x + m_W &&
pos.y >= y && pos.y < y + m_H)
{
if (m_State == BUTTON_STATE_NORMAL)
{

File diff suppressed because it is too large Load Diff

View File

@ -37,15 +37,19 @@
#define WM_DELAYED_EXECUTE WM_APP + 0
#define WM_DELAYED_REFRESH WM_APP + 1
#define WM_DELAYED_QUIT WM_APP + 2
#define WM_DELAYED_MOVE WM_APP + 3
enum MOUSE
{
MOUSE_LMB_DOWN,
MOUSE_LMB_UP,
MOUSE_LMB_DBLCLK,
MOUSE_RMB_DOWN,
MOUSE_RMB_UP,
MOUSE_RMB_DBLCLK,
MOUSE_MMB_DOWN,
MOUSE_MMB_UP,
MOUSE_MMB_DBLCLK,
MOUSE_OVER,
MOUSE_LEAVE
};
@ -105,15 +109,25 @@ enum BANGCOMMAND
BANG_SETVARIABLE
};
typedef struct
struct MONITOR_INFO
{
int count; //Number of monitors
HMONITOR m_Monitors[32]; //Monitor info
RECT m_MonitorRect[32]; //Monitor rect on virtual screen
MONITORINFO m_MonitorInfo[32]; //Monitor information
//int index; //Utility for enumeration
int vsT, vsL, vsH, vsW;
} MULTIMONITOR_INFO;
bool active;
HMONITOR handle;
RECT screen;
RECT work;
WCHAR deviceName[32]; //Device name (E.g. "\\.\DISPLAY1")
WCHAR monitorName[128]; //Monitor name (E.g. "Generic Non-PnP Monitor")
};
struct MULTIMONITOR_INFO
{
bool useEnumDisplayDevices; //If true, use EnumDisplayDevices function to obtain the multi-monitor information
bool useEnumDisplayMonitors; //If true, use EnumDisplayMonitors function to obtain the multi-monitor information
int vsT, vsL, vsH, vsW; //Coordinates of the top-left corner (vsT,vsL) and size (vsH,vsW) of the virtual screen
int primary; //Index of the primary monitor
std::vector<MONITOR_INFO> monitors; //Monitor information
};
class CRainmeter;
class CMeasure;
@ -161,9 +175,15 @@ public:
bool GetXFromRight() { return m_WindowXFromRight; }
bool GetYFromBottom() { return m_WindowYFromBottom; }
bool GetXScreenDefined() { return m_WindowXScreenDefined; }
bool GetYScreenDefined() { return m_WindowYScreenDefined; }
int GetXScreen() { return m_WindowXScreen; }
int GetYScreen() { return m_WindowYScreen; }
bool GetNativeTransparency() { return m_NativeTransparency; }
bool GetClickThrough() { return m_ClickThrough; }
bool GetKeepOnScreen() { return m_KeepOnScreen; }
bool GetAutoSelectScreen() { return m_AutoSelectScreen; }
bool GetWindowDraggable() { return m_WindowDraggable; }
bool GetSavePosition() { return m_SavePosition; }
bool GetSnapEdges() { return m_SnapEdges; }
@ -180,6 +200,11 @@ public:
Gdiplus::PrivateFontCollection* GetPrivateFontCollection(){ return m_FontCollection; }
static const MULTIMONITOR_INFO& GetMultiMonitorInfo() { return c_Monitors; }
static void ClearMultiMonitorInfo() { c_Monitors.monitors.clear(); }
static size_t GetMonitorCount();
static void UpdateWorkareaInfo();
protected:
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
@ -189,6 +214,9 @@ protected:
LRESULT OnDestroy(WPARAM wParam, LPARAM lParam);
LRESULT OnTimer(WPARAM wParam, LPARAM lParam);
LRESULT OnCommand(WPARAM wParam, LPARAM lParam);
LRESULT OnSysCommand(WPARAM wParam, LPARAM lParam);
LRESULT OnEnterSizeMove(WPARAM wParam, LPARAM lParam);
LRESULT OnExitSizeMove(WPARAM wParam, LPARAM lParam);
LRESULT OnNcHitTest(WPARAM wParam, LPARAM lParam);
LRESULT OnWindowPosChanging(WPARAM wParam, LPARAM lParam);
LRESULT OnMouseMove(WPARAM wParam, LPARAM lParam);
@ -200,8 +228,12 @@ protected:
LRESULT OnLeftButtonUp(WPARAM wParam, LPARAM lParam);
LRESULT OnRightButtonUp(WPARAM wParam, LPARAM lParam);
LRESULT OnMiddleButtonUp(WPARAM wParam, LPARAM lParam);
LRESULT OnLeftButtonDoubleClick(WPARAM wParam, LPARAM lParam);
LRESULT OnRightButtonDoubleClick(WPARAM wParam, LPARAM lParam);
LRESULT OnMiddleButtonDoubleClick(WPARAM wParam, LPARAM lParam);
LRESULT OnDelayedExecute(WPARAM wParam, LPARAM lParam);
LRESULT OnDelayedRefresh(WPARAM wParam, LPARAM lParam);
LRESULT OnDelayedMove(WPARAM wParam, LPARAM lParam);
LRESULT OnDelayedQuit(WPARAM wParam, LPARAM lParam);
LRESULT OnSettingChange(WPARAM wParam, LPARAM lParam);
LRESULT OnDisplayChange(WPARAM wParam, LPARAM lParam);
@ -224,6 +256,8 @@ private:
bool DoAction(int x, int y, MOUSE mouse, bool test);
bool ResizeWindow(bool reset);
static void SetMultiMonitorInfo();
CConfigParser m_Parser;
Gdiplus::Bitmap* m_DoubleBuffer;
@ -240,6 +274,9 @@ private:
std::wstring m_RightMouseUpAction; // Action to run when right mouse is released
std::wstring m_LeftMouseUpAction; // Action to run when left mouse is released
std::wstring m_MiddleMouseUpAction; // Action to run when middle mouse is released
std::wstring m_RightMouseDoubleClickAction; // Action to run when right mouse is double-clicked
std::wstring m_LeftMouseDoubleClickAction; // Action to run when left mouse is double-clicked
std::wstring m_MiddleMouseDoubleClickAction; // Action to run when middle mouse is double-clicked
std::wstring m_MouseOverAction; // Action to run when mouse goes over the window
std::wstring m_MouseLeaveAction; // Action to run when mouse leaves the window
std::wstring m_OnRefreshAction; // Action to run when window is initialized
@ -256,12 +293,12 @@ private:
std::wstring m_AnchorY; // Anchor's Y-position in config file
int m_WindowXScreen;
int m_WindowYScreen;
bool m_WindowXScreenDefined;
bool m_WindowYScreenDefined;
bool m_WindowXFromRight;
bool m_WindowYFromBottom;
bool m_WindowXPercentage;
bool m_WindowYPercentage;
float m_WindowXNumber; // Store the number portion from the config
float m_WindowYNumber; // Store the number portion from the config
int m_WindowW; // Window's Width
int m_WindowH; // Window's Height
int m_ScreenX; // Window's X-postion on the virtual screen
@ -270,11 +307,8 @@ private:
bool m_AnchorYFromBottom;
bool m_AnchorXPercentage;
bool m_AnchorYPercentage;
float m_AnchorXNumber; // Store the number portion from the config
float m_AnchorYNumber; // Store the number portion from the config
int m_AnchorScreenX; // Window's anchor X-postion
int m_AnchorScreenY; // Window's anchor Y-postion
static MULTIMONITOR_INFO m_Monitors; // Multi-Monitor info
bool m_WindowDraggable; // True, if window can be moved
int m_WindowUpdate; // Measure update frequency
int m_TransitionUpdate; // Transition redraw frequency
@ -291,7 +325,10 @@ private:
bool m_DynamicWindowSize; //
bool m_ClickThrough; //
bool m_KeepOnScreen; //
bool m_AutoSelectScreen; //
bool m_Dragging; //
bool m_Dragged; //
bool m_PreventMoving; //
BGMODE m_BackgroundMode; // The background mode
Gdiplus::Color m_SolidColor; // Color of the solid background
Gdiplus::Color m_SolidColor2; // Color of the solid background
@ -325,6 +362,8 @@ private:
static int c_InstanceCount;
static MULTIMONITOR_INFO c_Monitors; // Multi-Monitor info
Gdiplus::PrivateFontCollection* m_FontCollection;
bool m_MouseActionCursor;

View File

@ -1781,9 +1781,9 @@ void CRainmeter::ReadGeneralSettings(std::wstring& iniFile)
c_GlobalConfig.netInSpeed = parser.ReadFloat(L"Rainmeter", L"NetInSpeed", c_GlobalConfig.netInSpeed);
c_GlobalConfig.netOutSpeed = parser.ReadFloat(L"Rainmeter", L"NetOutSpeed", c_GlobalConfig.netOutSpeed);
m_ConfigEditor = parser.ReadString(L"Rainmeter", L"ConfigEditor", m_ConfigEditor.c_str());
if(m_ConfigEditor.substr(0,1) != L"\"")
m_ConfigEditor = parser.ReadString(L"Rainmeter", L"ConfigEditor", m_ConfigEditor.c_str());
if (!m_ConfigEditor.empty() && m_ConfigEditor[0] != L'\"')
{
m_ConfigEditor.insert(0,L"\"");
m_ConfigEditor.append(L"\"");
@ -2185,6 +2185,13 @@ HMENU CRainmeter::CreateSkinMenu(CMeterWindow* meterWindow, int index)
{
EnableMenuItem(posMenu, ID_CONTEXT_SKINMENU_ONDESKTOP, MF_BYCOMMAND | MF_GRAYED);
}
HMENU monitorMenu = CreateMonitorMenu(meterWindow);
if (monitorMenu)
{
InsertMenu(posMenu, 0, MF_BYPOSITION | MF_POPUP, (UINT_PTR)monitorMenu, L"Display Monitor");
InsertMenu(posMenu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
}
}
// Tick the transparency
@ -2268,6 +2275,84 @@ HMENU CRainmeter::CreateSkinMenu(CMeterWindow* meterWindow, int index)
return skinMenu;
}
HMENU CRainmeter::CreateMonitorMenu(CMeterWindow* meterWindow)
{
WCHAR buffer[256];
std::wstring item;
UINT flags;
HMENU monitorMenu = CreatePopupMenu();
bool screenDefined = meterWindow->GetXScreenDefined();
int screenIndex = meterWindow->GetXScreen();
// for the "Primary monitor"
flags = 0;
if (!screenDefined)
{
flags |= MF_CHECKED;
}
AppendMenu(monitorMenu, flags, ID_CONTEXT_SKINMENU_MONITOR_PRIMARY, L"Use default: Primary monitor");
// for the "Virtual screen" (@0)
flags = 0;
if (screenDefined && screenIndex == 0)
{
flags |= MF_CHECKED;
}
AppendMenu(monitorMenu, flags, ID_MONITOR_FIRST, L"@0: Virtual screen");
// for the "Specified monitor" (@n)
if (CMeterWindow::GetMonitorCount() > 0)
{
AppendMenu(monitorMenu, MF_SEPARATOR, 0, NULL);
const MULTIMONITOR_INFO& multimonInfo = CMeterWindow::GetMultiMonitorInfo();
const std::vector<MONITOR_INFO>& monitors = multimonInfo.monitors;
for (size_t i = 0; i < monitors.size(); i++)
{
wsprintf(buffer, L"@%i: ", i + 1);
item = buffer;
flags = 0;
if (screenDefined && screenIndex == (int)i + 1)
{
flags |= MF_CHECKED;
}
size_t len = wcslen(monitors[i].monitorName);
if (len > 32)
{
item += std::wstring(monitors[i].monitorName, 32);
item += L"...";
}
else
{
item += monitors[i].monitorName;
}
if (!monitors[i].active)
{
flags |= MF_GRAYED;
}
AppendMenu(monitorMenu, flags, ID_MONITOR_FIRST + i + 1, item.c_str());
}
}
AppendMenu(monitorMenu, MF_SEPARATOR, 0, NULL);
flags = 0;
if (meterWindow->GetAutoSelectScreen())
{
flags |= MF_CHECKED;
}
AppendMenu(monitorMenu, flags, ID_CONTEXT_SKINMENU_MONITOR_AUTOSELECT, L"Auto-select based on window position");
return monitorMenu;
}
void CRainmeter::ChangeSkinIndex(HMENU menu, int index)
{
int count = GetMenuItemCount(menu);

View File

@ -180,6 +180,7 @@ private:
int ScanForConfigsRecursive(std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu, bool DontRecurse);
HMENU CreateConfigMenu(std::vector<CONFIGMENU>& configMenuData);
HMENU CreateThemeMenu();
HMENU CreateMonitorMenu(CMeterWindow* meterWindow);
void CreateDefaultConfigFile(std::wstring strFile);
void TestSettingsFile(bool bDefaultIniLocation);
bool CopyFiles(std::wstring strFrom, std::wstring strTo, bool bMove = false);

View File

@ -488,7 +488,7 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
command += L"\"";
LSExecute(tray->GetWindow(), command.c_str(), SW_SHOWNORMAL);
}
else if((wParam & 0x0ffff) >= ID_THEME_FIRST)
else if((wParam & 0x0ffff) >= ID_THEME_FIRST && (wParam & 0x0ffff) <= ID_THEME_LAST)
{
int pos = (wParam & 0x0ffff) - ID_THEME_FIRST;
@ -502,7 +502,7 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
LSExecute(tray->GetWindow(), command.c_str(), SW_SHOWNORMAL);
}
}
else if((wParam & 0x0ffff) >= ID_CONFIG_FIRST)
else if((wParam & 0x0ffff) >= ID_CONFIG_FIRST && (wParam & 0x0ffff) <= ID_CONFIG_LAST)
{
wParam = wParam & 0x0ffff;
@ -650,6 +650,31 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
return 0;
// --- for CMeterWindow ---
case WM_DISPLAYCHANGE:
DebugLog(L"* Display setting has been changed.");
CMeterWindow::ClearMultiMonitorInfo();
CConfigParser::ClearMultiMonitorVariables();
case WM_SETTINGCHANGE:
if (uMsg == WM_DISPLAYCHANGE || (uMsg == WM_SETTINGCHANGE && wParam == SPI_SETWORKAREA))
{
if (uMsg == WM_SETTINGCHANGE) // SPI_SETWORKAREA
{
DebugLog(L"* Work area has been changed.");
CMeterWindow::UpdateWorkareaInfo();
CConfigParser::UpdateWorkareaVariables();
}
// Deliver WM_DISPLAYCHANGE / WM_SETTINGCHANGE message to all meter windows
std::map<std::wstring, CMeterWindow*>& windows = Rainmeter->GetAllMeterWindows();
std::map<std::wstring, CMeterWindow*>::iterator iter = windows.begin();
for( ; iter != windows.end(); iter++)
{
PostMessage((*iter).second->GetWindow(), WM_DELAYED_MOVE, (WPARAM)uMsg, (LPARAM)0);
}
}
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);

View File

@ -56,10 +56,16 @@
#define ID_CONTEXT_SKINMENU_OPENSKINSFOLDER 4045
#define ID_CONTEXT_MANAGETHEMES 4046
#define ID_CONTEXT_MANAGESKINS 4047
#define ID_CONTEXT_SKINMENU_MONITOR_PRIMARY 4048
#define ID_CONTEXT_SKINMENU_MONITOR_AUTOSELECT 4049
#define ID_CONFIG_EDIT 30000
#define ID_CONFIG_FIRST 30001
#define ID_THEME_FIRST 31001
#define ID_CONFIG_LAST 33000
#define ID_THEME_FIRST 33001
#define ID_THEME_LAST 36000
#define ID_MONITOR_FIRST 36001
#define ID_MONITOR_LAST 37000
// Next default values for new objects
//

View File

@ -153,6 +153,28 @@ HWND FindMeterWindow()
if (ProgmanHwnd)
{
wnd = FindWindowEx(ProgmanHwnd, NULL, L"RainmeterMeterWindow", NULL);
if (wnd == NULL)
{
ProgmanHwnd = FindWindowEx(FindWindowEx(ProgmanHwnd, NULL, L"SHELLDLL_DefView", L""), NULL, L"SysListView32", L"FolderView");
if (ProgmanHwnd)
{
wnd = FindWindowEx(ProgmanHwnd, NULL, L"RainmeterMeterWindow", NULL);
}
}
}
if (wnd == NULL)
{
HWND WorkerWHwnd = NULL;
while ((WorkerWHwnd = FindWindowEx(NULL, WorkerWHwnd, L"WorkerW", L"")) != NULL)
{
ProgmanHwnd = FindWindowEx(FindWindowEx(WorkerWHwnd, NULL, L"SHELLDLL_DefView", L""), NULL, L"SysListView32", L"FolderView");
if (ProgmanHwnd)
{
wnd = FindWindowEx(ProgmanHwnd, NULL, L"RainmeterMeterWindow", NULL);
break;
}
}
}
}
return wnd;