mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
- Added the workaround to pin the window to desktop in Vista/7 with Aero.
- Added !RainmeterSetTransparency, !RainmeterShowFade, !RainmeterHideFade, !RainmeterToggleFade. - Added the function to log the installed font families to the log file when Debug=1 is set. - Added the workaround for issue 145. The wrong drawing position was fixed when AntiAlias=0 is set.
This commit is contained in:
parent
015062bddb
commit
06ec730bfd
@ -20,6 +20,7 @@
|
|||||||
#include "ConfigParser.h"
|
#include "ConfigParser.h"
|
||||||
#include "Litestep.h"
|
#include "Litestep.h"
|
||||||
#include "Rainmeter.h"
|
#include "Rainmeter.h"
|
||||||
|
#include "System.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
extern CRainmeter* Rainmeter;
|
extern CRainmeter* Rainmeter;
|
||||||
@ -219,9 +220,9 @@ void CConfigParser::SetMultiMonitorVariables(bool reset)
|
|||||||
SetMonitorVariable(L"VSCREENAREAHEIGHT", buffer);
|
SetMonitorVariable(L"VSCREENAREAHEIGHT", buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CMeterWindow::GetMonitorCount() > 0)
|
if (CSystem::GetMonitorCount() > 0)
|
||||||
{
|
{
|
||||||
const MULTIMONITOR_INFO& multimonInfo = CMeterWindow::GetMultiMonitorInfo();
|
const MULTIMONITOR_INFO& multimonInfo = CSystem::GetMultiMonitorInfo();
|
||||||
const std::vector<MONITOR_INFO>& monitors = multimonInfo.monitors;
|
const std::vector<MONITOR_INFO>& monitors = multimonInfo.monitors;
|
||||||
|
|
||||||
for (size_t i = 0; i < monitors.size(); i++)
|
for (size_t i = 0; i < monitors.size(); i++)
|
||||||
@ -290,12 +291,12 @@ void CConfigParser::SetAutoSelectedMonitorVariables(CMeterWindow* meterWindow)
|
|||||||
|
|
||||||
if (meterWindow)
|
if (meterWindow)
|
||||||
{
|
{
|
||||||
if (CMeterWindow::GetMonitorCount() > 0)
|
if (CSystem::GetMonitorCount() > 0)
|
||||||
{
|
{
|
||||||
TCHAR buffer[256];
|
TCHAR buffer[256];
|
||||||
int w1, w2, s1, s2;
|
int w1, w2, s1, s2;
|
||||||
|
|
||||||
const MULTIMONITOR_INFO& multimonInfo = CMeterWindow::GetMultiMonitorInfo();
|
const MULTIMONITOR_INFO& multimonInfo = CSystem::GetMultiMonitorInfo();
|
||||||
const std::vector<MONITOR_INFO>& monitors = multimonInfo.monitors;
|
const std::vector<MONITOR_INFO>& monitors = multimonInfo.monitors;
|
||||||
|
|
||||||
if (meterWindow->GetXScreenDefined())
|
if (meterWindow->GetXScreenDefined())
|
||||||
|
@ -54,11 +54,12 @@ public:
|
|||||||
std::wstring& GetFilename() { return m_Filename; }
|
std::wstring& GetFilename() { return m_Filename; }
|
||||||
const std::vector<std::wstring>& GetSections();
|
const std::vector<std::wstring>& GetSections();
|
||||||
|
|
||||||
|
|
||||||
// Returns an int if the formula was read successfully, -1 for failure.
|
// Returns an int if the formula was read successfully, -1 for failure.
|
||||||
int ReadFormula(std::wstring& result, double* number);
|
int ReadFormula(std::wstring& result, double* number);
|
||||||
|
|
||||||
static std::vector<std::wstring> Tokenize(const std::wstring& str, const std::wstring delimiters);
|
static std::vector<std::wstring> Tokenize(const std::wstring& str, const std::wstring delimiters);
|
||||||
|
static double ParseDouble(const std::wstring& string, double defValue, bool rejectExp = false);
|
||||||
|
static Gdiplus::Color ParseColor(LPCTSTR string);
|
||||||
|
|
||||||
static void ClearMultiMonitorVariables() { c_MonitorVariables.clear(); }
|
static void ClearMultiMonitorVariables() { c_MonitorVariables.clear(); }
|
||||||
static void UpdateWorkareaVariables() { SetMultiMonitorVariables(false); }
|
static void UpdateWorkareaVariables() { SetMultiMonitorVariables(false); }
|
||||||
@ -68,9 +69,6 @@ private:
|
|||||||
void ReadVariables();
|
void ReadVariables();
|
||||||
void ReplaceVariables(std::wstring& result);
|
void ReplaceVariables(std::wstring& result);
|
||||||
|
|
||||||
double ParseDouble(const std::wstring& string, double defValue, bool rejectExp = false);
|
|
||||||
Gdiplus::Color ParseColor(LPCTSTR string);
|
|
||||||
|
|
||||||
void ReadIniFile(const std::wstring& strFileName, int depth = 0);
|
void ReadIniFile(const std::wstring& strFileName, int depth = 0);
|
||||||
void SetValue(const std::wstring& strSection, const std::wstring& strKey, const std::wstring& strValue);
|
void SetValue(const std::wstring& strSection, const std::wstring& strKey, const std::wstring& strValue);
|
||||||
const std::wstring& GetValue(const std::wstring& strSection, const std::wstring& strKey, const std::wstring& strDefault);
|
const std::wstring& GetValue(const std::wstring& strSection, const std::wstring& strKey, const std::wstring& strDefault);
|
||||||
|
@ -2610,6 +2610,10 @@
|
|||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\System.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="TrayWindow.cpp"
|
RelativePath="TrayWindow.cpp"
|
||||||
>
|
>
|
||||||
@ -2877,6 +2881,10 @@
|
|||||||
RelativePath=".\StdAfx.h"
|
RelativePath=".\StdAfx.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\System.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="TrayWindow.h"
|
RelativePath="TrayWindow.h"
|
||||||
>
|
>
|
||||||
|
@ -682,6 +682,11 @@ void CMeasureNet::InitializeNewApi()
|
|||||||
c_FreeMibTable = NULL;
|
c_FreeMibTable = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CRainmeter::GetDebug())
|
||||||
|
{
|
||||||
|
UpdateIFTable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -116,16 +116,34 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section)
|
|||||||
}
|
}
|
||||||
m_PluginName = Rainmeter->GetPluginPath() + m_PluginName;
|
m_PluginName = Rainmeter->GetPluginPath() + m_PluginName;
|
||||||
|
|
||||||
|
SetLastError(ERROR_SUCCESS);
|
||||||
m_Plugin = LoadLibrary(m_PluginName.c_str());
|
m_Plugin = LoadLibrary(m_PluginName.c_str());
|
||||||
|
|
||||||
if(m_Plugin == NULL)
|
if(m_Plugin == NULL)
|
||||||
{
|
{
|
||||||
|
if (CRainmeter::GetDebug())
|
||||||
|
{
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
DebugLog(L"Plugin: Unable to load plugin: \"%s\", ErrorCode=%i", m_PluginName.c_str(), err);
|
||||||
|
}
|
||||||
|
|
||||||
// Try to load from Rainmeter's folder
|
// Try to load from Rainmeter's folder
|
||||||
pos = m_PluginName.rfind(L'\\');
|
pos = m_PluginName.rfind(L'\\');
|
||||||
if (pos != std::wstring::npos)
|
if (pos != std::wstring::npos)
|
||||||
{
|
{
|
||||||
std::wstring pluginName = Rainmeter->GetPath() + m_PluginName.substr(pos + 1);
|
std::wstring pluginName = Rainmeter->GetPath() + m_PluginName.substr(pos + 1);
|
||||||
|
|
||||||
|
SetLastError(ERROR_SUCCESS);
|
||||||
m_Plugin = LoadLibrary(pluginName.c_str());
|
m_Plugin = LoadLibrary(pluginName.c_str());
|
||||||
|
|
||||||
|
if (m_Plugin == NULL)
|
||||||
|
{
|
||||||
|
if (CRainmeter::GetDebug())
|
||||||
|
{
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
DebugLog(L"Plugin: Unable to load plugin: \"%s\", ErrorCode=%i", pluginName.c_str(), err);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Plugin == NULL)
|
if (m_Plugin == NULL)
|
||||||
|
@ -643,10 +643,11 @@ bool CMeterImage::Draw(Graphics& graphics)
|
|||||||
drawH = m_H;
|
drawH = m_H;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (m_AntiAlias && m_Rotate != 0.0f)
|
if (!m_AntiAlias)
|
||||||
//{
|
{
|
||||||
// graphics.SetCompositingQuality(CompositingQualityHighQuality);
|
//graphics.SetInterpolationMode(InterpolationModeNearestNeighbor);
|
||||||
//}
|
graphics.SetPixelOffsetMode(PixelOffsetModeHalf);
|
||||||
|
}
|
||||||
|
|
||||||
Rect r(x, y, drawW, drawH);
|
Rect r(x, y, drawW, drawH);
|
||||||
graphics.DrawImage(drawBitmap, r, 0, 0, imageW, imageH, UnitPixel);
|
graphics.DrawImage(drawBitmap, r, 0, 0, imageW, imageH, UnitPixel);
|
||||||
|
@ -717,4 +717,60 @@ std::wstring StringToProper(std::wstring str)
|
|||||||
return str;//return the converted string
|
return str;//return the converted string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** EnumerateInstalledFontFamilies
|
||||||
|
**
|
||||||
|
** Static helper to log all installed font families.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CMeterString::EnumerateInstalledFontFamilies()
|
||||||
|
{
|
||||||
|
INT fontCount;
|
||||||
|
InstalledFontCollection fontCollection;
|
||||||
|
|
||||||
|
if (Ok == fontCollection.GetLastStatus())
|
||||||
|
{
|
||||||
|
fontCount = fontCollection.GetFamilyCount();
|
||||||
|
if (fontCount > 0)
|
||||||
|
{
|
||||||
|
INT fontFound;
|
||||||
|
|
||||||
|
FontFamily* fontFamilies = new FontFamily[fontCount];
|
||||||
|
|
||||||
|
if (Ok == fontCollection.GetFamilies(fontCount, fontFamilies, &fontFound))
|
||||||
|
{
|
||||||
|
std::wstring fonts;
|
||||||
|
for (INT i = 0; i < fontCount; i++)
|
||||||
|
{
|
||||||
|
WCHAR familyName[LF_FACESIZE];
|
||||||
|
if (Ok == fontFamilies[i].GetFamilyName(familyName))
|
||||||
|
{
|
||||||
|
fonts += familyName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fonts += L"***";
|
||||||
|
}
|
||||||
|
fonts += L", ";
|
||||||
|
}
|
||||||
|
LSLog(LOG_DEBUG, L"Rainmeter", fonts.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LSLog(LOG_DEBUG, L"Rainmeter", L"Failed to enumerate installed font families: GetFamilies() failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] fontFamilies;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LSLog(LOG_DEBUG, L"Rainmeter", L"There are no installed font families!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LSLog(LOG_DEBUG, L"Rainmeter", L"Failed to enumerate installed font families: InstalledFontCollection() failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// EOF
|
// EOF
|
||||||
|
@ -41,6 +41,7 @@ public:
|
|||||||
virtual void BindMeasure(std::list<CMeasure*>& measures);
|
virtual void BindMeasure(std::list<CMeasure*>& measures);
|
||||||
|
|
||||||
static void FreeFontCache();
|
static void FreeFontCache();
|
||||||
|
static void EnumerateInstalledFontFamilies();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum TEXTSTYLE
|
enum TEXTSTYLE
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -99,8 +99,12 @@ enum BANGCOMMAND
|
|||||||
BANG_SHOW,
|
BANG_SHOW,
|
||||||
BANG_HIDE,
|
BANG_HIDE,
|
||||||
BANG_TOGGLE,
|
BANG_TOGGLE,
|
||||||
|
BANG_SHOWFADE,
|
||||||
|
BANG_HIDEFADE,
|
||||||
|
BANG_TOGGLEFADE,
|
||||||
BANG_MOVE,
|
BANG_MOVE,
|
||||||
BANG_ZPOS,
|
BANG_ZPOS,
|
||||||
|
BANG_SETTRANSPARENCY,
|
||||||
BANG_LSHOOK,
|
BANG_LSHOOK,
|
||||||
BANG_ABOUT,
|
BANG_ABOUT,
|
||||||
BANG_MOVEMETER,
|
BANG_MOVEMETER,
|
||||||
@ -109,26 +113,6 @@ enum BANGCOMMAND
|
|||||||
BANG_SETVARIABLE
|
BANG_SETVARIABLE
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MONITOR_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 CRainmeter;
|
||||||
class CMeasure;
|
class CMeasure;
|
||||||
class CMeter;
|
class CMeter;
|
||||||
@ -200,11 +184,6 @@ public:
|
|||||||
|
|
||||||
Gdiplus::PrivateFontCollection* GetPrivateFontCollection(){ return m_FontCollection; }
|
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:
|
protected:
|
||||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
@ -255,8 +234,7 @@ private:
|
|||||||
void ShowWindowIfAppropriate();
|
void ShowWindowIfAppropriate();
|
||||||
bool DoAction(int x, int y, MOUSE mouse, bool test);
|
bool DoAction(int x, int y, MOUSE mouse, bool test);
|
||||||
bool ResizeWindow(bool reset);
|
bool ResizeWindow(bool reset);
|
||||||
|
void IgnoreAeroPeek();
|
||||||
static void SetMultiMonitorInfo();
|
|
||||||
|
|
||||||
CConfigParser m_Parser;
|
CConfigParser m_Parser;
|
||||||
|
|
||||||
@ -360,8 +338,6 @@ private:
|
|||||||
|
|
||||||
static int c_InstanceCount;
|
static int c_InstanceCount;
|
||||||
|
|
||||||
static MULTIMONITOR_INFO c_Monitors; // Multi-Monitor info
|
|
||||||
|
|
||||||
Gdiplus::PrivateFontCollection* m_FontCollection;
|
Gdiplus::PrivateFontCollection* m_FontCollection;
|
||||||
|
|
||||||
bool m_MouseActionCursor;
|
bool m_MouseActionCursor;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "Rainmeter.h"
|
#include "Rainmeter.h"
|
||||||
|
#include "System.h"
|
||||||
#include "Error.h"
|
#include "Error.h"
|
||||||
#include "AboutDialog.h"
|
#include "AboutDialog.h"
|
||||||
#include "MeasureNet.h"
|
#include "MeasureNet.h"
|
||||||
@ -244,11 +245,55 @@ void BangWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No config defined -> apply to all.
|
// No config defined -> apply to all.
|
||||||
|
|
||||||
|
// Make the sending order by using order of the config sections
|
||||||
|
std::vector<std::wstring> sections;
|
||||||
|
{
|
||||||
|
CConfigParser parser;
|
||||||
|
parser.Initialize(Rainmeter->GetIniFile().c_str(), Rainmeter);
|
||||||
|
sections = parser.GetSections();
|
||||||
|
}
|
||||||
|
std::vector<CMeterWindow*> windows(sections.size(), NULL);
|
||||||
|
std::vector<CMeterWindow*> windowsMissing;
|
||||||
|
|
||||||
std::map<std::wstring, CMeterWindow*>::iterator iter = Rainmeter->GetAllMeterWindows().begin();
|
std::map<std::wstring, CMeterWindow*>::iterator iter = Rainmeter->GetAllMeterWindows().begin();
|
||||||
|
|
||||||
for (; iter != Rainmeter->GetAllMeterWindows().end(); iter++)
|
for (; iter != Rainmeter->GetAllMeterWindows().end(); iter++)
|
||||||
{
|
{
|
||||||
((*iter).second)->RunBang(bang, argument.c_str());
|
CMeterWindow* window = (*iter).second;
|
||||||
|
bool find = false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < windows.size(); i++)
|
||||||
|
{
|
||||||
|
if (windows[i] == NULL && wcsicmp(sections[i].c_str(), window->GetSkinName().c_str()) == 0)
|
||||||
|
{
|
||||||
|
windows[i] = window;
|
||||||
|
find = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!find) // Not found for some reasons
|
||||||
|
{
|
||||||
|
windowsMissing.push_back(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply to all
|
||||||
|
std::vector<CMeterWindow*>::const_reverse_iterator iter2 = windows.rbegin();
|
||||||
|
for ( ; iter2 != windows.rend(); iter2++)
|
||||||
|
{
|
||||||
|
if (*iter2)
|
||||||
|
{
|
||||||
|
(*iter2)->RunBang(bang, argument.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < windowsMissing.size(); i++)
|
||||||
|
{
|
||||||
|
if (windowsMissing[i])
|
||||||
|
{
|
||||||
|
windowsMissing[i]->RunBang(bang, argument.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -293,6 +338,39 @@ void RainmeterToggle(HWND, const char* arg)
|
|||||||
BangWithArgs(BANG_TOGGLE, ConvertToWide(arg).c_str(), 0);
|
BangWithArgs(BANG_TOGGLE, ConvertToWide(arg).c_str(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** RainmeterHideFade
|
||||||
|
**
|
||||||
|
** Callback for the !RainmeterHideFade bang
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void RainmeterHideFade(HWND, const char* arg)
|
||||||
|
{
|
||||||
|
BangWithArgs(BANG_HIDEFADE, ConvertToWide(arg).c_str(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** RainmeterShowFade
|
||||||
|
**
|
||||||
|
** Callback for the !RainmeterShowFade bang
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void RainmeterShowFade(HWND, const char* arg)
|
||||||
|
{
|
||||||
|
BangWithArgs(BANG_SHOWFADE, ConvertToWide(arg).c_str(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** RainmeterToggleFade
|
||||||
|
**
|
||||||
|
** Callback for the !RainmeterToggleFade bang
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void RainmeterToggleFade(HWND, const char* arg)
|
||||||
|
{
|
||||||
|
BangWithArgs(BANG_TOGGLEFADE, ConvertToWide(arg).c_str(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** RainmeterHideMeter
|
** RainmeterHideMeter
|
||||||
**
|
**
|
||||||
@ -511,6 +589,17 @@ void RainmeterZPos(HWND, const char* arg)
|
|||||||
BangWithArgs(BANG_ZPOS, ConvertToWide(arg).c_str(), 1);
|
BangWithArgs(BANG_ZPOS, ConvertToWide(arg).c_str(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** RainmeterSetTransparency
|
||||||
|
**
|
||||||
|
** Callback for the !RainmeterSetTransparency bang
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void RainmeterSetTransparency(HWND, const char* arg)
|
||||||
|
{
|
||||||
|
BangWithArgs(BANG_SETTRANSPARENCY, ConvertToWide(arg).c_str(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** RainmeterLsHook
|
** RainmeterLsHook
|
||||||
**
|
**
|
||||||
@ -662,6 +751,8 @@ CRainmeter::~CRainmeter()
|
|||||||
|
|
||||||
CMeterString::FreeFontCache();
|
CMeterString::FreeFontCache();
|
||||||
|
|
||||||
|
CSystem::Finalize();
|
||||||
|
|
||||||
GdiplusShutdown(m_GDIplusToken);
|
GdiplusShutdown(m_GDIplusToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,6 +956,18 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath)
|
|||||||
CheckSkinVersions();
|
CheckSkinVersions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read Debug first
|
||||||
|
c_Debug = 0!=GetPrivateProfileInt(L"Rainmeter", L"Debug", 0, m_IniFile.c_str());
|
||||||
|
|
||||||
|
CSystem::Initialize(Instance);
|
||||||
|
CMeasureNet::InitializeNewApi();
|
||||||
|
|
||||||
|
if (c_Debug)
|
||||||
|
{
|
||||||
|
LSLog(LOG_DEBUG, L"Rainmeter", L"Enumerating installed font families ...");
|
||||||
|
CMeterString::EnumerateInstalledFontFamilies();
|
||||||
|
}
|
||||||
|
|
||||||
// Tray must exist before configs are read
|
// Tray must exist before configs are read
|
||||||
m_TrayWindow = new CTrayWindow(m_Instance);
|
m_TrayWindow = new CTrayWindow(m_Instance);
|
||||||
|
|
||||||
@ -884,8 +987,6 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath)
|
|||||||
CheckUpdate();
|
CheckUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
CMeasureNet::InitializeNewApi();
|
|
||||||
|
|
||||||
ResetStats();
|
ResetStats();
|
||||||
ReadStats();
|
ReadStats();
|
||||||
|
|
||||||
@ -915,6 +1016,9 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath)
|
|||||||
AddBangCommand("!RainmeterHide", RainmeterHide);
|
AddBangCommand("!RainmeterHide", RainmeterHide);
|
||||||
AddBangCommand("!RainmeterShow", RainmeterShow);
|
AddBangCommand("!RainmeterShow", RainmeterShow);
|
||||||
AddBangCommand("!RainmeterToggle", RainmeterToggle);
|
AddBangCommand("!RainmeterToggle", RainmeterToggle);
|
||||||
|
AddBangCommand("!RainmeterHideFade", RainmeterHideFade);
|
||||||
|
AddBangCommand("!RainmeterShowFade", RainmeterShowFade);
|
||||||
|
AddBangCommand("!RainmeterToggleFade", RainmeterToggleFade);
|
||||||
AddBangCommand("!RainmeterHideMeter", RainmeterHideMeter);
|
AddBangCommand("!RainmeterHideMeter", RainmeterHideMeter);
|
||||||
AddBangCommand("!RainmeterShowMeter", RainmeterShowMeter);
|
AddBangCommand("!RainmeterShowMeter", RainmeterShowMeter);
|
||||||
AddBangCommand("!RainmeterToggleMeter", RainmeterToggleMeter);
|
AddBangCommand("!RainmeterToggleMeter", RainmeterToggleMeter);
|
||||||
@ -926,6 +1030,7 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath)
|
|||||||
AddBangCommand("!RainmeterDeactivateConfig", RainmeterDeactivateConfig);
|
AddBangCommand("!RainmeterDeactivateConfig", RainmeterDeactivateConfig);
|
||||||
AddBangCommand("!RainmeterMove", RainmeterMove);
|
AddBangCommand("!RainmeterMove", RainmeterMove);
|
||||||
AddBangCommand("!RainmeterZPos", RainmeterZPos);
|
AddBangCommand("!RainmeterZPos", RainmeterZPos);
|
||||||
|
AddBangCommand("!RainmeterSetTransparency", RainmeterSetTransparency);
|
||||||
AddBangCommand("!RainmeterLsBoxHook", RainmeterLsHook);
|
AddBangCommand("!RainmeterLsBoxHook", RainmeterLsHook);
|
||||||
AddBangCommand("!RainmeterAbout", RainmeterAbout);
|
AddBangCommand("!RainmeterAbout", RainmeterAbout);
|
||||||
AddBangCommand("!RainmeterResetStats", RainmeterResetStats);
|
AddBangCommand("!RainmeterResetStats", RainmeterResetStats);
|
||||||
@ -935,12 +1040,54 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath)
|
|||||||
AddBangCommand("!RainmeterSetVariable", RainmeterSetVariable);
|
AddBangCommand("!RainmeterSetVariable", RainmeterSetVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create meter windows for active configs
|
// Make the starting order by using order of the config sections
|
||||||
|
std::vector<std::wstring> sections;
|
||||||
|
{
|
||||||
|
CConfigParser parser;
|
||||||
|
parser.Initialize(m_IniFile.c_str(), this);
|
||||||
|
sections = parser.GetSections();
|
||||||
|
}
|
||||||
|
std::vector<std::pair<int, int> > startup(sections.size(), std::pair<int, int>(0, 0));
|
||||||
|
std::vector<std::pair<int, int> > startupMissing;
|
||||||
|
|
||||||
for (size_t i = 0; i < m_ConfigStrings.size(); i++)
|
for (size_t i = 0; i < m_ConfigStrings.size(); i++)
|
||||||
{
|
{
|
||||||
if (m_ConfigStrings[i].active > 0 && m_ConfigStrings[i].active <= (int)m_ConfigStrings[i].iniFiles.size())
|
if (m_ConfigStrings[i].active > 0 && m_ConfigStrings[i].active <= (int)m_ConfigStrings[i].iniFiles.size())
|
||||||
{
|
{
|
||||||
ActivateConfig(i, m_ConfigStrings[i].active - 1);
|
bool find = false;
|
||||||
|
|
||||||
|
for (size_t j = 0; j < startup.size(); j++)
|
||||||
|
{
|
||||||
|
if (startup[j].second == 0 && wcsicmp(sections[j].c_str(), m_ConfigStrings[i].config.c_str()) == 0)
|
||||||
|
{
|
||||||
|
startup[j].first = i;
|
||||||
|
startup[j].second = m_ConfigStrings[i].active;
|
||||||
|
find = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!find) // Not found for some reasons
|
||||||
|
{
|
||||||
|
startupMissing.push_back(std::pair<int, int>(i, m_ConfigStrings[i].active));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create meter windows for active configs
|
||||||
|
std::vector<std::pair<int, int> >::const_reverse_iterator iter = startup.rbegin();
|
||||||
|
for ( ; iter != startup.rend(); iter++)
|
||||||
|
{
|
||||||
|
if ((*iter).second > 0)
|
||||||
|
{
|
||||||
|
ActivateConfig((*iter).first, (*iter).second - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < startupMissing.size(); i++)
|
||||||
|
{
|
||||||
|
if (startupMissing[i].second > 0)
|
||||||
|
{
|
||||||
|
ActivateConfig(startupMissing[i].first, startupMissing[i].second - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1278,7 +1425,8 @@ bool CRainmeter::DeleteMeterWindow(CMeterWindow* meterWindow, bool bLater)
|
|||||||
if (bLater)
|
if (bLater)
|
||||||
{
|
{
|
||||||
m_DelayDeleteList.push_back(meterWindow);
|
m_DelayDeleteList.push_back(meterWindow);
|
||||||
meterWindow->FadeWindow(meterWindow->GetAlphaValue(), 0); // Fade out the window
|
meterWindow->RunBang(BANG_HIDEFADE, NULL); // Fade out the window
|
||||||
|
//meterWindow->FadeWindow(meterWindow->GetAlphaValue(), 0); // Fade out the window
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1344,6 +1492,9 @@ void CRainmeter::Quit(HINSTANCE dllInst)
|
|||||||
RemoveBangCommand("!RainmeterHide");
|
RemoveBangCommand("!RainmeterHide");
|
||||||
RemoveBangCommand("!RainmeterShow");
|
RemoveBangCommand("!RainmeterShow");
|
||||||
RemoveBangCommand("!RainmeterToggle");
|
RemoveBangCommand("!RainmeterToggle");
|
||||||
|
RemoveBangCommand("!RainmeterHideFade");
|
||||||
|
RemoveBangCommand("!RainmeterShowFade");
|
||||||
|
RemoveBangCommand("!RainmeterToggleFade");
|
||||||
RemoveBangCommand("!RainmeterHideMeter");
|
RemoveBangCommand("!RainmeterHideMeter");
|
||||||
RemoveBangCommand("!RainmeterShowMeter");
|
RemoveBangCommand("!RainmeterShowMeter");
|
||||||
RemoveBangCommand("!RainmeterToggleMeter");
|
RemoveBangCommand("!RainmeterToggleMeter");
|
||||||
@ -1355,6 +1506,7 @@ void CRainmeter::Quit(HINSTANCE dllInst)
|
|||||||
RemoveBangCommand("!RainmeterToggleConfig");
|
RemoveBangCommand("!RainmeterToggleConfig");
|
||||||
RemoveBangCommand("!RainmeterMove");
|
RemoveBangCommand("!RainmeterMove");
|
||||||
RemoveBangCommand("!RainmeterZPos");
|
RemoveBangCommand("!RainmeterZPos");
|
||||||
|
RemoveBangCommand("!RainmeterSetTransparency");
|
||||||
RemoveBangCommand("!RainmeterLsBoxHook");
|
RemoveBangCommand("!RainmeterLsBoxHook");
|
||||||
RemoveBangCommand("!RainmeterAbout");
|
RemoveBangCommand("!RainmeterAbout");
|
||||||
RemoveBangCommand("!RainmeterResetStats");
|
RemoveBangCommand("!RainmeterResetStats");
|
||||||
@ -1518,6 +1670,18 @@ BOOL CRainmeter::ExecuteBang(const std::wstring& bang, const std::wstring& arg,
|
|||||||
{
|
{
|
||||||
BangWithArgs(BANG_TOGGLE, arg.c_str(), 0);
|
BangWithArgs(BANG_TOGGLE, arg.c_str(), 0);
|
||||||
}
|
}
|
||||||
|
else if (wcsicmp(bang.c_str(), L"!RainmeterHideFade") == 0)
|
||||||
|
{
|
||||||
|
BangWithArgs(BANG_HIDEFADE, arg.c_str(), 0);
|
||||||
|
}
|
||||||
|
else if (wcsicmp(bang.c_str(), L"!RainmeterShowFade") == 0)
|
||||||
|
{
|
||||||
|
BangWithArgs(BANG_SHOWFADE, arg.c_str(), 0);
|
||||||
|
}
|
||||||
|
else if (wcsicmp(bang.c_str(), L"!RainmeterToggleFade") == 0)
|
||||||
|
{
|
||||||
|
BangWithArgs(BANG_TOGGLEFADE, arg.c_str(), 0);
|
||||||
|
}
|
||||||
else if (wcsicmp(bang.c_str(), L"!RainmeterHideMeter") == 0)
|
else if (wcsicmp(bang.c_str(), L"!RainmeterHideMeter") == 0)
|
||||||
{
|
{
|
||||||
BangWithArgs(BANG_HIDEMETER, arg.c_str(), 1);
|
BangWithArgs(BANG_HIDEMETER, arg.c_str(), 1);
|
||||||
@ -1566,6 +1730,10 @@ BOOL CRainmeter::ExecuteBang(const std::wstring& bang, const std::wstring& arg,
|
|||||||
{
|
{
|
||||||
BangWithArgs(BANG_ZPOS, arg.c_str(), 1);
|
BangWithArgs(BANG_ZPOS, arg.c_str(), 1);
|
||||||
}
|
}
|
||||||
|
else if (wcsicmp(bang.c_str(), L"!RainmeterSetTransparency") == 0)
|
||||||
|
{
|
||||||
|
BangWithArgs(BANG_SETTRANSPARENCY, arg.c_str(), 1);
|
||||||
|
}
|
||||||
else if (wcsicmp(bang.c_str(), L"!RainmeterAbout") == 0)
|
else if (wcsicmp(bang.c_str(), L"!RainmeterAbout") == 0)
|
||||||
{
|
{
|
||||||
BangWithArgs(BANG_ABOUT, arg.c_str(), 0);
|
BangWithArgs(BANG_ABOUT, arg.c_str(), 0);
|
||||||
@ -1778,9 +1946,6 @@ void CRainmeter::ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow)
|
|||||||
*/
|
*/
|
||||||
void CRainmeter::ReadGeneralSettings(std::wstring& iniFile)
|
void CRainmeter::ReadGeneralSettings(std::wstring& iniFile)
|
||||||
{
|
{
|
||||||
// Read Debug first
|
|
||||||
c_Debug = 0!=GetPrivateProfileInt(L"Rainmeter", L"Debug", 0, iniFile.c_str());
|
|
||||||
|
|
||||||
CConfigParser parser;
|
CConfigParser parser;
|
||||||
parser.Initialize(iniFile.c_str(), this);
|
parser.Initialize(iniFile.c_str(), this);
|
||||||
|
|
||||||
@ -1891,34 +2056,34 @@ bool CRainmeter::SetActiveConfig(std::wstring& skinName, std::wstring& skinIni)
|
|||||||
** Refreshes Rainmeter. If argument is given the config is refreshed
|
** Refreshes Rainmeter. If argument is given the config is refreshed
|
||||||
** otherwise all active meters are refreshed
|
** otherwise all active meters are refreshed
|
||||||
*/
|
*/
|
||||||
void CRainmeter::Refresh(const WCHAR* arg)
|
//void CRainmeter::Refresh(const WCHAR* arg)
|
||||||
{
|
//{
|
||||||
std::wstring config, iniFile;
|
// std::wstring config, iniFile;
|
||||||
|
//
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
if (arg != NULL && wcslen(arg) > 0)
|
// if (arg != NULL && wcslen(arg) > 0)
|
||||||
{
|
// {
|
||||||
std::wstring config = arg;
|
// std::wstring config = arg;
|
||||||
CMeterWindow* meterWindow = GetMeterWindow(config);
|
// CMeterWindow* meterWindow = GetMeterWindow(config);
|
||||||
meterWindow->Refresh(false);
|
// meterWindow->Refresh(false);
|
||||||
}
|
// }
|
||||||
else
|
// else
|
||||||
{
|
// {
|
||||||
std::map<std::wstring, CMeterWindow*>::iterator iter = m_Meters.begin();
|
// std::map<std::wstring, CMeterWindow*>::iterator iter = m_Meters.begin();
|
||||||
|
//
|
||||||
// Refresh all
|
// // Refresh all
|
||||||
for (; iter != m_Meters.end(); iter++)
|
// for (; iter != m_Meters.end(); iter++)
|
||||||
{
|
// {
|
||||||
(*iter).second->Refresh(false);
|
// (*iter).second->Refresh(false);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
catch(CError& error)
|
// catch(CError& error)
|
||||||
{
|
// {
|
||||||
MessageBox(NULL, error.GetString().c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION);
|
// MessageBox(NULL, error.GetString().c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** ReadStats
|
** ReadStats
|
||||||
@ -2313,11 +2478,11 @@ HMENU CRainmeter::CreateMonitorMenu(CMeterWindow* meterWindow)
|
|||||||
AppendMenu(monitorMenu, flags, ID_MONITOR_FIRST, L"@0: Virtual screen");
|
AppendMenu(monitorMenu, flags, ID_MONITOR_FIRST, L"@0: Virtual screen");
|
||||||
|
|
||||||
// for the "Specified monitor" (@n)
|
// for the "Specified monitor" (@n)
|
||||||
if (CMeterWindow::GetMonitorCount() > 0)
|
if (CSystem::GetMonitorCount() > 0)
|
||||||
{
|
{
|
||||||
AppendMenu(monitorMenu, MF_SEPARATOR, 0, NULL);
|
AppendMenu(monitorMenu, MF_SEPARATOR, 0, NULL);
|
||||||
|
|
||||||
const MULTIMONITOR_INFO& multimonInfo = CMeterWindow::GetMultiMonitorInfo();
|
const MULTIMONITOR_INFO& multimonInfo = CSystem::GetMultiMonitorInfo();
|
||||||
const std::vector<MONITOR_INFO>& monitors = multimonInfo.monitors;
|
const std::vector<MONITOR_INFO>& monitors = multimonInfo.monitors;
|
||||||
|
|
||||||
for (size_t i = 0; i < monitors.size(); i++)
|
for (size_t i = 0; i < monitors.size(); i++)
|
||||||
|
@ -175,7 +175,7 @@ private:
|
|||||||
void ScanForThemes(std::wstring& path);
|
void ScanForThemes(std::wstring& path);
|
||||||
void ReadGeneralSettings(std::wstring& path);
|
void ReadGeneralSettings(std::wstring& path);
|
||||||
bool SetActiveConfig(std::wstring& skinName, std::wstring& skinIni);
|
bool SetActiveConfig(std::wstring& skinName, std::wstring& skinIni);
|
||||||
void Refresh(const WCHAR* arg);
|
//void Refresh(const WCHAR* arg);
|
||||||
HMENU CreateSkinMenu(CMeterWindow* meterWindow, int index);
|
HMENU CreateSkinMenu(CMeterWindow* meterWindow, int index);
|
||||||
void ChangeSkinIndex(HMENU subMenu, int index);
|
void ChangeSkinIndex(HMENU subMenu, int index);
|
||||||
int ScanForConfigsRecursive(std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu, bool DontRecurse);
|
int ScanForConfigsRecursive(std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu, bool DontRecurse);
|
||||||
|
793
Library/System.cpp
Normal file
793
Library/System.cpp
Normal file
@ -0,0 +1,793 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2010 spx
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdAfx.h"
|
||||||
|
#include "System.h"
|
||||||
|
#include "Litestep.h"
|
||||||
|
#include "Rainmeter.h"
|
||||||
|
#include "Error.h"
|
||||||
|
|
||||||
|
enum TIMER
|
||||||
|
{
|
||||||
|
TIMER_SHOWDESKTOP = 1,
|
||||||
|
TIMER_COMPOSITION = 2
|
||||||
|
};
|
||||||
|
enum INTERVAL
|
||||||
|
{
|
||||||
|
INTERVAL_SHOWDESKTOP = 250,
|
||||||
|
INTERVAL_COMPOSITION = 250
|
||||||
|
};
|
||||||
|
|
||||||
|
MULTIMONITOR_INFO CSystem::c_Monitors = { 0 };
|
||||||
|
|
||||||
|
HWND CSystem::c_Window = NULL;
|
||||||
|
bool CSystem::c_DwmCompositionEnabled = false;
|
||||||
|
bool CSystem::c_ShowDesktop = false;
|
||||||
|
|
||||||
|
extern CRainmeter* Rainmeter;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Initialize
|
||||||
|
**
|
||||||
|
** Creates a window to detect changes in the system.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CSystem::Initialize(HINSTANCE instance)
|
||||||
|
{
|
||||||
|
WNDCLASS wc = {0};
|
||||||
|
wc.lpfnWndProc = (WNDPROC)WndProc;
|
||||||
|
wc.hInstance = instance;
|
||||||
|
wc.lpszClassName = L"RainmeterSystemClass";
|
||||||
|
|
||||||
|
RegisterClass(&wc);
|
||||||
|
|
||||||
|
c_Window = CreateWindowEx(
|
||||||
|
WS_EX_TOOLWINDOW,
|
||||||
|
L"RainmeterSystemClass",
|
||||||
|
NULL,
|
||||||
|
WS_POPUP,
|
||||||
|
CW_USEDEFAULT,
|
||||||
|
CW_USEDEFAULT,
|
||||||
|
CW_USEDEFAULT,
|
||||||
|
CW_USEDEFAULT,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
instance,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
SetWindowPos(c_Window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
|
||||||
|
|
||||||
|
#ifndef _WIN64
|
||||||
|
SetWindowLong(c_Window, GWL_USERDATA, magicDWord);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SetMultiMonitorInfo();
|
||||||
|
|
||||||
|
c_DwmCompositionEnabled = (DwmIsCompositionEnabled() == TRUE);
|
||||||
|
if (c_DwmCompositionEnabled)
|
||||||
|
{
|
||||||
|
SetTimer(c_Window, TIMER_SHOWDESKTOP, INTERVAL_SHOWDESKTOP, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Finalize
|
||||||
|
**
|
||||||
|
** Destroys a window.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CSystem::Finalize()
|
||||||
|
{
|
||||||
|
KillTimer(c_Window, TIMER_SHOWDESKTOP);
|
||||||
|
KillTimer(c_Window, TIMER_COMPOSITION);
|
||||||
|
|
||||||
|
if (c_Window) DestroyWindow(c_Window);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MyInfoEnumProc
|
||||||
|
**
|
||||||
|
** Retrieves the multi-monitor information.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
BOOL CALLBACK MyInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
|
||||||
|
{
|
||||||
|
MULTIMONITOR_INFO* m = (MULTIMONITOR_INFO*)dwData;
|
||||||
|
|
||||||
|
MONITORINFOEX info;
|
||||||
|
info.cbSize = sizeof(MONITORINFOEX);
|
||||||
|
GetMonitorInfo(hMonitor, &info);
|
||||||
|
|
||||||
|
if (CRainmeter::GetDebug())
|
||||||
|
{
|
||||||
|
DebugLog(info.szDevice);
|
||||||
|
DebugLog(L" Flags : %s(0x%08X)", (info.dwFlags & MONITORINFOF_PRIMARY) ? L"PRIMARY " : L"", info.dwFlags);
|
||||||
|
DebugLog(L" Handle : 0x%08X", hMonitor);
|
||||||
|
DebugLog(L" ScrArea : L=%i, T=%i, R=%i, B=%i (W=%i, H=%i)",
|
||||||
|
lprcMonitor->left, lprcMonitor->top, lprcMonitor->right, lprcMonitor->bottom,
|
||||||
|
lprcMonitor->right - lprcMonitor->left, lprcMonitor->bottom - lprcMonitor->top);
|
||||||
|
DebugLog(L" WorkArea : L=%i, T=%i, R=%i, B=%i (W=%i, H=%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);
|
||||||
|
}
|
||||||
|
if (m == NULL) return TRUE;
|
||||||
|
|
||||||
|
if (m->useEnumDisplayDevices)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < m->monitors.size(); i++)
|
||||||
|
{
|
||||||
|
if (m->monitors[i].handle == NULL && _wcsnicmp(info.szDevice, m->monitors[i].deviceName, 32) == 0)
|
||||||
|
{
|
||||||
|
m->monitors[i].handle = hMonitor;
|
||||||
|
m->monitors[i].screen = *lprcMonitor;
|
||||||
|
m->monitors[i].work = info.rcWork;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // use only EnumDisplayMonitors
|
||||||
|
{
|
||||||
|
MONITOR_INFO monitor = {0};
|
||||||
|
monitor.active = true;
|
||||||
|
|
||||||
|
monitor.handle = hMonitor;
|
||||||
|
monitor.screen = *lprcMonitor;
|
||||||
|
monitor.work = info.rcWork;
|
||||||
|
|
||||||
|
wcsncpy(monitor.deviceName, info.szDevice, 32); // E.g. "\\.\DISPLAY1"
|
||||||
|
|
||||||
|
// Get the monitor name (E.g. "Generic Non-PnP Monitor")
|
||||||
|
DISPLAY_DEVICE ddm = {0};
|
||||||
|
ddm.cb = sizeof(DISPLAY_DEVICE);
|
||||||
|
DWORD dwMon = 0;
|
||||||
|
while (EnumDisplayDevices(info.szDevice, dwMon++, &ddm, 0))
|
||||||
|
{
|
||||||
|
if (ddm.StateFlags & DISPLAY_DEVICE_ACTIVE && ddm.StateFlags & DISPLAY_DEVICE_ATTACHED)
|
||||||
|
{
|
||||||
|
wcsncpy(monitor.monitorName, ddm.DeviceString, 128);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m->monitors.push_back(monitor);
|
||||||
|
|
||||||
|
if (info.dwFlags & MONITORINFOF_PRIMARY)
|
||||||
|
{
|
||||||
|
// It's primary monitor!
|
||||||
|
m->primary = (int)m->monitors.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GetMonitorCount
|
||||||
|
**
|
||||||
|
** Returns the number of monitors.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
size_t CSystem::GetMonitorCount()
|
||||||
|
{
|
||||||
|
if (c_Monitors.monitors.size() == 0)
|
||||||
|
{
|
||||||
|
SetMultiMonitorInfo();
|
||||||
|
}
|
||||||
|
return c_Monitors.monitors.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* SetMultiMonitorInfo
|
||||||
|
**
|
||||||
|
** Sets the multi-monitor information.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CSystem::SetMultiMonitorInfo()
|
||||||
|
{
|
||||||
|
std::vector<MONITOR_INFO>& monitors = c_Monitors.monitors;
|
||||||
|
bool logging = CRainmeter::GetDebug();
|
||||||
|
|
||||||
|
if (monitors.capacity() < 16) { monitors.reserve(16); }
|
||||||
|
|
||||||
|
c_Monitors.vsT = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
||||||
|
c_Monitors.vsL = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||||||
|
c_Monitors.vsH = GetSystemMetrics(SM_CYVIRTUALSCREEN);
|
||||||
|
c_Monitors.vsW = GetSystemMetrics(SM_CXVIRTUALSCREEN);
|
||||||
|
|
||||||
|
c_Monitors.primary = 1; // If primary screen is not found, 1st screen is assumed as primary screen.
|
||||||
|
|
||||||
|
c_Monitors.useEnumDisplayDevices = true;
|
||||||
|
c_Monitors.useEnumDisplayMonitors = false;
|
||||||
|
|
||||||
|
if (logging)
|
||||||
|
{
|
||||||
|
DebugLog(L"------------------------------");
|
||||||
|
DebugLog(L"* EnumDisplayDevices / EnumDisplaySettings API");
|
||||||
|
}
|
||||||
|
|
||||||
|
DISPLAY_DEVICE dd = {0};
|
||||||
|
dd.cb = sizeof(DISPLAY_DEVICE);
|
||||||
|
|
||||||
|
if (EnumDisplayDevices(NULL, 0, &dd, 0))
|
||||||
|
{
|
||||||
|
DWORD dwDevice = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
std::wstring msg;
|
||||||
|
|
||||||
|
if (logging)
|
||||||
|
{
|
||||||
|
DebugLog(dd.DeviceName);
|
||||||
|
|
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_ACTIVE)
|
||||||
|
{
|
||||||
|
msg += L"ACTIVE ";
|
||||||
|
}
|
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_MULTI_DRIVER)
|
||||||
|
{
|
||||||
|
msg += L"MULTI ";
|
||||||
|
}
|
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
||||||
|
{
|
||||||
|
msg += L"PRIMARY ";
|
||||||
|
}
|
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER)
|
||||||
|
{
|
||||||
|
msg += L"MIRROR ";
|
||||||
|
}
|
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_VGA_COMPATIBLE)
|
||||||
|
{
|
||||||
|
msg += L"VGA ";
|
||||||
|
}
|
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_REMOVABLE)
|
||||||
|
{
|
||||||
|
msg += L"REMOVABLE ";
|
||||||
|
}
|
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_MODESPRUNED)
|
||||||
|
{
|
||||||
|
msg += L"PRUNED ";
|
||||||
|
}
|
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_REMOTE)
|
||||||
|
{
|
||||||
|
msg += L"REMOTE ";
|
||||||
|
}
|
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_DISCONNECT)
|
||||||
|
{
|
||||||
|
msg += L"DISCONNECT ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) == 0)
|
||||||
|
{
|
||||||
|
MONITOR_INFO monitor = {0};
|
||||||
|
|
||||||
|
monitor.handle = NULL;
|
||||||
|
wcsncpy(monitor.deviceName, dd.DeviceName, 32); // E.g. "\\.\DISPLAY1"
|
||||||
|
|
||||||
|
// Get the monitor name (E.g. "Generic Non-PnP Monitor")
|
||||||
|
DISPLAY_DEVICE ddm = {0};
|
||||||
|
ddm.cb = sizeof(DISPLAY_DEVICE);
|
||||||
|
DWORD dwMon = 0;
|
||||||
|
while (EnumDisplayDevices(dd.DeviceName, dwMon++, &ddm, 0))
|
||||||
|
{
|
||||||
|
if (ddm.StateFlags & DISPLAY_DEVICE_ACTIVE && ddm.StateFlags & DISPLAY_DEVICE_ATTACHED)
|
||||||
|
{
|
||||||
|
wcsncpy(monitor.monitorName, ddm.DeviceString, 128);
|
||||||
|
|
||||||
|
if (logging)
|
||||||
|
{
|
||||||
|
DebugLog(L" Name : %s", ddm.DeviceString);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logging)
|
||||||
|
{
|
||||||
|
DebugLog(L" Adapter : %s", dd.DeviceString);
|
||||||
|
DebugLog(L" Flags : %s(0x%08X)", msg.c_str(), dd.StateFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_ACTIVE)
|
||||||
|
{
|
||||||
|
monitor.active = true;
|
||||||
|
|
||||||
|
DEVMODE dm = {0};
|
||||||
|
dm.dmSize = sizeof(DEVMODE);
|
||||||
|
|
||||||
|
if (EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dm))
|
||||||
|
{
|
||||||
|
POINT pos = {dm.dmPosition.x, dm.dmPosition.y};
|
||||||
|
monitor.handle = MonitorFromPoint(pos, MONITOR_DEFAULTTONULL);
|
||||||
|
|
||||||
|
if (logging)
|
||||||
|
{
|
||||||
|
DebugLog(L" Handle : 0x%08X", monitor.handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitor.handle != NULL)
|
||||||
|
{
|
||||||
|
MONITORINFO info = {0};
|
||||||
|
info.cbSize = sizeof(MONITORINFO);
|
||||||
|
GetMonitorInfo(monitor.handle, &info);
|
||||||
|
|
||||||
|
monitor.screen = info.rcMonitor;
|
||||||
|
monitor.work = info.rcWork;
|
||||||
|
|
||||||
|
if (logging)
|
||||||
|
{
|
||||||
|
DebugLog(L" ScrArea : L=%i, T=%i, R=%i, B=%i (W=%i, H=%i)",
|
||||||
|
info.rcMonitor.left, info.rcMonitor.top, info.rcMonitor.right, info.rcMonitor.bottom,
|
||||||
|
info.rcMonitor.right - info.rcMonitor.left, info.rcMonitor.bottom - info.rcMonitor.top);
|
||||||
|
DebugLog(L" WorkArea : L=%i, T=%i, R=%i, B=%i (W=%i, H=%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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // monitor not found
|
||||||
|
{
|
||||||
|
c_Monitors.useEnumDisplayMonitors = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
monitor.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitors.push_back(monitor);
|
||||||
|
|
||||||
|
if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
|
||||||
|
{
|
||||||
|
// It's primary monitor!
|
||||||
|
c_Monitors.primary = (int)monitors.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (logging)
|
||||||
|
{
|
||||||
|
DebugLog(L" Adapter : %s", dd.DeviceString);
|
||||||
|
DebugLog(L" Flags : %s(0x%08X)", msg.c_str(), dd.StateFlags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dwDevice++;
|
||||||
|
} while (EnumDisplayDevices(NULL, dwDevice, &dd, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitors.empty()) // Failed to enumerate the non-mirroring monitors
|
||||||
|
{
|
||||||
|
DebugLog(L"Failed to enumerate the non-mirroring monitors. Only EnumDisplayMonitors is used instead.");
|
||||||
|
c_Monitors.useEnumDisplayDevices = false;
|
||||||
|
c_Monitors.useEnumDisplayMonitors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logging)
|
||||||
|
{
|
||||||
|
DebugLog(L"------------------------------");
|
||||||
|
DebugLog(L"* EnumDisplayMonitors API");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c_Monitors.useEnumDisplayMonitors)
|
||||||
|
{
|
||||||
|
EnumDisplayMonitors(NULL, NULL, MyInfoEnumProc, (LPARAM)(&c_Monitors));
|
||||||
|
|
||||||
|
if (monitors.empty()) // Failed to enumerate the monitors
|
||||||
|
{
|
||||||
|
DebugLog(L"Failed to enumerate the monitors. Prepares the dummy monitor information.");
|
||||||
|
c_Monitors.useEnumDisplayMonitors = false;
|
||||||
|
|
||||||
|
MONITOR_INFO monitor = {0};
|
||||||
|
wcscpy(monitor.deviceName, L"DUMMY");
|
||||||
|
POINT pos = {0, 0};
|
||||||
|
monitor.handle = MonitorFromPoint(pos, MONITOR_DEFAULTTOPRIMARY);
|
||||||
|
monitor.screen.left = 0;
|
||||||
|
monitor.screen.top = 0;
|
||||||
|
monitor.screen.right = GetSystemMetrics(SM_CXSCREEN);
|
||||||
|
monitor.screen.bottom = GetSystemMetrics(SM_CYSCREEN);
|
||||||
|
SystemParametersInfo(SPI_GETWORKAREA, 0, &(monitor.work), 0);
|
||||||
|
monitor.active = true;
|
||||||
|
|
||||||
|
monitors.push_back(monitor);
|
||||||
|
|
||||||
|
c_Monitors.primary = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (logging)
|
||||||
|
{
|
||||||
|
EnumDisplayMonitors(NULL, NULL, MyInfoEnumProc, (LPARAM)NULL); // Only logging
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logging)
|
||||||
|
{
|
||||||
|
DebugLog(L"------------------------------");
|
||||||
|
|
||||||
|
std::wstring method = L"* METHOD: ";
|
||||||
|
if (c_Monitors.useEnumDisplayDevices)
|
||||||
|
{
|
||||||
|
method += L"EnumDisplayDevices + ";
|
||||||
|
method += c_Monitors.useEnumDisplayMonitors ? L"EnumDisplayMonitors Mode" : L"EnumDisplaySettings Mode";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
method += c_Monitors.useEnumDisplayMonitors ? L"EnumDisplayMonitors Mode" : L"Dummy Mode";
|
||||||
|
}
|
||||||
|
DebugLog(method.c_str());
|
||||||
|
|
||||||
|
DebugLog(L"* MONITORS: Count=%i, Primary=@%i", monitors.size(), c_Monitors.primary);
|
||||||
|
DebugLog(L"@0: Virtual screen");
|
||||||
|
DebugLog(L" L=%i, T=%i, R=%i, B=%i (W=%i, H=%i)",
|
||||||
|
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; i < monitors.size(); i++)
|
||||||
|
{
|
||||||
|
if (monitors[i].active)
|
||||||
|
{
|
||||||
|
DebugLog(L"@%i: %s (active), MonitorName: %s", i + 1, monitors[i].deviceName, monitors[i].monitorName);
|
||||||
|
DebugLog(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);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugLog(L"@%i: %s (inactive), MonitorName: %s", i + 1, monitors[i].deviceName, monitors[i].monitorName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DebugLog(L"------------------------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* UpdateWorkareaInfo
|
||||||
|
**
|
||||||
|
** Updates the workarea information.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CSystem::UpdateWorkareaInfo()
|
||||||
|
{
|
||||||
|
std::vector<MONITOR_INFO>& monitors = c_Monitors.monitors;
|
||||||
|
|
||||||
|
if (monitors.empty())
|
||||||
|
{
|
||||||
|
SetMultiMonitorInfo();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < monitors.size(); i++)
|
||||||
|
{
|
||||||
|
if (monitors[i].active && monitors[i].handle != NULL)
|
||||||
|
{
|
||||||
|
MONITORINFO info = {0};
|
||||||
|
info.cbSize = sizeof(MONITORINFO);
|
||||||
|
GetMonitorInfo(monitors[i].handle, &info);
|
||||||
|
|
||||||
|
monitors[i].work = info.rcWork;
|
||||||
|
|
||||||
|
if (CRainmeter::GetDebug())
|
||||||
|
{
|
||||||
|
DebugLog(L"WorkArea @%i : L=%i, T=%i, R=%i, B=%i (W=%i, H=%i)",
|
||||||
|
i + 1,
|
||||||
|
info.rcWork.left, info.rcWork.top, info.rcWork.right, info.rcWork.bottom,
|
||||||
|
info.rcWork.right - info.rcWork.left, info.rcWork.bottom - info.rcWork.top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** GetShellDesktopWindow
|
||||||
|
**
|
||||||
|
** Finds the Shell's desktop window.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
HWND CSystem::GetShellDesktopWindow()
|
||||||
|
{
|
||||||
|
HWND DesktopW = NULL;
|
||||||
|
|
||||||
|
HWND hwnd = FindWindow(L"Progman", L"Program Manager");
|
||||||
|
if (!hwnd) return NULL; // Default Shell (Explorer) not started
|
||||||
|
|
||||||
|
if (!(hwnd = FindWindowEx(hwnd, NULL, L"SHELLDLL_DefView", L"")) ||
|
||||||
|
!(DesktopW = FindWindowEx(hwnd, NULL, L"SysListView32", L"FolderView"))) // for Windows 7 (with Aero)
|
||||||
|
{
|
||||||
|
HWND WorkerW = NULL;
|
||||||
|
while (WorkerW = FindWindowEx(NULL, WorkerW, L"WorkerW", L""))
|
||||||
|
{
|
||||||
|
if ((hwnd = FindWindowEx(WorkerW, NULL, L"SHELLDLL_DefView", L"")) &&
|
||||||
|
(DesktopW = FindWindowEx(hwnd, NULL, L"SysListView32", L"FolderView"))) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DesktopW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** GetWorkerW
|
||||||
|
**
|
||||||
|
** Finds the WorkerW window.
|
||||||
|
** If the Progman or WorkerW window is not found, this function returns NULL.
|
||||||
|
**
|
||||||
|
** In Windows Vista / 7 (without Aero):
|
||||||
|
** This function returns a topmost window handle which is visible.
|
||||||
|
**
|
||||||
|
** In Windows 7 (with Aero):
|
||||||
|
** This function returns a window handle which has the "SHELLDLL_DefView".
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
HWND CSystem::GetWorkerW()
|
||||||
|
{
|
||||||
|
HWND WorkerW = NULL;
|
||||||
|
|
||||||
|
HWND hwnd = FindWindow(L"Progman", L"Program Manager");
|
||||||
|
if (!hwnd) return NULL; // Default Shell (Explorer) not started
|
||||||
|
|
||||||
|
if ((hwnd = FindWindowEx(hwnd, NULL, L"SHELLDLL_DefView", L"")) &&
|
||||||
|
(hwnd = FindWindowEx(hwnd, NULL, L"SysListView32", L"FolderView"))) // for Windows Vista / 7 (without Aero)
|
||||||
|
{
|
||||||
|
while (WorkerW = FindWindowEx(NULL, WorkerW, L"WorkerW", L""))
|
||||||
|
{
|
||||||
|
if (IsWindowVisible(WorkerW))
|
||||||
|
{
|
||||||
|
// Check whether WorkerW covers whole of the screens
|
||||||
|
WINDOWPLACEMENT wp = {sizeof(WINDOWPLACEMENT)};
|
||||||
|
GetWindowPlacement(WorkerW, &wp);
|
||||||
|
|
||||||
|
if (wp.rcNormalPosition.left == c_Monitors.vsL &&
|
||||||
|
wp.rcNormalPosition.top == c_Monitors.vsT &&
|
||||||
|
(wp.rcNormalPosition.right - wp.rcNormalPosition.left) == c_Monitors.vsW &&
|
||||||
|
(wp.rcNormalPosition.bottom - wp.rcNormalPosition.top) == c_Monitors.vsH) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // for Windows 7 (with Aero)
|
||||||
|
{
|
||||||
|
while (WorkerW = FindWindowEx(NULL, WorkerW, L"WorkerW", L""))
|
||||||
|
{
|
||||||
|
if ((hwnd = FindWindowEx(WorkerW, NULL, L"SHELLDLL_DefView", L"")) &&
|
||||||
|
FindWindowEx(hwnd, NULL, L"SysListView32", L"FolderView")) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return WorkerW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** MyEnumWindowsProc
|
||||||
|
**
|
||||||
|
** Retrieves the Rainmeter meter window pinned on desktop in Z-order.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
BOOL CALLBACK MyEnumWindowsProc(HWND hwnd, LPARAM lParam)
|
||||||
|
{
|
||||||
|
bool logging = false; // Set true if you need verbose logging.
|
||||||
|
WCHAR className[128] = {0};
|
||||||
|
CMeterWindow* Window;
|
||||||
|
|
||||||
|
if (GetClassName(hwnd, className, 128) > 0 &&
|
||||||
|
wcscmp(className, L"RainmeterMeterWindow") == 0 &&
|
||||||
|
(Window = (CMeterWindow*)GetProp(hwnd, L"RAINMETER")))
|
||||||
|
{
|
||||||
|
if (Window->GetWindowZPosition() == ZPOSITION_ONDESKTOP)
|
||||||
|
{
|
||||||
|
if (logging) DebugLog(L"+ [%c] 0x%08X : %s (Name: \"%s\")", IsWindowVisible(hwnd) ? L'V' : L'H', hwnd, className, Window->GetSkinName().c_str());
|
||||||
|
|
||||||
|
if (lParam)
|
||||||
|
{
|
||||||
|
((std::vector<CMeterWindow*>*)lParam)->push_back(Window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (logging) DebugLog(L"- [%c] 0x%08X : %s (Name: \"%s\")", IsWindowVisible(hwnd) ? L'V' : L'H', hwnd, className, Window->GetSkinName().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (logging) DebugLog(L" [%c] 0x%08X : %s", IsWindowVisible(hwnd) ? L'V' : L'H', hwnd, className);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** ChangeZPosInOrder
|
||||||
|
**
|
||||||
|
** Arranges the meter window in Z-order.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
void CSystem::ChangeZPosInOrder()
|
||||||
|
{
|
||||||
|
if (Rainmeter)
|
||||||
|
{
|
||||||
|
bool logging = false; // Set true if you need verbose logging.
|
||||||
|
std::vector<CMeterWindow*> windowsInZOrder;
|
||||||
|
|
||||||
|
if (logging) LSLog(LOG_DEBUG, L"Rainmeter", L"1: -----");
|
||||||
|
|
||||||
|
// Retrieve the Rainmeter meter window in Z-order
|
||||||
|
if (logging) LSLog(LOG_DEBUG, L"Rainmeter", L" [Top-level window]");
|
||||||
|
EnumWindows(MyEnumWindowsProc, (LPARAM)(&windowsInZOrder));
|
||||||
|
|
||||||
|
HWND DesktopW = GetShellDesktopWindow();
|
||||||
|
if (DesktopW)
|
||||||
|
{
|
||||||
|
if (logging) LSLog(LOG_DEBUG, L"Rainmeter", L" [Child of Shell's desktop window]");
|
||||||
|
EnumChildWindows(DesktopW, MyEnumWindowsProc, (LPARAM)(&windowsInZOrder));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logging) LSLog(LOG_DEBUG, L"Rainmeter", L"2: -----");
|
||||||
|
|
||||||
|
// Reset ZPos in Z-order
|
||||||
|
for (size_t i = 0; i < windowsInZOrder.size(); i++)
|
||||||
|
{
|
||||||
|
windowsInZOrder[i]->ChangeZPos(ZPOSITION_ONDESKTOP); // reset
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logging)
|
||||||
|
{
|
||||||
|
LSLog(LOG_DEBUG, L"Rainmeter", L"3: -----");
|
||||||
|
LSLog(LOG_DEBUG, L"Rainmeter", L" [Top-level window]");
|
||||||
|
|
||||||
|
// Log all windows in Z-order
|
||||||
|
EnumWindows(MyEnumWindowsProc, (LPARAM)NULL);
|
||||||
|
|
||||||
|
if (DesktopW)
|
||||||
|
{
|
||||||
|
LSLog(LOG_DEBUG, L"Rainmeter", L" [Child of Shell's desktop window]");
|
||||||
|
EnumChildWindows(DesktopW, MyEnumWindowsProc, (LPARAM)NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** WndProc
|
||||||
|
**
|
||||||
|
** The window procedure
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
LRESULT CALLBACK CSystem::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
static int DesktopCompositionCheckCount = 0;
|
||||||
|
|
||||||
|
switch (uMsg)
|
||||||
|
{
|
||||||
|
case WM_WINDOWPOSCHANGING:
|
||||||
|
((LPWINDOWPOS)lParam)->flags |= SWP_NOZORDER;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_TIMER:
|
||||||
|
switch (wParam)
|
||||||
|
{
|
||||||
|
case TIMER_SHOWDESKTOP:
|
||||||
|
{
|
||||||
|
HWND WorkerW = GetWorkerW(), hwnd = NULL;
|
||||||
|
|
||||||
|
if (WorkerW)
|
||||||
|
{
|
||||||
|
hwnd = FindWindowEx(NULL, WorkerW, L"RainmeterSystemClass", L"");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((hwnd && !c_ShowDesktop) || (!hwnd && c_ShowDesktop))
|
||||||
|
{
|
||||||
|
c_ShowDesktop = !c_ShowDesktop;
|
||||||
|
|
||||||
|
if (CRainmeter::GetDebug())
|
||||||
|
{
|
||||||
|
DebugLog(L"System: %s",
|
||||||
|
c_ShowDesktop ? L"\"Show the desktop\" has been detected." : L"\"Show open windows\" has been detected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeZPosInOrder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case TIMER_COMPOSITION:
|
||||||
|
{
|
||||||
|
if (GetShellDesktopWindow() || DesktopCompositionCheckCount >= 10) // 250ms * 10 = 2.5s
|
||||||
|
{
|
||||||
|
KillTimer(c_Window, TIMER_COMPOSITION);
|
||||||
|
|
||||||
|
ChangeZPosInOrder();
|
||||||
|
|
||||||
|
if (c_DwmCompositionEnabled)
|
||||||
|
{
|
||||||
|
SetTimer(c_Window, TIMER_SHOWDESKTOP, INTERVAL_SHOWDESKTOP, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DesktopCompositionCheckCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_DWMCOMPOSITIONCHANGED:
|
||||||
|
DebugLog(L"System: DWM desktop composition has been changed.");
|
||||||
|
|
||||||
|
KillTimer(c_Window, TIMER_SHOWDESKTOP);
|
||||||
|
KillTimer(c_Window, TIMER_COMPOSITION);
|
||||||
|
|
||||||
|
c_DwmCompositionEnabled = (DwmIsCompositionEnabled() == TRUE);
|
||||||
|
|
||||||
|
DesktopCompositionCheckCount = 0;
|
||||||
|
SetTimer(c_Window, TIMER_COMPOSITION, INTERVAL_COMPOSITION, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_DISPLAYCHANGE:
|
||||||
|
DebugLog(L"System: Display setting has been changed.");
|
||||||
|
ClearMultiMonitorInfo();
|
||||||
|
CConfigParser::ClearMultiMonitorVariables();
|
||||||
|
case WM_SETTINGCHANGE:
|
||||||
|
if (uMsg == WM_DISPLAYCHANGE || (uMsg == WM_SETTINGCHANGE && wParam == SPI_SETWORKAREA))
|
||||||
|
{
|
||||||
|
if (uMsg == WM_SETTINGCHANGE) // SPI_SETWORKAREA
|
||||||
|
{
|
||||||
|
DebugLog(L"System: Work area has been changed.");
|
||||||
|
UpdateWorkareaInfo();
|
||||||
|
CConfigParser::UpdateWorkareaVariables();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Rainmeter)
|
||||||
|
{
|
||||||
|
// Deliver WM_DISPLAYCHANGE / WM_SETTINGCHANGE message to all meter windows
|
||||||
|
std::map<std::wstring, CMeterWindow*>& windows = Rainmeter->GetAllMeterWindows();
|
||||||
|
std::map<std::wstring, CMeterWindow*>::const_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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** DwmIsCompositionEnabled
|
||||||
|
**
|
||||||
|
** Returns TRUE if the DWM desktop composition is enabled.
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
BOOL CSystem::DwmIsCompositionEnabled()
|
||||||
|
{
|
||||||
|
BOOL fEnabled = FALSE;
|
||||||
|
|
||||||
|
typedef HRESULT (WINAPI * FPDWMISCOMPOSITIONENABLED)(BOOL* pfEnabled);
|
||||||
|
HINSTANCE h = LoadLibrary(L"dwmapi.dll");
|
||||||
|
if (h)
|
||||||
|
{
|
||||||
|
FPDWMISCOMPOSITIONENABLED DwmIsCompositionEnabled = (FPDWMISCOMPOSITIONENABLED)GetProcAddress(h, "DwmIsCompositionEnabled");
|
||||||
|
if (DwmIsCompositionEnabled)
|
||||||
|
{
|
||||||
|
if (DwmIsCompositionEnabled(&fEnabled) != S_OK)
|
||||||
|
{
|
||||||
|
fEnabled = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FreeLibrary(h);
|
||||||
|
}
|
||||||
|
return fEnabled;
|
||||||
|
}
|
80
Library/System.h
Normal file
80
Library/System.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2010 spx
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RAINMETER_SYSTEM_H__
|
||||||
|
#define __RAINMETER_SYSTEM_H__
|
||||||
|
|
||||||
|
#pragma warning(disable: 4786)
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
struct MONITOR_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 CSystem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void Initialize(HINSTANCE instance);
|
||||||
|
static void Finalize();
|
||||||
|
|
||||||
|
static const MULTIMONITOR_INFO& GetMultiMonitorInfo() { return c_Monitors; }
|
||||||
|
static size_t GetMonitorCount();
|
||||||
|
|
||||||
|
static bool GetDwmCompositionEnabled() { return c_DwmCompositionEnabled; }
|
||||||
|
static bool GetShowDesktop() { return c_ShowDesktop; }
|
||||||
|
|
||||||
|
static HWND GetShellDesktopWindow();
|
||||||
|
static HWND GetWorkerW();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
|
static BOOL DwmIsCompositionEnabled();
|
||||||
|
|
||||||
|
static void SetMultiMonitorInfo();
|
||||||
|
static void ClearMultiMonitorInfo() { c_Monitors.monitors.clear(); }
|
||||||
|
static void UpdateWorkareaInfo();
|
||||||
|
|
||||||
|
static void ChangeZPosInOrder();
|
||||||
|
|
||||||
|
static HWND c_Window;
|
||||||
|
|
||||||
|
static MULTIMONITOR_INFO c_Monitors; // Multi-Monitor info
|
||||||
|
|
||||||
|
static bool c_DwmCompositionEnabled;
|
||||||
|
static bool c_ShowDesktop;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -649,32 +649,6 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
|||||||
return strlen(Buffer);
|
return strlen(Buffer);
|
||||||
}
|
}
|
||||||
return 0;
|
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);
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
Loading…
Reference in New Issue
Block a user