mirror of
				https://github.com/chibicitiberiu/rainmeter-studio.git
				synced 2024-02-24 04:33:31 +00:00 
			
		
		
		
	- Fixed a problem that !RainmeterQuit isn't executed when no meter window is running.
- Fixed a problem that StyleTemplate affects to Meters which have no relation. - Added a workaround to avoid the "IniFileMapping" function when reading skins. - Some small code cosmetics.
This commit is contained in:
		| @@ -78,8 +78,15 @@ void CConfigParser::Initialize(LPCTSTR filename, CRainmeter* pRainmeter, CMeterW | ||||
| 	// Set the SCREENAREA/WORKAREA variables for present monitor | ||||
| 	SetAutoSelectedMonitorVariables(meterWindow); | ||||
|  | ||||
| 	if (meterWindow) | ||||
| 	{ | ||||
| 		GetIniFileMappingList(); | ||||
| 	} | ||||
|  | ||||
| 	ReadIniFile(m_Filename); | ||||
| 	ReadVariables(); | ||||
|  | ||||
| 	m_IniFileMappings.clear(); | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -288,7 +295,6 @@ void CConfigParser::SetMonitorVariable(const std::wstring& strVariable, const st | ||||
| */ | ||||
| void CConfigParser::SetAutoSelectedMonitorVariables(CMeterWindow* meterWindow) | ||||
| { | ||||
|  | ||||
| 	if (meterWindow) | ||||
| 	{ | ||||
| 		if (CSystem::GetMonitorCount() > 0) | ||||
| @@ -798,17 +804,36 @@ Color CConfigParser::ParseColor(LPCTSTR string) | ||||
| */ | ||||
| void CConfigParser::ReadIniFile(const std::wstring& iniFile, int depth) | ||||
| { | ||||
| 	if (CRainmeter::GetDebug()) | ||||
| 	{ | ||||
| 		DebugLog(L"Reading file: %s", iniFile.c_str()); | ||||
| 	} | ||||
|  | ||||
| 	if (depth > 100)	// Is 100 enough to assume the include loop never ends? | ||||
| 	{ | ||||
| 		MessageBox(NULL, L"It looks like you've made an infinite\nloop with the @include statements.\nPlease check your skin.", L"Rainmeter", MB_OK | MB_ICONERROR); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	// Avoid "IniFileMapping" | ||||
| 	std::wstring iniRead = GetAlternateFileName(iniFile); | ||||
| 	bool alternate = false; | ||||
|  | ||||
| 	if (!iniRead.empty()) | ||||
| 	{ | ||||
| 		// Copy iniFile to temporary directory | ||||
| 		if (CRainmeter::CopyFiles(iniFile, iniRead)) | ||||
| 		{ | ||||
| 			if (CRainmeter::GetDebug()) DebugLog(L"Reading file: %s (Alternate: %s)", iniFile.c_str(), iniRead.c_str()); | ||||
| 			alternate = true; | ||||
| 		} | ||||
| 		else  // copy failed | ||||
| 		{ | ||||
| 			DeleteFile(iniRead.c_str()); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!alternate) | ||||
| 	{ | ||||
| 		if (CRainmeter::GetDebug()) DebugLog(L"Reading file: %s", iniFile.c_str()); | ||||
| 		iniRead = iniFile; | ||||
| 	} | ||||
|  | ||||
| 	// Get all the sections (i.e. different meters) | ||||
| 	WCHAR* items = new WCHAR[MAX_LINE_LENGTH]; | ||||
| 	int size = MAX_LINE_LENGTH; | ||||
| @@ -817,8 +842,13 @@ void CConfigParser::ReadIniFile(const std::wstring& iniFile, int depth) | ||||
| 	while(true) | ||||
| 	{ | ||||
| 		items[0] = 0; | ||||
| 		int res = GetPrivateProfileString( NULL, NULL, NULL, items, size, iniFile.c_str()); | ||||
| 		if (res == 0) { delete [] items; return; }		// File not found | ||||
| 		int res = GetPrivateProfileString( NULL, NULL, NULL, items, size, iniRead.c_str()); | ||||
| 		if (res == 0)		// File not found | ||||
| 		{ | ||||
| 			delete [] items; | ||||
| 			if (alternate) DeleteFile(iniRead.c_str()); | ||||
| 			return; | ||||
| 		} | ||||
| 		if (res < size - 2) break;		// Fits in the buffer | ||||
|  | ||||
| 		delete [] items; | ||||
| @@ -850,7 +880,7 @@ void CConfigParser::ReadIniFile(const std::wstring& iniFile, int depth) | ||||
| 		while(true) | ||||
| 		{ | ||||
| 			items[0] = 0; | ||||
| 			int res = GetPrivateProfileString((*iter).first.c_str(), NULL, NULL, items, size, iniFile.c_str()); | ||||
| 			int res = GetPrivateProfileString((*iter).first.c_str(), NULL, NULL, items, size, iniRead.c_str()); | ||||
| 			if (res < size - 2) break;		// Fits in the buffer | ||||
|  | ||||
| 			delete [] items; | ||||
| @@ -866,7 +896,7 @@ void CConfigParser::ReadIniFile(const std::wstring& iniFile, int depth) | ||||
| 			while(true) | ||||
| 			{ | ||||
| 				buffer[0] = 0; | ||||
| 				int res = GetPrivateProfileString((*iter).first.c_str(), strKey.c_str(), L"", buffer, bufferSize, iniFile.c_str()); | ||||
| 				int res = GetPrivateProfileString((*iter).first.c_str(), strKey.c_str(), L"", buffer, bufferSize, iniRead.c_str()); | ||||
| 				if (res < bufferSize - 2) break;		// Fits in the buffer | ||||
|  | ||||
| 				delete [] buffer; | ||||
| @@ -895,6 +925,7 @@ void CConfigParser::ReadIniFile(const std::wstring& iniFile, int depth) | ||||
| 	} | ||||
| 	delete [] buffer; | ||||
| 	delete [] items; | ||||
| 	if (alternate) DeleteFile(iniRead.c_str()); | ||||
| } | ||||
|  | ||||
| //============================================================================== | ||||
| @@ -978,3 +1009,82 @@ std::vector<std::wstring> CConfigParser::GetKeys(const std::wstring& strSection) | ||||
| 	return std::vector<std::wstring>(); | ||||
| } | ||||
|  | ||||
| void CConfigParser::GetIniFileMappingList() | ||||
| { | ||||
| 	HKEY hKey; | ||||
| 	LONG ret; | ||||
|  | ||||
| 	ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\IniFileMapping", 0, KEY_ENUMERATE_SUB_KEYS, &hKey); | ||||
| 	if (ret == ERROR_SUCCESS) | ||||
| 	{ | ||||
| 		WCHAR buffer[MAX_PATH]; | ||||
| 		DWORD index = 0, cch = MAX_PATH; | ||||
|  | ||||
| 		while (true) | ||||
| 		{ | ||||
| 			ret = RegEnumKeyEx(hKey, index++, buffer, &cch, NULL, NULL, NULL, NULL); | ||||
| 			if (ret == ERROR_NO_MORE_ITEMS) break; | ||||
|  | ||||
| 			if (ret == ERROR_SUCCESS) | ||||
| 			{ | ||||
| 				m_IniFileMappings.push_back(buffer); | ||||
| 			} | ||||
| 			cch = MAX_PATH; | ||||
| 		} | ||||
| 		RegCloseKey(hKey); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| std::wstring CConfigParser::GetAlternateFileName(const std::wstring &iniFile) | ||||
| { | ||||
| 	std::wstring alternate; | ||||
|  | ||||
| 	if (!m_IniFileMappings.empty()) | ||||
| 	{ | ||||
| 		std::wstring::size_type pos = iniFile.find_last_of(L'\\'); | ||||
| 		std::wstring filename; | ||||
|  | ||||
| 		if (pos != std::wstring::npos) | ||||
| 		{ | ||||
| 			filename = iniFile.substr(pos + 1); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			filename = iniFile; | ||||
| 		} | ||||
|  | ||||
| 		for (size_t i = 0; i < m_IniFileMappings.size(); ++i) | ||||
| 		{ | ||||
| 			if (wcsicmp(m_IniFileMappings[i].c_str(), filename.c_str()) == 0) | ||||
| 			{ | ||||
| 				WCHAR buffer[4096]; | ||||
|  | ||||
| 				GetTempPath(4096, buffer); | ||||
| 				alternate = buffer; | ||||
| 				if (GetTempFileName(alternate.c_str(), L"cfg", 0, buffer) != 0) | ||||
| 				{ | ||||
| 					alternate = buffer; | ||||
|  | ||||
| 					std::wstring tmp = GetAlternateFileName(alternate); | ||||
| 					if (tmp.empty()) | ||||
| 					{ | ||||
| 						return alternate; | ||||
| 					} | ||||
| 					else  // alternate is reserved | ||||
| 					{ | ||||
| 						DeleteFile(alternate.c_str()); | ||||
| 						return tmp; | ||||
| 					} | ||||
| 				} | ||||
| 				else  // failed | ||||
| 				{ | ||||
| 					DebugLog(L"Unable to create a temporary file to: %s", alternate.c_str()); | ||||
| 					alternate.clear(); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return alternate; | ||||
| } | ||||
|   | ||||
| @@ -41,6 +41,7 @@ public: | ||||
| 	void AddMeasure(CMeasure* pMeasure); | ||||
| 	void SetVariable(const std::wstring& strVariable, const std::wstring& strValue); | ||||
| 	void SetStyleTemplate(const std::wstring& strStyle) { m_StyleTemplate = strStyle; } | ||||
| 	void ResetStyleTemplate() { m_StyleTemplate.clear(); } | ||||
|  | ||||
| 	void ResetVariables(CRainmeter* pRainmeter, CMeterWindow* meterWindow = NULL); | ||||
|  | ||||
| @@ -76,6 +77,9 @@ private: | ||||
|  | ||||
| 	void SetAutoSelectedMonitorVariables(CMeterWindow* meterWindow); | ||||
|  | ||||
| 	void GetIniFileMappingList(); | ||||
| 	std::wstring GetAlternateFileName(const std::wstring& iniFile); | ||||
|  | ||||
| 	static void SetMultiMonitorVariables(bool reset); | ||||
| 	static void SetMonitorVariable(const std::wstring& strVariable, const std::wstring& strValue); | ||||
|  | ||||
| @@ -91,6 +95,8 @@ private: | ||||
| 	stdext::hash_map<std::wstring, std::vector<std::wstring> > m_Keys; | ||||
| 	stdext::hash_map<std::wstring, std::wstring> m_Values; | ||||
|  | ||||
| 	std::vector<std::wstring> m_IniFileMappings; | ||||
|  | ||||
| 	static std::map<std::wstring, std::wstring> c_MonitorVariables; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -148,9 +148,9 @@ void CMeasureCalc::RandomFormulaReplace() | ||||
| 	//To implement random numbers the word "Random" in the string | ||||
| 	//formula is being replaced by the random number value | ||||
| 	m_Formula = m_FormulaHolder; | ||||
| 	int loc = m_Formula.find(L"Random"); | ||||
| 	std::wstring::size_type loc = m_Formula.find(L"Random"); | ||||
|  | ||||
| 	while(loc > -1) | ||||
| 	while(loc != std::wstring::npos) | ||||
| 	{ | ||||
| 		int range = (m_HighBound - m_LowBound);  | ||||
| 		srand((unsigned) rand());  | ||||
|   | ||||
| @@ -786,11 +786,6 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const WCHAR* arg) | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 	case BANG_QUIT: | ||||
| 		// Quit needs to be delayed since it crashes if done during Update() | ||||
| 		PostMessage(m_Window, WM_DELAYED_QUIT, (WPARAM)NULL, (LPARAM)NULL); | ||||
| 		break; | ||||
|  | ||||
| 	case BANG_SETVARIABLE: | ||||
| 		pos = wcschr(arg, ' '); | ||||
| 		if (pos != NULL) | ||||
| @@ -1751,6 +1746,8 @@ void CMeterWindow::ReadSkin() | ||||
|  | ||||
| 						meter->ReadConfig(strSection.c_str()); | ||||
| 						m_Meters.push_back(meter); | ||||
|  | ||||
| 						m_Parser.ResetStyleTemplate(); | ||||
| 					} | ||||
| 				} | ||||
| 				catch (CError& error) | ||||
| @@ -2171,6 +2168,7 @@ void CMeterWindow::Update(bool nodraw) | ||||
| 			if ((*j)->HasDynamicVariables()) | ||||
| 			{ | ||||
| 				(*j)->ReadConfig((*j)->GetName()); | ||||
| 				m_Parser.ResetStyleTemplate(); | ||||
| 			} | ||||
| 			(*j)->Update(); | ||||
| 		} | ||||
| @@ -3871,7 +3869,6 @@ LRESULT CALLBACK CMeterWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPAR | ||||
| 	MESSAGE(OnDelayedExecute, WM_DELAYED_EXECUTE) | ||||
| 	MESSAGE(OnDelayedRefresh, WM_DELAYED_REFRESH) | ||||
| 	MESSAGE(OnDelayedMove, WM_DELAYED_MOVE) | ||||
| 	MESSAGE(OnDelayedQuit, WM_DELAYED_QUIT) | ||||
| 	MESSAGE(OnSettingChange, WM_SETTINGCHANGE) | ||||
| 	MESSAGE(OnDisplayChange, WM_DISPLAYCHANGE) | ||||
| 	END_MESSAGEPROC | ||||
| @@ -3949,19 +3946,6 @@ LRESULT CMeterWindow::OnDelayedMove(WPARAM wParam, LPARAM lParam) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
| ** OnDelayedQuit | ||||
| ** | ||||
| ** Handles delayed quit | ||||
| ** | ||||
| */ | ||||
| LRESULT CMeterWindow::OnDelayedQuit(WPARAM wParam, LPARAM lParam) | ||||
| { | ||||
| 	if (Rainmeter->GetDummyLitestep()) PostQuitMessage(0); | ||||
| 	quitModule(Rainmeter->GetInstance()); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* | ||||
| ** OnCopyData | ||||
| ** | ||||
|   | ||||
| @@ -36,7 +36,6 @@ | ||||
|  | ||||
| #define WM_DELAYED_EXECUTE WM_APP + 0 | ||||
| #define WM_DELAYED_REFRESH WM_APP + 1 | ||||
| #define WM_DELAYED_QUIT    WM_APP + 2 | ||||
| #define WM_DELAYED_MOVE    WM_APP + 3 | ||||
|  | ||||
| enum MOUSE | ||||
| @@ -109,7 +108,6 @@ enum BANGCOMMAND | ||||
| 	BANG_ABOUT, | ||||
| 	BANG_MOVEMETER, | ||||
| 	BANG_PLUGIN, | ||||
| 	BANG_QUIT, | ||||
| 	BANG_SETVARIABLE | ||||
| }; | ||||
|  | ||||
| @@ -213,7 +211,6 @@ protected: | ||||
| 	LRESULT OnDelayedExecute(WPARAM wParam, LPARAM lParam); | ||||
| 	LRESULT OnDelayedRefresh(WPARAM wParam, LPARAM lParam); | ||||
| 	LRESULT OnDelayedMove(WPARAM wParam, LPARAM lParam); | ||||
| 	LRESULT OnDelayedQuit(WPARAM wParam, LPARAM lParam); | ||||
| 	LRESULT OnSettingChange(WPARAM wParam, LPARAM lParam);   | ||||
| 	LRESULT OnDisplayChange(WPARAM wParam, LPARAM lParam);   | ||||
|  | ||||
|   | ||||
| @@ -637,7 +637,11 @@ void RainmeterPluginBang(HWND, const char* arg) | ||||
| */ | ||||
| void RainmeterQuit(HWND, const char* arg) | ||||
| { | ||||
| 	BangWithArgs(BANG_QUIT, ConvertToWide(arg).c_str(), 0); | ||||
| 	if (Rainmeter) | ||||
| 	{ | ||||
| 		// Quit needs to be delayed since it crashes if done during Update() | ||||
| 		PostMessage(Rainmeter->GetTrayWindow()->GetWindow(), WM_DELAYED_QUIT, (WPARAM)NULL, (LPARAM)NULL); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* | ||||
| @@ -1190,18 +1194,20 @@ int CRainmeter::CompareVersions(std::wstring strA, std::wstring strB) | ||||
| ** Copies files and folders from one location to another. | ||||
| ** | ||||
| */ | ||||
| bool CRainmeter::CopyFiles(std::wstring strFrom, std::wstring strTo, bool bMove) | ||||
| bool CRainmeter::CopyFiles(const std::wstring& strFrom, const std::wstring& strTo, bool bMove) | ||||
| { | ||||
| 	std::wstring tmpFrom(strFrom), tmpTo(strTo); | ||||
|  | ||||
| 	// The strings must end with double nul | ||||
| 	strFrom.append(L"0"); | ||||
| 	strFrom[strFrom.size() - 1] = L'\0'; | ||||
| 	strTo.append(L"0"); | ||||
| 	strTo[strTo.size() - 1] = L'\0'; | ||||
| 	tmpFrom.append(L"0"); | ||||
| 	tmpFrom[tmpFrom.size() - 1] = L'\0'; | ||||
| 	tmpTo.append(L"0"); | ||||
| 	tmpTo[tmpTo.size() - 1] = L'\0'; | ||||
|  | ||||
| 	SHFILEOPSTRUCT fo = {0}; | ||||
| 	fo.wFunc = bMove ? FO_MOVE : FO_COPY; | ||||
| 	fo.pFrom = strFrom.c_str(); | ||||
| 	fo.pTo = strTo.c_str(); | ||||
| 	fo.pFrom = tmpFrom.c_str(); | ||||
| 	fo.pTo = tmpTo.c_str(); | ||||
| 	fo.fFlags = FOF_NO_UI | FOF_NOCONFIRMATION | FOF_ALLOWUNDO; | ||||
|  | ||||
| 	int result = SHFileOperation(&fo); | ||||
| @@ -1774,7 +1780,8 @@ BOOL CRainmeter::ExecuteBang(const std::wstring& bang, const std::wstring& arg, | ||||
| 	} | ||||
| 	else if (wcsicmp(bang.c_str(), L"!RainmeterQuit") == 0) | ||||
| 	{ | ||||
| 		BangWithArgs(BANG_QUIT, arg.c_str(), 0); | ||||
| 		// Quit needs to be delayed since it crashes if done during Update() | ||||
| 		PostMessage(m_TrayWindow->GetWindow(), WM_DELAYED_QUIT, (WPARAM)NULL, (LPARAM)NULL); | ||||
| 	} | ||||
| 	else if (wcsicmp(bang.c_str(), L"!Execute") == 0) | ||||
| 	{ | ||||
|   | ||||
| @@ -179,6 +179,7 @@ public: | ||||
| 	static PLATFORM IsNT(); | ||||
| 	static std::wstring ExtractPath(const std::wstring& strFilePath); | ||||
| 	static void ExpandEnvironmentVariables(std::wstring& strPath); | ||||
| 	static bool CopyFiles(const std::wstring& strFrom, const std::wstring& strTo, bool bMove = false); | ||||
|  | ||||
| private: | ||||
| 	void CreateMeterWindow(std::wstring path, std::wstring config, std::wstring iniFile); | ||||
| @@ -197,7 +198,6 @@ private: | ||||
| 	HMENU CreateMonitorMenu(CMeterWindow* meterWindow); | ||||
| 	void CreateDefaultConfigFile(std::wstring strFile); | ||||
| 	void TestSettingsFile(bool bDefaultIniLocation); | ||||
| 	bool CopyFiles(std::wstring strFrom, std::wstring strTo, bool bMove = false); | ||||
| 	void CheckSkinVersions(); | ||||
| 	int CompareVersions(std::wstring strA, std::wstring strB); | ||||
|  | ||||
|   | ||||
| @@ -631,6 +631,14 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA | ||||
| 		} | ||||
| 		return 0; | ||||
|  | ||||
| 	case WM_DELAYED_QUIT: | ||||
| 		if (Rainmeter) | ||||
| 		{ | ||||
| 			if (Rainmeter->GetDummyLitestep()) PostQuitMessage(0); | ||||
| 			quitModule(Rainmeter->GetInstance()); | ||||
| 		} | ||||
| 		return 0; | ||||
|  | ||||
| 	case WM_DESTROY: | ||||
| 		if (Rainmeter->GetDummyLitestep()) PostQuitMessage(0); | ||||
| 		break; | ||||
|   | ||||
| @@ -25,6 +25,7 @@ | ||||
| #include "Measure.h" | ||||
|  | ||||
| #define WM_DELAYED_REFRESH_ALL WM_APP + 0 | ||||
| #define WM_DELAYED_QUIT        WM_APP + 1 | ||||
|  | ||||
| #define WM_NOTIFYICON WM_USER + 101 | ||||
| #define TRAYICON_SIZE 16 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 spx
					spx