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:
		| @@ -20,6 +20,7 @@ | ||||
| #include "ConfigParser.h" | ||||
| #include "Litestep.h" | ||||
| #include "Rainmeter.h" | ||||
| #include "System.h" | ||||
| #include <algorithm> | ||||
|  | ||||
| extern CRainmeter* Rainmeter; | ||||
| @@ -219,9 +220,9 @@ void CConfigParser::SetMultiMonitorVariables(bool reset) | ||||
| 		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; | ||||
|  | ||||
| 		for (size_t i = 0; i < monitors.size(); i++) | ||||
| @@ -290,12 +291,12 @@ void CConfigParser::SetAutoSelectedMonitorVariables(CMeterWindow* meterWindow) | ||||
|  | ||||
| 	if (meterWindow) | ||||
| 	{ | ||||
| 		if (CMeterWindow::GetMonitorCount() > 0) | ||||
| 		if (CSystem::GetMonitorCount() > 0) | ||||
| 		{ | ||||
| 			TCHAR buffer[256]; | ||||
| 			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; | ||||
|  | ||||
| 			if (meterWindow->GetXScreenDefined()) | ||||
|   | ||||
| @@ -54,11 +54,12 @@ public: | ||||
| 	std::wstring& GetFilename() { return m_Filename; } | ||||
| 	const std::vector<std::wstring>& GetSections(); | ||||
|  | ||||
|  | ||||
| 	// Returns an int if the formula was read successfully, -1 for failure. | ||||
| 	int ReadFormula(std::wstring& result, double* number); | ||||
|  | ||||
| 	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 UpdateWorkareaVariables() { SetMultiMonitorVariables(false); } | ||||
| @@ -68,9 +69,6 @@ private: | ||||
| 	void ReadVariables(); | ||||
| 	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 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); | ||||
|   | ||||
| @@ -2610,6 +2610,10 @@ | ||||
| 					/> | ||||
| 				</FileConfiguration> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath=".\System.cpp" | ||||
| 				> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="TrayWindow.cpp" | ||||
| 				> | ||||
| @@ -2877,6 +2881,10 @@ | ||||
| 				RelativePath=".\StdAfx.h" | ||||
| 				> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath=".\System.h" | ||||
| 				> | ||||
| 			</File> | ||||
| 			<File | ||||
| 				RelativePath="TrayWindow.h" | ||||
| 				> | ||||
|   | ||||
| @@ -682,6 +682,11 @@ void CMeasureNet::InitializeNewApi() | ||||
| 			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; | ||||
|  | ||||
| 	SetLastError(ERROR_SUCCESS); | ||||
| 	m_Plugin = LoadLibrary(m_PluginName.c_str()); | ||||
| 	 | ||||
| 	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 | ||||
| 		pos = m_PluginName.rfind(L'\\'); | ||||
| 		if (pos != std::wstring::npos)  | ||||
| 		{ | ||||
| 			std::wstring pluginName = Rainmeter->GetPath() + m_PluginName.substr(pos + 1); | ||||
|  | ||||
| 			SetLastError(ERROR_SUCCESS); | ||||
| 			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) | ||||
|   | ||||
| @@ -643,10 +643,11 @@ bool CMeterImage::Draw(Graphics& graphics) | ||||
| 			drawH = m_H; | ||||
| 		} | ||||
|  | ||||
| 		//if (m_AntiAlias && m_Rotate != 0.0f) | ||||
| 		//{ | ||||
| 		//	graphics.SetCompositingQuality(CompositingQualityHighQuality); | ||||
| 		//} | ||||
| 		if (!m_AntiAlias) | ||||
| 		{ | ||||
| 			//graphics.SetInterpolationMode(InterpolationModeNearestNeighbor); | ||||
| 			graphics.SetPixelOffsetMode(PixelOffsetModeHalf); | ||||
| 		} | ||||
|  | ||||
| 		Rect r(x, y, drawW, drawH); | ||||
| 		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 | ||||
| } | ||||
|  | ||||
| /* | ||||
| ** 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 | ||||
|   | ||||
| @@ -41,6 +41,7 @@ public: | ||||
| 	virtual void BindMeasure(std::list<CMeasure*>& measures); | ||||
|  | ||||
| 	static void FreeFontCache(); | ||||
| 	static void EnumerateInstalledFontFamilies(); | ||||
|  | ||||
| private: | ||||
| 	enum TEXTSTYLE | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -99,8 +99,12 @@ enum BANGCOMMAND | ||||
| 	BANG_SHOW, | ||||
| 	BANG_HIDE, | ||||
| 	BANG_TOGGLE, | ||||
| 	BANG_SHOWFADE, | ||||
| 	BANG_HIDEFADE, | ||||
| 	BANG_TOGGLEFADE, | ||||
| 	BANG_MOVE, | ||||
| 	BANG_ZPOS, | ||||
| 	BANG_SETTRANSPARENCY, | ||||
| 	BANG_LSHOOK, | ||||
| 	BANG_ABOUT, | ||||
| 	BANG_MOVEMETER, | ||||
| @@ -109,26 +113,6 @@ enum BANGCOMMAND | ||||
| 	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 CMeasure; | ||||
| class CMeter; | ||||
| @@ -200,11 +184,6 @@ 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); | ||||
|  | ||||
| @@ -255,8 +234,7 @@ private: | ||||
| 	void ShowWindowIfAppropriate(); | ||||
| 	bool DoAction(int x, int y, MOUSE mouse, bool test); | ||||
| 	bool ResizeWindow(bool reset); | ||||
|  | ||||
| 	static void SetMultiMonitorInfo(); | ||||
| 	void IgnoreAeroPeek(); | ||||
|  | ||||
| 	CConfigParser m_Parser; | ||||
|  | ||||
| @@ -360,8 +338,6 @@ private: | ||||
|  | ||||
| 	static int c_InstanceCount; | ||||
|  | ||||
| 	static MULTIMONITOR_INFO c_Monitors;		// Multi-Monitor info | ||||
|  | ||||
| 	Gdiplus::PrivateFontCollection* m_FontCollection; | ||||
|  | ||||
| 	bool m_MouseActionCursor; | ||||
|   | ||||
| @@ -18,6 +18,7 @@ | ||||
|  | ||||
| #include "StdAfx.h" | ||||
| #include "Rainmeter.h" | ||||
| #include "System.h" | ||||
| #include "Error.h" | ||||
| #include "AboutDialog.h" | ||||
| #include "MeasureNet.h" | ||||
| @@ -244,11 +245,55 @@ void BangWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs) | ||||
| 			else | ||||
| 			{ | ||||
| 				// 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(); | ||||
|  | ||||
| 				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); | ||||
| } | ||||
|  | ||||
| /* | ||||
| ** 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 | ||||
| ** | ||||
| @@ -511,6 +589,17 @@ void RainmeterZPos(HWND, const char* arg) | ||||
| 	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 | ||||
| ** | ||||
| @@ -662,6 +751,8 @@ CRainmeter::~CRainmeter() | ||||
|  | ||||
| 	CMeterString::FreeFontCache(); | ||||
|  | ||||
| 	CSystem::Finalize(); | ||||
|  | ||||
| 	GdiplusShutdown(m_GDIplusToken); | ||||
| } | ||||
|  | ||||
| @@ -865,6 +956,18 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath) | ||||
| 		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 | ||||
| 	m_TrayWindow = new CTrayWindow(m_Instance); | ||||
|  | ||||
| @@ -884,8 +987,6 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath) | ||||
| 		CheckUpdate(); | ||||
| 	} | ||||
|  | ||||
| 	CMeasureNet::InitializeNewApi(); | ||||
|  | ||||
| 	ResetStats(); | ||||
| 	ReadStats(); | ||||
|  | ||||
| @@ -915,6 +1016,9 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath) | ||||
| 		AddBangCommand("!RainmeterHide", RainmeterHide); | ||||
| 		AddBangCommand("!RainmeterShow", RainmeterShow); | ||||
| 		AddBangCommand("!RainmeterToggle", RainmeterToggle); | ||||
| 		AddBangCommand("!RainmeterHideFade", RainmeterHideFade); | ||||
| 		AddBangCommand("!RainmeterShowFade", RainmeterShowFade); | ||||
| 		AddBangCommand("!RainmeterToggleFade", RainmeterToggleFade); | ||||
| 		AddBangCommand("!RainmeterHideMeter", RainmeterHideMeter); | ||||
| 		AddBangCommand("!RainmeterShowMeter", RainmeterShowMeter); | ||||
| 		AddBangCommand("!RainmeterToggleMeter", RainmeterToggleMeter); | ||||
| @@ -926,6 +1030,7 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath) | ||||
| 		AddBangCommand("!RainmeterDeactivateConfig", RainmeterDeactivateConfig); | ||||
| 		AddBangCommand("!RainmeterMove", RainmeterMove); | ||||
| 		AddBangCommand("!RainmeterZPos", RainmeterZPos); | ||||
| 		AddBangCommand("!RainmeterSetTransparency", RainmeterSetTransparency); | ||||
| 		AddBangCommand("!RainmeterLsBoxHook", RainmeterLsHook); | ||||
| 		AddBangCommand("!RainmeterAbout", RainmeterAbout); | ||||
| 		AddBangCommand("!RainmeterResetStats", RainmeterResetStats); | ||||
| @@ -935,12 +1040,54 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath) | ||||
| 		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++) | ||||
| 	{ | ||||
| 		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) | ||||
| 	{ | ||||
| 		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 | ||||
| 	{ | ||||
| @@ -1344,6 +1492,9 @@ void CRainmeter::Quit(HINSTANCE dllInst) | ||||
| 		RemoveBangCommand("!RainmeterHide"); | ||||
| 		RemoveBangCommand("!RainmeterShow"); | ||||
| 		RemoveBangCommand("!RainmeterToggle"); | ||||
| 		RemoveBangCommand("!RainmeterHideFade"); | ||||
| 		RemoveBangCommand("!RainmeterShowFade"); | ||||
| 		RemoveBangCommand("!RainmeterToggleFade"); | ||||
| 		RemoveBangCommand("!RainmeterHideMeter"); | ||||
| 		RemoveBangCommand("!RainmeterShowMeter"); | ||||
| 		RemoveBangCommand("!RainmeterToggleMeter"); | ||||
| @@ -1355,6 +1506,7 @@ void CRainmeter::Quit(HINSTANCE dllInst) | ||||
| 		RemoveBangCommand("!RainmeterToggleConfig"); | ||||
| 		RemoveBangCommand("!RainmeterMove"); | ||||
| 		RemoveBangCommand("!RainmeterZPos"); | ||||
| 		RemoveBangCommand("!RainmeterSetTransparency"); | ||||
| 		RemoveBangCommand("!RainmeterLsBoxHook"); | ||||
| 		RemoveBangCommand("!RainmeterAbout"); | ||||
| 		RemoveBangCommand("!RainmeterResetStats"); | ||||
| @@ -1518,6 +1670,18 @@ BOOL CRainmeter::ExecuteBang(const std::wstring& bang, const std::wstring& arg, | ||||
| 	{ | ||||
| 		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) | ||||
| 	{ | ||||
| 		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); | ||||
| 	} | ||||
| 	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) | ||||
| 	{ | ||||
| 		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) | ||||
| { | ||||
| 	// Read Debug first | ||||
| 	c_Debug = 0!=GetPrivateProfileInt(L"Rainmeter", L"Debug", 0, iniFile.c_str()); | ||||
|  | ||||
| 	CConfigParser parser; | ||||
| 	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 | ||||
| ** otherwise all active meters are refreshed | ||||
| */ | ||||
| void CRainmeter::Refresh(const WCHAR* arg) | ||||
| { | ||||
| 	std::wstring config, iniFile; | ||||
|  | ||||
| 	try  | ||||
| 	{ | ||||
| 		if (arg != NULL && wcslen(arg) > 0)  | ||||
| 		{ | ||||
| 			std::wstring config = arg; | ||||
| 			CMeterWindow* meterWindow = GetMeterWindow(config); | ||||
| 			meterWindow->Refresh(false); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			std::map<std::wstring, CMeterWindow*>::iterator iter = m_Meters.begin(); | ||||
|  | ||||
| 			// Refresh all | ||||
| 			for (; iter != m_Meters.end(); iter++) | ||||
| 			{ | ||||
| 				(*iter).second->Refresh(false); | ||||
| 			} | ||||
| 		} | ||||
| 	}  | ||||
| 	catch(CError& error)  | ||||
| 	{ | ||||
| 		MessageBox(NULL, error.GetString().c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION); | ||||
| 	} | ||||
| } | ||||
| //void CRainmeter::Refresh(const WCHAR* arg) | ||||
| //{ | ||||
| //	std::wstring config, iniFile; | ||||
| // | ||||
| //	try  | ||||
| //	{ | ||||
| //		if (arg != NULL && wcslen(arg) > 0)  | ||||
| //		{ | ||||
| //			std::wstring config = arg; | ||||
| //			CMeterWindow* meterWindow = GetMeterWindow(config); | ||||
| //			meterWindow->Refresh(false); | ||||
| //		} | ||||
| //		else | ||||
| //		{ | ||||
| //			std::map<std::wstring, CMeterWindow*>::iterator iter = m_Meters.begin(); | ||||
| // | ||||
| //			// Refresh all | ||||
| //			for (; iter != m_Meters.end(); iter++) | ||||
| //			{ | ||||
| //				(*iter).second->Refresh(false); | ||||
| //			} | ||||
| //		} | ||||
| //	}  | ||||
| //	catch(CError& error)  | ||||
| //	{ | ||||
| //		MessageBox(NULL, error.GetString().c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION); | ||||
| //	} | ||||
| //} | ||||
|  | ||||
| /* | ||||
| ** ReadStats | ||||
| @@ -2313,11 +2478,11 @@ HMENU CRainmeter::CreateMonitorMenu(CMeterWindow* meterWindow) | ||||
| 	AppendMenu(monitorMenu, flags, ID_MONITOR_FIRST, L"@0: Virtual screen"); | ||||
|  | ||||
| 	// for the "Specified monitor" (@n) | ||||
| 	if (CMeterWindow::GetMonitorCount() > 0) | ||||
| 	if (CSystem::GetMonitorCount() > 0) | ||||
| 	{ | ||||
| 		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; | ||||
|  | ||||
| 		for (size_t i = 0; i < monitors.size(); i++) | ||||
|   | ||||
| @@ -175,7 +175,7 @@ private: | ||||
| 	void ScanForThemes(std::wstring& path); | ||||
| 	void ReadGeneralSettings(std::wstring& path); | ||||
| 	bool SetActiveConfig(std::wstring& skinName, std::wstring& skinIni); | ||||
| 	void Refresh(const WCHAR* arg); | ||||
| 	//void Refresh(const WCHAR* arg); | ||||
| 	HMENU CreateSkinMenu(CMeterWindow* meterWindow, int index); | ||||
| 	void ChangeSkinIndex(HMENU subMenu, int index); | ||||
| 	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 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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 spx
					spx