mirror of
				https://github.com/chibicitiberiu/rainmeter-studio.git
				synced 2024-02-24 04:33:31 +00:00 
			
		
		
		
	- Modified the way to handle the "On Desktop". This affects all of Windows versions.
- Added "LoadOrder" to handle the skins' loading order. - Changed the way to update and save the network statistics.
This commit is contained in:
		| @@ -93,6 +93,7 @@ CMeterWindow::CMeterWindow(std::wstring& path, std::wstring& config, std::wstrin | |||||||
| 	m_WindowUpdate = 1000; | 	m_WindowUpdate = 1000; | ||||||
| 	m_TransitionUpdate = 100; | 	m_TransitionUpdate = 100; | ||||||
| 	m_ActiveTransition = false; | 	m_ActiveTransition = false; | ||||||
|  | 	m_HasNetMeasures = false; | ||||||
| 	m_WindowHide = HIDEMODE_NONE; | 	m_WindowHide = HIDEMODE_NONE; | ||||||
| 	m_WindowStartHidden = false; | 	m_WindowStartHidden = false; | ||||||
| 	m_SnapEdges = true; | 	m_SnapEdges = true; | ||||||
| @@ -294,7 +295,7 @@ void CMeterWindow::IgnoreAeroPeek() | |||||||
| ** This deletes everything and rebuilds the config again. | ** This deletes everything and rebuilds the config again. | ||||||
| ** | ** | ||||||
| */ | */ | ||||||
| void CMeterWindow::Refresh(bool init) | void CMeterWindow::Refresh(bool init, bool all) | ||||||
| { | { | ||||||
| 	assert(m_Rainmeter != NULL); | 	assert(m_Rainmeter != NULL); | ||||||
|  |  | ||||||
| @@ -316,13 +317,6 @@ void CMeterWindow::Refresh(bool init) | |||||||
| 		KillTimer(m_Window, MOUSETIMER);	// Kill the timer | 		KillTimer(m_Window, MOUSETIMER);	// Kill the timer | ||||||
| 		KillTimer(m_Window, FADETIMER);	// Kill the timer | 		KillTimer(m_Window, FADETIMER);	// Kill the timer | ||||||
|  |  | ||||||
| 		if (!m_ChildWindow && GetAncestor(m_Window, GA_PARENT) != GetDesktopWindow()) |  | ||||||
| 		{ |  | ||||||
| 			// Reset to the top-level window |  | ||||||
| 			m_PreventMoving = true;  // Prevent moving the window by SetParent |  | ||||||
| 			SetParent(m_Window, NULL); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		std::list<CMeasure*>::iterator i = m_Measures.begin(); | 		std::list<CMeasure*>::iterator i = m_Measures.begin(); | ||||||
| 		for( ; i != m_Measures.end(); i++) | 		for( ; i != m_Measures.end(); i++) | ||||||
| 		{ | 		{ | ||||||
| @@ -348,6 +342,8 @@ void CMeterWindow::Refresh(bool init) | |||||||
| 		m_FontCollection = NULL; | 		m_FontCollection = NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	ZPOSITION oldZPos = m_WindowZPosition; | ||||||
|  |  | ||||||
| 	//TODO: Should these be moved to a Reload command instead of hitting the disk on every refresh | 	//TODO: Should these be moved to a Reload command instead of hitting the disk on every refresh | ||||||
| 	ReadConfig();	// Read the general settings  | 	ReadConfig();	// Read the general settings  | ||||||
| 	ReadSkin(); | 	ReadSkin(); | ||||||
| @@ -373,10 +369,7 @@ void CMeterWindow::Refresh(bool init) | |||||||
| 		MapCoordsToScreen(m_ScreenX, m_ScreenY, m_WindowW, m_WindowH); | 		MapCoordsToScreen(m_ScreenX, m_ScreenY, m_WindowW, m_WindowH); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ZPOSITION zPos = m_WindowZPosition; | 	SetWindowPos(m_Window, NULL, m_ScreenX, m_ScreenY, m_WindowW, m_WindowH, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||||
| 	m_WindowZPosition = ZPOSITION_NORMAL;  // Handles as the normal window temporarily |  | ||||||
| 	SetWindowPos(m_Window, NULL, m_ScreenX, m_ScreenY, m_WindowW, m_WindowH, SWP_NOZORDER | SWP_NOACTIVATE); |  | ||||||
| 	m_WindowZPosition = zPos; |  | ||||||
|  |  | ||||||
| 	ScreenToWindow(); | 	ScreenToWindow(); | ||||||
|  |  | ||||||
| @@ -393,7 +386,10 @@ void CMeterWindow::Refresh(bool init) | |||||||
|  |  | ||||||
| 	UpdateTransparency(m_AlphaValue, true); | 	UpdateTransparency(m_AlphaValue, true); | ||||||
|  |  | ||||||
| 	ChangeZPos(m_WindowZPosition); | 	if (init || all || oldZPos != m_WindowZPosition) | ||||||
|  | 	{ | ||||||
|  | 		ChangeZPos(m_WindowZPosition, init || all); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	m_Rainmeter->SetCurrentParser(NULL); | 	m_Rainmeter->SetCurrentParser(NULL); | ||||||
|  |  | ||||||
| @@ -474,17 +470,6 @@ void CMeterWindow::MapCoordsToScreen(int& x, int& y, int w, int h) | |||||||
| */ | */ | ||||||
| void CMeterWindow::MoveWindow(int x, int y) | void CMeterWindow::MoveWindow(int x, int y) | ||||||
| { | { | ||||||
| 	// Convert the screen coordinates to the client coordinates of the shell window |  | ||||||
| 	if (!m_ChildWindow && m_WindowZPosition == ZPOSITION_ONDESKTOP && GetAncestor(m_Window, GA_PARENT) != GetDesktopWindow()) |  | ||||||
| 	{ |  | ||||||
| 		POINT pos = {x, y}; |  | ||||||
| 		if (ScreenToClient(GetAncestor(m_Window, GA_PARENT), &pos)) |  | ||||||
| 		{ |  | ||||||
| 			x = pos.x; |  | ||||||
| 			y = pos.y; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	SetWindowPos(m_Window, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); | 	SetWindowPos(m_Window, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE); | ||||||
|  |  | ||||||
| 	ScreenToWindow(); | 	ScreenToWindow(); | ||||||
| @@ -501,7 +486,7 @@ void CMeterWindow::MoveWindow(int x, int y) | |||||||
| ** Sets the window's z-position | ** Sets the window's z-position | ||||||
| ** | ** | ||||||
| */ | */ | ||||||
| void CMeterWindow::ChangeZPos(ZPOSITION zPos) | void CMeterWindow::ChangeZPos(ZPOSITION zPos, bool all) | ||||||
| { | { | ||||||
| 	if(!m_ChildWindow) | 	if(!m_ChildWindow) | ||||||
| 	{ | 	{ | ||||||
| @@ -517,104 +502,60 @@ void CMeterWindow::ChangeZPos(ZPOSITION zPos) | |||||||
|  			break; |  			break; | ||||||
|  |  | ||||||
| 		case ZPOSITION_ONBOTTOM: | 		case ZPOSITION_ONBOTTOM: | ||||||
| 			 winPos = HWND_BOTTOM; | 			if (all) | ||||||
| 			 break; |  | ||||||
|  |  | ||||||
| 		case ZPOSITION_ONDESKTOP: |  | ||||||
| 			if (!m_NativeTransparency || !CSystem::GetDwmCompositionEnabled()) |  | ||||||
| 			{ | 			{ | ||||||
| 				winPos = HWND_BOTTOM; | 				if (CSystem::GetShowDesktop()) | ||||||
|  |  | ||||||
| 				// Set the window's parent to progman, so it stays always on desktop |  | ||||||
| 				HWND ProgmanHwnd = CSystem::GetShellDesktopWindow(); |  | ||||||
|  |  | ||||||
| 				if (ProgmanHwnd && (parent != ProgmanHwnd)) |  | ||||||
| 				{ | 				{ | ||||||
| 					m_PreventMoving = true;  // Prevent moving the window by SetParent | 					// Insert after the tray window temporarily to keep order | ||||||
| 					SetParent(m_Window, ProgmanHwnd); | 					winPos = Rainmeter->GetTrayWindow()->GetWindow(); | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
|  | 				{ | ||||||
|  | 					// Insert after the helper window | ||||||
|  | 					winPos = CSystem::GetHelperWindow(); | ||||||
| 				} | 				} | ||||||
| 				//else |  | ||||||
| 				//{ |  | ||||||
| 				//	return;		// The window is already on desktop |  | ||||||
| 				//} |  | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				if (parent != GetDesktopWindow()) | 				winPos = HWND_BOTTOM; | ||||||
| 				{ | 			} | ||||||
| 					m_PreventMoving = true;  // Prevent moving the window by SetParent | 			break; | ||||||
| 					SetParent(m_Window, NULL); |  | ||||||
|  |  | ||||||
| 					IgnoreAeroPeek(); | 		case ZPOSITION_ONDESKTOP: | ||||||
|  | 			if (CSystem::GetShowDesktop()) | ||||||
|  | 			{ | ||||||
|  | 				// Set WS_EX_TOPMOST flag | ||||||
|  | 				SetWindowPos(m_Window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||||
|  |  | ||||||
|  | 				if (all) | ||||||
|  | 				{ | ||||||
|  | 					// Insert after the helper window | ||||||
|  | 					SetWindowPos(m_Window, CSystem::GetHelperWindow(), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||||
| 				} | 				} | ||||||
|  | 				else | ||||||
| 				if (CSystem::GetShowDesktop()) |  | ||||||
| 				{ | 				{ | ||||||
| 					bool logging = false;  // Set true if you need verbose logging. |  | ||||||
| 					std::wstring msg; |  | ||||||
|  |  | ||||||
| 					if (logging)  |  | ||||||
| 					{ |  | ||||||
| 						msg += (GetWindowLong(m_Window, GWL_EXSTYLE) & WS_EX_TOPMOST) ? L"TOPMOST" : L"NORMAL"; |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					// Set WS_EX_TOPMOST flag |  | ||||||
| 					SetWindowPos(m_Window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING); |  | ||||||
|  |  | ||||||
| 					if (logging) |  | ||||||
| 					{ |  | ||||||
| 						msg += L" - "; |  | ||||||
| 						msg += (GetWindowLong(m_Window, GWL_EXSTYLE) & WS_EX_TOPMOST) ? L"TOPMOST" : L"NORMAL"; |  | ||||||
| 					} |  | ||||||
|  |  | ||||||
| 					// Get WorkerW window |  | ||||||
| 					HWND WorkerW = CSystem::GetWorkerW(); |  | ||||||
|  |  | ||||||
| 					// Find the "backmost" topmost window | 					// Find the "backmost" topmost window | ||||||
| 					if (WorkerW) | 					HWND hwnd = CSystem::GetHelperWindow(); | ||||||
|  | 					while (hwnd = ::GetNextWindow(hwnd, GW_HWNDPREV)) | ||||||
| 					{ | 					{ | ||||||
| 						HWND hwnd = WorkerW; | 						if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) | ||||||
| 						while (hwnd = ::GetNextWindow(hwnd, GW_HWNDPREV)) |  | ||||||
| 						{ | 						{ | ||||||
| 							if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) | 							// Insert after the found window | ||||||
|  | 							if (0 != SetWindowPos(m_Window, hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING)) | ||||||
| 							{ | 							{ | ||||||
| 								WCHAR className[128], windowText[128]; | 								break; | ||||||
|  |  | ||||||
| 								if (logging) |  | ||||||
| 								{ |  | ||||||
| 									GetClassName(hwnd, className, 128); |  | ||||||
| 									GetWindowText(hwnd, windowText, 128); |  | ||||||
| 								} |  | ||||||
|  |  | ||||||
| 								if (0 == SetWindowPos(m_Window, hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING)) |  | ||||||
| 								{ |  | ||||||
| 									if (logging) |  | ||||||
| 									{ |  | ||||||
| 										DebugLog(L" %s: hwnd=0x%08X (WorkerW=0x%08X), hwndInsertAfter=0x%08X (\"%s\" %s) - FAILED", |  | ||||||
| 											m_SkinName.c_str(), m_Window, WorkerW, hwnd, windowText, className); |  | ||||||
| 									} |  | ||||||
| 									continue; |  | ||||||
| 								} |  | ||||||
|  |  | ||||||
| 								if (logging) |  | ||||||
| 								{ |  | ||||||
| 									msg += L" - "; |  | ||||||
| 									msg += (GetWindowLong(m_Window, GWL_EXSTYLE) & WS_EX_TOPMOST) ? L"TOPMOST" : L"NORMAL"; |  | ||||||
|  |  | ||||||
| 									DebugLog(L" %s: hwnd=0x%08X (WorkerW=0x%08X), hwndInsertAfter=0x%08X (\"%s\" %s) - %s", |  | ||||||
| 										m_SkinName.c_str(), m_Window, WorkerW, hwnd, windowText, className, msg.c_str()); |  | ||||||
| 								} |  | ||||||
| 								return; |  | ||||||
| 							} | 							} | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  | 				} | ||||||
| 					if (logging) | 				return; | ||||||
| 					{ | 			} | ||||||
| 						DebugLog(L" %s: hwnd=0x%08X (WorkerW=0x%08X), hwndInsertAfter=HWND_TOPMOST - %s", | 			else | ||||||
| 							m_SkinName.c_str(), m_Window, WorkerW, msg.c_str()); | 			{ | ||||||
| 					} | 				if (all) | ||||||
| 					return; | 				{ | ||||||
|  | 					// Insert after the helper window | ||||||
|  | 					winPos = CSystem::GetHelperWindow(); | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| @@ -624,18 +565,7 @@ void CMeterWindow::ChangeZPos(ZPOSITION zPos) | |||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (zPos != ZPOSITION_ONDESKTOP && (parent != GetDesktopWindow())) | 		SetWindowPos(m_Window, winPos, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||||
| 		{ |  | ||||||
| 			m_PreventMoving = true;  // Prevent moving the window by SetParent |  | ||||||
| 			SetParent(m_Window, NULL); |  | ||||||
|  |  | ||||||
| 			IgnoreAeroPeek(); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		bool refresh = m_Refreshing; |  | ||||||
| 		m_Refreshing = true;	// Fake refreshing so that the z-position can be changed |  | ||||||
| 		SetWindowPos(m_Window, winPos, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); |  | ||||||
| 		m_Refreshing = refresh; |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1762,6 +1692,8 @@ void CMeterWindow::ReadSkin() | |||||||
|  |  | ||||||
| 	// Create the meters and measures | 	// Create the meters and measures | ||||||
|  |  | ||||||
|  | 	m_HasNetMeasures = false; | ||||||
|  |  | ||||||
| 	// Get all the sections (i.e. different meters, measures and the other stuff) | 	// Get all the sections (i.e. different meters, measures and the other stuff) | ||||||
| 	std::vector<std::wstring> arraySections = m_Parser.GetSections(); | 	std::vector<std::wstring> arraySections = m_Parser.GetSections(); | ||||||
|  |  | ||||||
| @@ -1791,6 +1723,11 @@ void CMeterWindow::ReadSkin() | |||||||
| 						m_Measures.push_back(measure); | 						m_Measures.push_back(measure); | ||||||
|  |  | ||||||
| 						m_Parser.AddMeasure(measure); | 						m_Parser.AddMeasure(measure); | ||||||
|  |  | ||||||
|  | 						if (!m_HasNetMeasures && dynamic_cast<CMeasureNet*>((measure))) | ||||||
|  | 						{ | ||||||
|  | 							m_HasNetMeasures = true; | ||||||
|  | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				catch (CError& error) | 				catch (CError& error) | ||||||
| @@ -2204,7 +2141,7 @@ void CMeterWindow::Update(bool nodraw) | |||||||
| 	m_UpdateCounter++; | 	m_UpdateCounter++; | ||||||
|  |  | ||||||
| 	// Pre-updates | 	// Pre-updates | ||||||
| 	CMeasureNet::UpdateIFTable(); | 	if (m_HasNetMeasures) CMeasureNet::UpdateIFTable(); | ||||||
| 	CMeasureCalc::UpdateVariableMap(*this); | 	CMeasureCalc::UpdateVariableMap(*this); | ||||||
|  |  | ||||||
| 	// Update all measures | 	// Update all measures | ||||||
| @@ -2244,10 +2181,6 @@ void CMeterWindow::Update(bool nodraw) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Statistics |  | ||||||
| 	CMeasureNet::UpdateStats(); |  | ||||||
| 	Rainmeter->WriteStats(false); |  | ||||||
|  |  | ||||||
| 	if (!nodraw) | 	if (!nodraw) | ||||||
| 	{ | 	{ | ||||||
| 		if (m_DynamicWindowSize) | 		if (m_DynamicWindowSize) | ||||||
| @@ -3154,17 +3087,6 @@ LRESULT CMeterWindow::OnWindowPosChanging(WPARAM wParam, LPARAM lParam) | |||||||
| 			return DefWindowProc(m_Window, m_Message, wParam, lParam); | 			return DefWindowProc(m_Window, m_Message, wParam, lParam); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Convert the client coordinates of the shell window to the screen coordinates |  | ||||||
| 		if (!m_ChildWindow && m_WindowZPosition == ZPOSITION_ONDESKTOP && (m_Dragging || !m_NativeTransparency) && GetAncestor(m_Window, GA_PARENT) != GetDesktopWindow()) |  | ||||||
| 		{ |  | ||||||
| 			POINT pos = {wp->x, wp->y}; |  | ||||||
| 			if (ClientToScreen(GetAncestor(m_Window, GA_PARENT), &pos)) |  | ||||||
| 			{ |  | ||||||
| 				wp->x = pos.x; |  | ||||||
| 				wp->y = pos.y; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		if (m_SnapEdges && !(GetKeyState(VK_CONTROL) & 0x8000 || GetKeyState(VK_SHIFT) & 0x8000)) | 		if (m_SnapEdges && !(GetKeyState(VK_CONTROL) & 0x8000 || GetKeyState(VK_SHIFT) & 0x8000)) | ||||||
| 		{ | 		{ | ||||||
| 			// only process movement (ignore anything without winpos values) | 			// only process movement (ignore anything without winpos values) | ||||||
| @@ -3213,17 +3135,6 @@ LRESULT CMeterWindow::OnWindowPosChanging(WPARAM wParam, LPARAM lParam) | |||||||
| 		{ | 		{ | ||||||
| 			MapCoordsToScreen(wp->x, wp->y, m_WindowW, m_WindowH); | 			MapCoordsToScreen(wp->x, wp->y, m_WindowW, m_WindowH); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		// Convert the screen coordinates to the client coordinates of the shell window |  | ||||||
| 		if (!m_ChildWindow && m_WindowZPosition == ZPOSITION_ONDESKTOP && GetAncestor(m_Window, GA_PARENT) != GetDesktopWindow()) |  | ||||||
| 		{ |  | ||||||
| 			POINT pos = {wp->x, wp->y}; |  | ||||||
| 			if (ScreenToClient(GetAncestor(m_Window, GA_PARENT), &pos)) |  | ||||||
| 			{ |  | ||||||
| 				wp->x = pos.x; |  | ||||||
| 				wp->y = pos.y; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return DefWindowProc(m_Window, m_Message, wParam, lParam); | 	return DefWindowProc(m_Window, m_Message, wParam, lParam); | ||||||
| @@ -3888,28 +3799,11 @@ LRESULT CMeterWindow::OnMove(WPARAM wParam, LPARAM lParam) | |||||||
| 	m_ScreenX = (SHORT)LOWORD(lParam); | 	m_ScreenX = (SHORT)LOWORD(lParam); | ||||||
| 	m_ScreenY = (SHORT)HIWORD(lParam); | 	m_ScreenY = (SHORT)HIWORD(lParam); | ||||||
|  |  | ||||||
| 	// Convert the client coordinates of the shell window to the screen coordinates |  | ||||||
| 	if (!m_ChildWindow && m_WindowZPosition == ZPOSITION_ONDESKTOP && GetAncestor(m_Window, GA_PARENT) != GetDesktopWindow()) |  | ||||||
| 	{ |  | ||||||
| 		POINT pos = {m_ScreenX, m_ScreenY}; |  | ||||||
| 		if (ClientToScreen(GetAncestor(m_Window, GA_PARENT), &pos)) |  | ||||||
| 		{ |  | ||||||
| 			m_ScreenX = pos.x; |  | ||||||
| 			m_ScreenY = pos.y; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (m_Dragging) | 	if (m_Dragging) | ||||||
| 	{ | 	{ | ||||||
| 		ScreenToWindow(); | 		ScreenToWindow(); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Redraw itself if the window is "On Desktop" |  | ||||||
| 	if (!m_ChildWindow && m_WindowZPosition == ZPOSITION_ONDESKTOP && m_NativeTransparency && GetAncestor(m_Window, GA_PARENT) != GetDesktopWindow()) |  | ||||||
| 	{ |  | ||||||
| 		UpdateTransparency(m_TransparencyValue, false); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -134,11 +134,11 @@ public: | |||||||
| 	void DisableMeasure(const WCHAR* name); | 	void DisableMeasure(const WCHAR* name); | ||||||
| 	void EnableMeasure(const WCHAR* name); | 	void EnableMeasure(const WCHAR* name); | ||||||
| 	void ToggleMeasure(const WCHAR* name); | 	void ToggleMeasure(const WCHAR* name); | ||||||
| 	void Refresh(bool init); | 	void Refresh(bool init, bool all = false); | ||||||
| 	void Redraw(); | 	void Redraw(); | ||||||
|  |  | ||||||
| 	void MoveWindow(int x, int y); | 	void MoveWindow(int x, int y); | ||||||
| 	void ChangeZPos(ZPOSITION zPos); | 	void ChangeZPos(ZPOSITION zPos, bool all = false); | ||||||
| 	void FadeWindow(int from, int to); | 	void FadeWindow(int from, int to); | ||||||
| 	 | 	 | ||||||
| 	Gdiplus::Bitmap* GetDoubleBuffer() { return m_DoubleBuffer; }; | 	Gdiplus::Bitmap* GetDoubleBuffer() { return m_DoubleBuffer; }; | ||||||
| @@ -291,6 +291,7 @@ private: | |||||||
| 	int m_WindowUpdate;							// Measure update frequency | 	int m_WindowUpdate;							// Measure update frequency | ||||||
| 	int m_TransitionUpdate;						// Transition redraw frequency | 	int m_TransitionUpdate;						// Transition redraw frequency | ||||||
| 	bool m_ActiveTransition; | 	bool m_ActiveTransition; | ||||||
|  | 	bool m_HasNetMeasures; | ||||||
| 	HIDEMODE m_WindowHide;						// If true, the window is hidden when mouse is over it | 	HIDEMODE m_WindowHide;						// If true, the window is hidden when mouse is over it | ||||||
| 	bool m_WindowStartHidden;					// If true, the window is hidden at startup | 	bool m_WindowStartHidden;					// If true, the window is hidden at startup | ||||||
| 	bool m_SavePosition;						// If true, the window's position is saved | 	bool m_SavePosition;						// If true, the window's position is saved | ||||||
|   | |||||||
| @@ -245,55 +245,11 @@ 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++) | ||||||
| 				{ | 				{ | ||||||
| 					CMeterWindow* window = (*iter).second; | 					((*iter).second)->RunBang(bang, argument.c_str()); | ||||||
| 					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()); |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -448,6 +404,21 @@ void RainmeterRefresh(HWND, const char* arg) | |||||||
| 	BangWithArgs(BANG_REFRESH, ConvertToWide(arg).c_str(), 0); | 	BangWithArgs(BANG_REFRESH, ConvertToWide(arg).c_str(), 0); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | ** RainmeterRefreshApp | ||||||
|  | ** | ||||||
|  | ** Callback for the !RainmeterRefreshApp bang | ||||||
|  | ** | ||||||
|  | */ | ||||||
|  | void RainmeterRefreshApp(HWND, const char* arg) | ||||||
|  | { | ||||||
|  | 	if (Rainmeter) | ||||||
|  | 	{ | ||||||
|  | 		// Refresh needs to be delayed since it crashes if done during Update() | ||||||
|  | 		PostMessage(Rainmeter->GetTrayWindow()->GetWindow(), WM_DELAYED_REFRESH_ALL, (WPARAM)NULL, (LPARAM)NULL); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** RainmeterRedraw | ** RainmeterRedraw | ||||||
| ** | ** | ||||||
| @@ -745,14 +716,16 @@ CRainmeter::~CRainmeter() | |||||||
|  |  | ||||||
| 	if (m_TrayWindow) delete m_TrayWindow; | 	if (m_TrayWindow) delete m_TrayWindow; | ||||||
|  |  | ||||||
|  | 	CSystem::Finalize(); | ||||||
|  |  | ||||||
|  | 	CMeasureNet::UpdateIFTable(); | ||||||
|  | 	CMeasureNet::UpdateStats(); | ||||||
| 	WriteStats(true); | 	WriteStats(true); | ||||||
|  |  | ||||||
| 	CMeasureNet::FinalizeNewApi(); | 	CMeasureNet::FinalizeNewApi(); | ||||||
|  |  | ||||||
| 	CMeterString::FreeFontCache(); | 	CMeterString::FreeFontCache(); | ||||||
|  |  | ||||||
| 	CSystem::Finalize(); |  | ||||||
|  |  | ||||||
| 	GdiplusShutdown(m_GDIplusToken); | 	GdiplusShutdown(m_GDIplusToken); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1012,6 +985,7 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath) | |||||||
| 		if (m_TrayWindow && m_TrayWindow->GetWindow()) ::SendMessage(GetLitestepWnd(), LM_REGISTERMESSAGE, (WPARAM)m_TrayWindow->GetWindow(), (LPARAM)Msgs); | 		if (m_TrayWindow && m_TrayWindow->GetWindow()) ::SendMessage(GetLitestepWnd(), LM_REGISTERMESSAGE, (WPARAM)m_TrayWindow->GetWindow(), (LPARAM)Msgs); | ||||||
|  |  | ||||||
| 		AddBangCommand("!RainmeterRefresh", RainmeterRefresh); | 		AddBangCommand("!RainmeterRefresh", RainmeterRefresh); | ||||||
|  | 		AddBangCommand("!RainmeterRefreshApp", RainmeterRefreshApp); | ||||||
| 		AddBangCommand("!RainmeterRedraw", RainmeterRedraw); | 		AddBangCommand("!RainmeterRedraw", RainmeterRedraw); | ||||||
| 		AddBangCommand("!RainmeterHide", RainmeterHide); | 		AddBangCommand("!RainmeterHide", RainmeterHide); | ||||||
| 		AddBangCommand("!RainmeterShow", RainmeterShow); | 		AddBangCommand("!RainmeterShow", RainmeterShow); | ||||||
| @@ -1040,57 +1014,16 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath) | |||||||
| 		AddBangCommand("!RainmeterSetVariable", RainmeterSetVariable); | 		AddBangCommand("!RainmeterSetVariable", RainmeterSetVariable); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// 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()) |  | ||||||
| 		{ |  | ||||||
| 			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 | 	// Create meter windows for active configs | ||||||
| 	std::vector<std::pair<int, int> >::const_reverse_iterator iter = startup.rbegin(); | 	std::multimap<int, CONFIGORDER>::const_iterator iter = m_ConfigOrders.begin(); | ||||||
| 	for ( ; iter != startup.rend(); iter++) | 	for ( ; iter != m_ConfigOrders.end(); iter++) | ||||||
| 	{ | 	{ | ||||||
| 		if ((*iter).second > 0) | 		ActivateConfig((*iter).second.id, (*iter).second.active - 1); | ||||||
| 		{ |  | ||||||
| 			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); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	//Clear order | ||||||
|  | 	m_ConfigOrders.clear(); | ||||||
|  |  | ||||||
| 	return Result;	// Alles OK | 	return Result;	// Alles OK | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1488,6 +1421,72 @@ CMeterWindow* CRainmeter::GetMeterWindow(HWND hwnd) | |||||||
| 	return NULL; | 	return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void CRainmeter::SetConfigOrder(const std::wstring& config, int index, int active) | ||||||
|  | { | ||||||
|  | 	WCHAR buffer[256]; | ||||||
|  | 	int order; | ||||||
|  |  | ||||||
|  | 	if (GetPrivateProfileString(config.c_str(), L"LoadOrder", L"", buffer, 256, m_IniFile.c_str()) > 0) | ||||||
|  | 	{ | ||||||
|  | 		if (wcsicmp(buffer, L"LAST") == 0) | ||||||
|  | 		{ | ||||||
|  | 			order = INT_MAX; | ||||||
|  | 		} | ||||||
|  | 		else if (wcsicmp(buffer, L"FIRST") == 0) | ||||||
|  | 		{ | ||||||
|  | 			order = INT_MIN; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			order = _wtoi(buffer); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	else  // LoadOrder not exists | ||||||
|  | 	{ | ||||||
|  | 		//WritePrivateProfileString(config.c_str(), L"LoadOrder", L"0", m_IniFile.c_str()); | ||||||
|  | 		order = 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	std::multimap<int, CONFIGORDER>::iterator iter = m_ConfigOrders.begin(); | ||||||
|  | 	for ( ; iter != m_ConfigOrders.end(); iter++) | ||||||
|  | 	{ | ||||||
|  | 		if ((*iter).second.config == config)  // already exists | ||||||
|  | 		{ | ||||||
|  | 			if ((*iter).first != order || (*iter).second.id != index || (*iter).second.active != active) | ||||||
|  | 			{ | ||||||
|  | 				m_ConfigOrders.erase(iter); | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 			{ | ||||||
|  | 				return; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Add CONFIGORDER | ||||||
|  | 	CONFIGORDER configOrder; | ||||||
|  | 	configOrder.config = config; | ||||||
|  | 	configOrder.id = index; | ||||||
|  | 	configOrder.active = active; | ||||||
|  |  | ||||||
|  | 	m_ConfigOrders.insert(std::pair<int, CONFIGORDER>(order, configOrder)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int CRainmeter::GetLoadOrder(const std::wstring& config) | ||||||
|  | { | ||||||
|  | 	std::multimap<int, CONFIGORDER>::const_iterator iter = m_ConfigOrders.begin(); | ||||||
|  | 	for ( ; iter != m_ConfigOrders.end(); iter++) | ||||||
|  | 	{ | ||||||
|  | 		if ((*iter).second.config == config) | ||||||
|  | 		{ | ||||||
|  | 			return (*iter).first; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| /*  | /*  | ||||||
| ** Quit | ** Quit | ||||||
| ** | ** | ||||||
| @@ -1504,6 +1503,7 @@ void CRainmeter::Quit(HINSTANCE dllInst) | |||||||
| 		if (m_TrayWindow && m_TrayWindow->GetWindow()) ::SendMessage(GetLitestepWnd(), LM_UNREGISTERMESSAGE, (WPARAM)m_TrayWindow->GetWindow(), (LPARAM)Msgs); | 		if (m_TrayWindow && m_TrayWindow->GetWindow()) ::SendMessage(GetLitestepWnd(), LM_UNREGISTERMESSAGE, (WPARAM)m_TrayWindow->GetWindow(), (LPARAM)Msgs); | ||||||
|  |  | ||||||
| 		RemoveBangCommand("!RainmeterRefresh"); | 		RemoveBangCommand("!RainmeterRefresh"); | ||||||
|  | 		RemoveBangCommand("!RainmeterRefreshApp"); | ||||||
| 		RemoveBangCommand("!RainmeterRedraw"); | 		RemoveBangCommand("!RainmeterRedraw"); | ||||||
| 		RemoveBangCommand("!RainmeterHide"); | 		RemoveBangCommand("!RainmeterHide"); | ||||||
| 		RemoveBangCommand("!RainmeterShow"); | 		RemoveBangCommand("!RainmeterShow"); | ||||||
| @@ -1542,6 +1542,7 @@ void CRainmeter::ScanForConfigs(std::wstring& path) | |||||||
| { | { | ||||||
| 	m_ConfigStrings.clear(); | 	m_ConfigStrings.clear(); | ||||||
| 	m_ConfigMenu.clear(); | 	m_ConfigMenu.clear(); | ||||||
|  | 	m_ConfigOrders.clear(); | ||||||
|  |  | ||||||
| 	ScanForConfigsRecursive(path, L"", 0, m_ConfigMenu, false); | 	ScanForConfigsRecursive(path, L"", 0, m_ConfigMenu, false); | ||||||
| } | } | ||||||
| @@ -1664,11 +1665,8 @@ BOOL CRainmeter::ExecuteBang(const std::wstring& bang, const std::wstring& arg, | |||||||
| 	} | 	} | ||||||
| 	else if (wcsicmp(bang.c_str(), L"!RainmeterRefreshApp") == 0) | 	else if (wcsicmp(bang.c_str(), L"!RainmeterRefreshApp") == 0) | ||||||
| 	{ | 	{ | ||||||
| 		// Read skins and settings | 		// Refresh needs to be delayed since it crashes if done during Update() | ||||||
| 		Rainmeter->ReloadSettings(); | 		PostMessage(m_TrayWindow->GetWindow(), WM_DELAYED_REFRESH_ALL, (WPARAM)NULL, (LPARAM)NULL); | ||||||
| 		// Refresh all |  | ||||||
| 		RainmeterRefresh(m_TrayWindow->GetWindow(), NULL); |  | ||||||
|  |  | ||||||
| 	} | 	} | ||||||
| 	else if (wcsicmp(bang.c_str(), L"!RainmeterRedraw") == 0) | 	else if (wcsicmp(bang.c_str(), L"!RainmeterRedraw") == 0) | ||||||
| 	{ | 	{ | ||||||
| @@ -2035,6 +2033,8 @@ void CRainmeter::ReadGeneralSettings(std::wstring& iniFile) | |||||||
| 		if (active > 0 && active <= (int)m_ConfigStrings[i].iniFiles.size()) | 		if (active > 0 && active <= (int)m_ConfigStrings[i].iniFiles.size()) | ||||||
| 		{ | 		{ | ||||||
| 			m_ConfigStrings[i].active = active; | 			m_ConfigStrings[i].active = active; | ||||||
|  |  | ||||||
|  | 			SetConfigOrder(m_ConfigStrings[i].config, i, active); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -2067,39 +2067,52 @@ bool CRainmeter::SetActiveConfig(std::wstring& skinName, std::wstring& skinIni) | |||||||
| } | } | ||||||
|  |  | ||||||
| /*  | /*  | ||||||
| ** Refresh | ** RefreshAll | ||||||
|  | ** | ||||||
|  | ** Refreshes all active meter windows. | ||||||
|  | ** Note: This function calls CMeterWindow::Refresh() directly for synchronization. Be careful about crash. | ||||||
| ** | ** | ||||||
| ** Refreshes Rainmeter. If argument is given the config is refreshed |  | ||||||
| ** otherwise all active meters are refreshed |  | ||||||
| */ | */ | ||||||
| //void CRainmeter::Refresh(const WCHAR* arg) | void CRainmeter::RefreshAll() | ||||||
| //{ | { | ||||||
| //	std::wstring config, iniFile; | 	// Read skins and settings | ||||||
| // | 	ReloadSettings(); | ||||||
| //	try  |  | ||||||
| //	{ | 	// Make the sending order by using LoadOrder | ||||||
| //		if (arg != NULL && wcslen(arg) > 0)  | 	std::multimap<int, CMeterWindow*> windows; | ||||||
| //		{ |  | ||||||
| //			std::wstring config = arg; | 	std::map<std::wstring, CMeterWindow*>::iterator iter = m_Meters.begin(); | ||||||
| //			CMeterWindow* meterWindow = GetMeterWindow(config); | 	for (; iter != m_Meters.end(); iter++) | ||||||
| //			meterWindow->Refresh(false); | 	{ | ||||||
| //		} | 		if ((*iter).second) | ||||||
| //		else | 		{ | ||||||
| //		{ | 			windows.insert(std::pair<int, CMeterWindow*>(GetLoadOrder((*iter).first), (*iter).second)); | ||||||
| //			std::map<std::wstring, CMeterWindow*>::iterator iter = m_Meters.begin(); | 		} | ||||||
| // | 	} | ||||||
| //			// Refresh all |  | ||||||
| //			for (; iter != m_Meters.end(); iter++) | 	// Prepare the helper window | ||||||
| //			{ | 	CSystem::PrepareHelperWindow(CSystem::GetWorkerW()); | ||||||
| //				(*iter).second->Refresh(false); |  | ||||||
| //			} | 	// Refresh all | ||||||
| //		} | 	std::multimap<int, CMeterWindow*>::const_iterator iter2 = windows.begin(); | ||||||
| //	}  | 	for ( ; iter2 != windows.end(); iter2++) | ||||||
| //	catch(CError& error)  | 	{ | ||||||
| //	{ | 		if ((*iter2).second) | ||||||
| //		MessageBox(NULL, error.GetString().c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION); | 		{ | ||||||
| //	} | 			try | ||||||
| //} | 			{ | ||||||
|  | 				(*iter2).second->Refresh(false, true); | ||||||
|  | 			} | ||||||
|  | 			catch (CError& error) | ||||||
|  | 			{ | ||||||
|  | 				MessageBox((*iter2).second->GetWindow(), error.GetString().c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// Clear order | ||||||
|  | 	m_ConfigOrders.clear(); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** ReadStats | ** ReadStats | ||||||
|   | |||||||
| @@ -52,6 +52,7 @@ void RainmeterActivateConfig(HWND, const char* arg); | |||||||
| void RainmeterDeactivateConfig(HWND, const char* arg); | void RainmeterDeactivateConfig(HWND, const char* arg); | ||||||
| void RainmeterToggleConfig(HWND, const char* arg); | void RainmeterToggleConfig(HWND, const char* arg); | ||||||
| void RainmeterRefresh(HWND, const char* arg); | void RainmeterRefresh(HWND, const char* arg); | ||||||
|  | void RainmeterRefreshApp(HWND, const char* arg); | ||||||
| void RainmeterRedraw(HWND, const char* arg); | void RainmeterRedraw(HWND, const char* arg); | ||||||
| void RainmeterToggleMeasure(HWND, const char* arg); | void RainmeterToggleMeasure(HWND, const char* arg); | ||||||
| void RainmeterEnableMeasure(HWND, const char* arg); | void RainmeterEnableMeasure(HWND, const char* arg); | ||||||
| @@ -92,6 +93,13 @@ public: | |||||||
| 		int active; | 		int active; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	struct CONFIGORDER | ||||||
|  | 	{ | ||||||
|  | 		std::wstring config; | ||||||
|  | 		int id; | ||||||
|  | 		int active; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| 	struct CONFIGMENU | 	struct CONFIGMENU | ||||||
| 	{ | 	{ | ||||||
| 		std::wstring name; | 		std::wstring name; | ||||||
| @@ -115,6 +123,7 @@ public: | |||||||
| 	CMeterWindow* GetMeterWindow(HWND hwnd); | 	CMeterWindow* GetMeterWindow(HWND hwnd); | ||||||
| 	std::map<std::wstring, CMeterWindow*>& GetAllMeterWindows() { return m_Meters; }; | 	std::map<std::wstring, CMeterWindow*>& GetAllMeterWindows() { return m_Meters; }; | ||||||
| 	const std::vector<CONFIG>& GetAllConfigs() { return m_ConfigStrings; }; | 	const std::vector<CONFIG>& GetAllConfigs() { return m_ConfigStrings; }; | ||||||
|  | 	const std::multimap<int, CONFIGORDER>& GetAllConfigOrders() { return m_ConfigOrders; } | ||||||
| 	const std::vector<std::wstring>& GetAllThemes() { return m_Themes; }; | 	const std::vector<std::wstring>& GetAllThemes() { return m_Themes; }; | ||||||
|  |  | ||||||
| 	void ActivateConfig(int configIndex, int iniIndex); | 	void ActivateConfig(int configIndex, int iniIndex); | ||||||
| @@ -163,6 +172,8 @@ public: | |||||||
| 	std::wstring ParseCommand(const WCHAR* command, CMeterWindow* meterWindow); | 	std::wstring ParseCommand(const WCHAR* command, CMeterWindow* meterWindow); | ||||||
| 	void ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow); | 	void ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow); | ||||||
|  |  | ||||||
|  | 	void RefreshAll(); | ||||||
|  |  | ||||||
| 	void ClearDeleteLaterList(); | 	void ClearDeleteLaterList(); | ||||||
|  |  | ||||||
| 	static PLATFORM IsNT(); | 	static PLATFORM IsNT(); | ||||||
| @@ -175,8 +186,9 @@ private: | |||||||
| 	void ScanForConfigs(std::wstring& path); | 	void ScanForConfigs(std::wstring& path); | ||||||
| 	void ScanForThemes(std::wstring& path); | 	void ScanForThemes(std::wstring& path); | ||||||
| 	void ReadGeneralSettings(std::wstring& path); | 	void ReadGeneralSettings(std::wstring& path); | ||||||
|  | 	void SetConfigOrder(const std::wstring& config, int index, int active); | ||||||
|  | 	int GetLoadOrder(const std::wstring& config); | ||||||
| 	bool SetActiveConfig(std::wstring& skinName, std::wstring& skinIni); | 	bool SetActiveConfig(std::wstring& skinName, std::wstring& skinIni); | ||||||
| 	//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); | ||||||
| @@ -193,6 +205,7 @@ private: | |||||||
|  |  | ||||||
| 	std::vector<CONFIG> m_ConfigStrings;	    // All configs found in the given folder | 	std::vector<CONFIG> m_ConfigStrings;	    // All configs found in the given folder | ||||||
| 	std::vector<CONFIGMENU> m_ConfigMenu; | 	std::vector<CONFIGMENU> m_ConfigMenu; | ||||||
|  | 	std::multimap<int, CONFIGORDER> m_ConfigOrders; | ||||||
| 	std::map<std::wstring, CMeterWindow*> m_Meters;			// The meter windows | 	std::map<std::wstring, CMeterWindow*> m_Meters;			// The meter windows | ||||||
| 	std::vector<std::wstring> m_Themes; | 	std::vector<std::wstring> m_Themes; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -20,22 +20,31 @@ | |||||||
| #include "System.h" | #include "System.h" | ||||||
| #include "Litestep.h" | #include "Litestep.h" | ||||||
| #include "Rainmeter.h" | #include "Rainmeter.h" | ||||||
|  | #include "MeasureNet.h" | ||||||
| #include "Error.h" | #include "Error.h" | ||||||
|  |  | ||||||
|  | #define DEBUG_VERBOSE  (0)  // Set 1 if you need verbose logging. | ||||||
|  |  | ||||||
| enum TIMER | enum TIMER | ||||||
| { | { | ||||||
| 	TIMER_SHOWDESKTOP = 1, | 	TIMER_SHOWDESKTOP = 1, | ||||||
| 	TIMER_COMPOSITION = 2 | 	TIMER_COMPOSITION = 2, | ||||||
|  | 	TIMER_NETSTATS    = 3 | ||||||
| }; | }; | ||||||
| enum INTERVAL | enum INTERVAL | ||||||
| { | { | ||||||
| 	INTERVAL_SHOWDESKTOP = 250, | 	INTERVAL_SHOWDESKTOP = 250, | ||||||
| 	INTERVAL_COMPOSITION = 250 | 	INTERVAL_COMPOSITION = 250, | ||||||
|  | 	INTERVAL_NETSTATS    = 10000 | ||||||
| }; | }; | ||||||
|  |  | ||||||
| MULTIMONITOR_INFO CSystem::c_Monitors = { 0 }; | MULTIMONITOR_INFO CSystem::c_Monitors = { 0 }; | ||||||
|  |  | ||||||
| HWND CSystem::c_Window = NULL; | HWND CSystem::c_Window = NULL; | ||||||
|  | HWND CSystem::c_HelperWindow = NULL; | ||||||
|  |  | ||||||
|  | HWINEVENTHOOK CSystem::c_WinEventHook = NULL; | ||||||
|  |  | ||||||
| bool CSystem::c_DwmCompositionEnabled = false; | bool CSystem::c_DwmCompositionEnabled = false; | ||||||
| bool CSystem::c_ShowDesktop = false; | bool CSystem::c_ShowDesktop = false; | ||||||
|  |  | ||||||
| @@ -44,7 +53,7 @@ extern CRainmeter* Rainmeter; | |||||||
| /* | /* | ||||||
| ** Initialize | ** Initialize | ||||||
| ** | ** | ||||||
| ** Creates a window to detect changes in the system. | ** Creates a helper window to detect changes in the system. | ||||||
| ** | ** | ||||||
| */ | */ | ||||||
| void CSystem::Initialize(HINSTANCE instance) | void CSystem::Initialize(HINSTANCE instance) | ||||||
| @@ -59,7 +68,7 @@ void CSystem::Initialize(HINSTANCE instance) | |||||||
| 	c_Window = CreateWindowEx( | 	c_Window = CreateWindowEx( | ||||||
| 		WS_EX_TOOLWINDOW, | 		WS_EX_TOOLWINDOW, | ||||||
| 		L"RainmeterSystemClass", | 		L"RainmeterSystemClass", | ||||||
| 		NULL, | 		L"SystemWindow", | ||||||
| 		WS_POPUP, | 		WS_POPUP, | ||||||
| 		CW_USEDEFAULT, | 		CW_USEDEFAULT, | ||||||
| 		CW_USEDEFAULT, | 		CW_USEDEFAULT, | ||||||
| @@ -70,19 +79,43 @@ void CSystem::Initialize(HINSTANCE instance) | |||||||
| 		instance, | 		instance, | ||||||
| 		NULL); | 		NULL); | ||||||
|  |  | ||||||
| 	SetWindowPos(c_Window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | 	c_HelperWindow = CreateWindowEx( | ||||||
|  | 		WS_EX_TOOLWINDOW, | ||||||
|  | 		L"RainmeterSystemClass", | ||||||
|  | 		L"PositioningHelperWindow", | ||||||
|  | 		WS_POPUP, | ||||||
|  | 		CW_USEDEFAULT, | ||||||
|  | 		CW_USEDEFAULT, | ||||||
|  | 		CW_USEDEFAULT, | ||||||
|  | 		CW_USEDEFAULT, | ||||||
|  | 		NULL, | ||||||
|  | 		NULL, | ||||||
|  | 		instance, | ||||||
|  | 		NULL); | ||||||
|  |  | ||||||
| #ifndef _WIN64 | #ifndef _WIN64 | ||||||
| 	SetWindowLong(c_Window, GWL_USERDATA, magicDWord); | 	SetWindowLong(c_Window, GWL_USERDATA, magicDWord); | ||||||
|  | 	SetWindowLong(c_HelperWindow, GWL_USERDATA, magicDWord); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | 	SetWindowPos(c_Window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||||
|  | 	SetWindowPos(c_HelperWindow, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||||
|  |  | ||||||
| 	SetMultiMonitorInfo(); | 	SetMultiMonitorInfo(); | ||||||
|  |  | ||||||
| 	c_DwmCompositionEnabled = (DwmIsCompositionEnabled() == TRUE); | 	c_DwmCompositionEnabled = (DwmIsCompositionEnabled() == TRUE); | ||||||
| 	if (c_DwmCompositionEnabled) |  | ||||||
| 	{ | 	c_WinEventHook = SetWinEventHook( | ||||||
| 		SetTimer(c_Window, TIMER_SHOWDESKTOP, INTERVAL_SHOWDESKTOP, NULL); | 		EVENT_SYSTEM_FOREGROUND, | ||||||
| 	} | 		EVENT_SYSTEM_FOREGROUND, | ||||||
|  | 		NULL, | ||||||
|  | 		MyWinEventProc, | ||||||
|  | 		0, | ||||||
|  | 		0, | ||||||
|  | 		WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); | ||||||
|  |  | ||||||
|  | 	SetTimer(c_Window, TIMER_SHOWDESKTOP, INTERVAL_SHOWDESKTOP, NULL); | ||||||
|  | 	SetTimer(c_Window, TIMER_NETSTATS, INTERVAL_NETSTATS, NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -95,7 +128,11 @@ void CSystem::Finalize() | |||||||
| { | { | ||||||
| 	KillTimer(c_Window, TIMER_SHOWDESKTOP); | 	KillTimer(c_Window, TIMER_SHOWDESKTOP); | ||||||
| 	KillTimer(c_Window, TIMER_COMPOSITION); | 	KillTimer(c_Window, TIMER_COMPOSITION); | ||||||
|  | 	KillTimer(c_Window, TIMER_NETSTATS); | ||||||
|  |  | ||||||
|  | 	if (c_WinEventHook) UnhookWinEvent(c_WinEventHook); | ||||||
|  |  | ||||||
|  | 	if (c_HelperWindow) DestroyWindow(c_HelperWindow); | ||||||
| 	if (c_Window) DestroyWindow(c_Window); | 	if (c_Window) DestroyWindow(c_Window); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -491,102 +528,143 @@ void CSystem::UpdateWorkareaInfo() | |||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** GetShellDesktopWindow | ** GetDefaultShellWindow | ||||||
| ** | ** | ||||||
| ** Finds the Shell's desktop window. | ** Finds the Default Shell's window. | ||||||
| ** | ** | ||||||
| */ | */ | ||||||
| HWND CSystem::GetShellDesktopWindow() | HWND CSystem::GetDefaultShellWindow() | ||||||
| { | { | ||||||
| 	HWND DesktopW = NULL; | 	HWND ShellW = GetShellWindow(); | ||||||
|  |  | ||||||
| 	HWND hwnd = FindWindow(L"Progman", L"Program Manager"); | 	if (ShellW) | ||||||
| 	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; | 		HWND hwnd = NULL; | ||||||
| 		while (WorkerW = FindWindowEx(NULL, WorkerW, L"WorkerW", L"")) | 		while (hwnd = FindWindowEx(NULL, hwnd, L"Progman", NULL)) | ||||||
| 		{ | 		{ | ||||||
| 			if ((hwnd = FindWindowEx(WorkerW, NULL, L"SHELLDLL_DefView", L"")) && | 			if (hwnd == ShellW) return ShellW; | ||||||
| 				(DesktopW = FindWindowEx(hwnd, NULL, L"SysListView32", L"FolderView"))) break; |  | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return DesktopW; | 	return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** GetWorkerW | ** GetShellDesktopWindow | ||||||
| ** | ** | ||||||
| ** Finds the WorkerW window. | ** Finds the Shell's desktop window or WorkerW window. | ||||||
| ** If the Progman or WorkerW window is not found, this function returns NULL. | ** If the window is not found, this function returns NULL. | ||||||
| **  | **  | ||||||
| ** In Windows Vista / 7 (without Aero): | ** Note for WorkerW: | ||||||
|  | ** | ||||||
|  | ** In Earlier Windows / 7 (without Aero): | ||||||
| ** This function returns a topmost window handle which is visible. | ** This function returns a topmost window handle which is visible. | ||||||
| ** | ** | ||||||
| ** In Windows 7 (with Aero): | ** In Windows 7 (with Aero): | ||||||
| ** This function returns a window handle which has the "SHELLDLL_DefView". | ** This function returns a window handle which has the "SHELLDLL_DefView". | ||||||
| ** | ** | ||||||
| */ | */ | ||||||
| HWND CSystem::GetWorkerW() | HWND CSystem::GetShellDesktopWindow(bool findWorkerW) | ||||||
| { | { | ||||||
| 	HWND WorkerW = NULL; | 	HWND DesktopW = NULL, hwnd; | ||||||
|  |  | ||||||
| 	HWND hwnd = FindWindow(L"Progman", L"Program Manager"); | 	HWND ShellW = GetDefaultShellWindow(); | ||||||
| 	if (!hwnd) return NULL;  // Default Shell (Explorer) not started | 	if (!ShellW) return NULL;  // Default Shell (Explorer) not running | ||||||
|  |  | ||||||
| 	if ((hwnd = FindWindowEx(hwnd, NULL, L"SHELLDLL_DefView", L"")) && | 	if ((hwnd = FindWindowEx(ShellW, NULL, L"SHELLDLL_DefView", L"")) && | ||||||
| 		(hwnd = FindWindowEx(hwnd, NULL, L"SysListView32", L"FolderView")))  // for Windows Vista / 7 (without Aero) | 		(DesktopW = FindWindowEx(hwnd, NULL, L"SysListView32", NULL)))  // In Earlier Windows / 7 (without Aero) | ||||||
| 	{ | 	{ | ||||||
| 		while (WorkerW = FindWindowEx(NULL, WorkerW, L"WorkerW", L"")) | 		if (findWorkerW) | ||||||
| 		{ | 		{ | ||||||
| 			if (IsWindowVisible(WorkerW)) | 			HWND WorkerW = NULL; | ||||||
|  | 			while (WorkerW = FindWindowEx(NULL, WorkerW, L"WorkerW", L"")) | ||||||
| 			{ | 			{ | ||||||
| 				// Check whether WorkerW covers whole of the screens | 				if (IsWindowVisible(WorkerW) && BelongToSameProcess(ShellW, WorkerW)) | ||||||
| 				WINDOWPLACEMENT wp = {sizeof(WINDOWPLACEMENT)}; | 				{ | ||||||
| 				GetWindowPlacement(WorkerW, &wp); | 					// Check whether WorkerW covers whole of the screens | ||||||
|  | 					WINDOWPLACEMENT wp = {sizeof(WINDOWPLACEMENT)}; | ||||||
|  | 					GetWindowPlacement(WorkerW, &wp); | ||||||
|  |  | ||||||
| 				if (wp.rcNormalPosition.left == c_Monitors.vsL && | 					if (wp.rcNormalPosition.left == c_Monitors.vsL && | ||||||
| 					wp.rcNormalPosition.top == c_Monitors.vsT && | 						wp.rcNormalPosition.top == c_Monitors.vsT && | ||||||
| 					(wp.rcNormalPosition.right - wp.rcNormalPosition.left) == c_Monitors.vsW && | 						(wp.rcNormalPosition.right - wp.rcNormalPosition.left) == c_Monitors.vsW && | ||||||
| 					(wp.rcNormalPosition.bottom - wp.rcNormalPosition.top) == c_Monitors.vsH) break; | 						(wp.rcNormalPosition.bottom - wp.rcNormalPosition.top) == c_Monitors.vsH) | ||||||
|  | 					{ | ||||||
|  | 						return WorkerW; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			if (BelongToSameProcess(ShellW, DesktopW)) | ||||||
|  | 			{ | ||||||
|  | 				return DesktopW; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else  // for Windows 7 (with Aero) | 	else  // In Windows 7 (with Aero) | ||||||
| 	{ | 	{ | ||||||
|  | 		HWND WorkerW = NULL; | ||||||
| 		while (WorkerW = FindWindowEx(NULL, WorkerW, L"WorkerW", L"")) | 		while (WorkerW = FindWindowEx(NULL, WorkerW, L"WorkerW", L"")) | ||||||
| 		{ | 		{ | ||||||
| 			if ((hwnd = FindWindowEx(WorkerW, NULL, L"SHELLDLL_DefView", L"")) && | 			if (BelongToSameProcess(ShellW, WorkerW)) | ||||||
| 				FindWindowEx(hwnd, NULL, L"SysListView32", L"FolderView")) break; | 			{ | ||||||
|  | 				if ((hwnd = FindWindowEx(WorkerW, NULL, L"SHELLDLL_DefView", L"")) && | ||||||
|  | 					(DesktopW = FindWindowEx(hwnd, NULL, L"SysListView32", NULL))) | ||||||
|  | 				{ | ||||||
|  | 					if (findWorkerW) | ||||||
|  | 					{ | ||||||
|  | 						return WorkerW; | ||||||
|  | 					} | ||||||
|  | 					else | ||||||
|  | 					{ | ||||||
|  | 						return DesktopW; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return WorkerW; | 	return NULL; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | ** BelongToSameProcess | ||||||
|  | ** | ||||||
|  | ** Checks whether the given windows belong to the same process. | ||||||
|  | ** | ||||||
|  | */ | ||||||
|  | bool CSystem::BelongToSameProcess(HWND hwndA, HWND hwndB) | ||||||
|  | { | ||||||
|  | 	DWORD procAId = 0, procBId = 0; | ||||||
|  |  | ||||||
|  | 	GetWindowThreadProcessId(hwndA, &procAId); | ||||||
|  | 	GetWindowThreadProcessId(hwndB, &procBId); | ||||||
|  |  | ||||||
|  | 	return (procAId == procBId); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| ** MyEnumWindowsProc | ** MyEnumWindowsProc | ||||||
| ** | ** | ||||||
| ** Retrieves the Rainmeter meter window pinned on desktop in Z-order. | ** Retrieves the Rainmeter's meter windows in Z-order. | ||||||
| ** | ** | ||||||
| */ | */ | ||||||
| BOOL CALLBACK MyEnumWindowsProc(HWND hwnd, LPARAM lParam) | BOOL CALLBACK MyEnumWindowsProc(HWND hwnd, LPARAM lParam) | ||||||
| { | { | ||||||
| 	bool logging = false;  // Set true if you need verbose logging. | 	bool logging = CRainmeter::GetDebug() && DEBUG_VERBOSE; | ||||||
| 	WCHAR className[128] = {0}; | 	WCHAR className[128] = {0}; | ||||||
| 	CMeterWindow* Window; | 	CMeterWindow* Window; | ||||||
|  |  | ||||||
| 	if (GetClassName(hwnd, className, 128) > 0 && | 	if (GetClassName(hwnd, className, 128) > 0 && | ||||||
| 		wcscmp(className, L"RainmeterMeterWindow") == 0 && | 		wcscmp(className, L"RainmeterMeterWindow") == 0 && | ||||||
| 		Rainmeter && | 		Rainmeter && (Window = Rainmeter->GetMeterWindow(hwnd))) | ||||||
| 		(Window = Rainmeter->GetMeterWindow(hwnd))) |  | ||||||
| 	{ | 	{ | ||||||
| 		if (Window->GetWindowZPosition() == ZPOSITION_ONDESKTOP) | 		ZPOSITION zPos = Window->GetWindowZPosition(); | ||||||
|  | 		if (zPos == 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 (logging) DebugLog(L"+ [%c] 0x%08X : %s (Name: \"%s\", zPos=%i)", IsWindowVisible(hwnd) ? L'V' : L'H', hwnd, className, Window->GetSkinName().c_str(), (int)zPos); | ||||||
|  |  | ||||||
| 			if (lParam) | 			if (lParam) | ||||||
| 			{ | 			{ | ||||||
| @@ -595,7 +673,7 @@ BOOL CALLBACK MyEnumWindowsProc(HWND hwnd, LPARAM lParam) | |||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			if (logging) DebugLog(L"- [%c] 0x%08X : %s (Name: \"%s\")", IsWindowVisible(hwnd) ? L'V' : L'H', hwnd, className, Window->GetSkinName().c_str()); | 			if (logging) DebugLog(L"- [%c] 0x%08X : %s (Name: \"%s\", zPos=%i)", IsWindowVisible(hwnd) ? L'V' : L'H', hwnd, className, Window->GetSkinName().c_str(), (int)zPos); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| @@ -616,42 +694,146 @@ void CSystem::ChangeZPosInOrder() | |||||||
| { | { | ||||||
| 	if (Rainmeter) | 	if (Rainmeter) | ||||||
| 	{ | 	{ | ||||||
| 		bool logging = false;  // Set true if you need verbose logging. | 		bool logging = CRainmeter::GetDebug() && DEBUG_VERBOSE; | ||||||
| 		std::vector<CMeterWindow*> windowsInZOrder; | 		std::vector<CMeterWindow*> windowsInZOrder; | ||||||
|  |  | ||||||
| 		if (logging) LSLog(LOG_DEBUG, L"Rainmeter", L"1: -----"); | 		if (logging) LSLog(LOG_DEBUG, L"Rainmeter", L"1: ----- BEFORE -----"); | ||||||
|  |  | ||||||
| 		// Retrieve the Rainmeter meter window in Z-order | 		// Retrieve the Rainmeter's meter windows in Z-order | ||||||
| 		if (logging) LSLog(LOG_DEBUG, L"Rainmeter", L" [Top-level window]"); |  | ||||||
| 		EnumWindows(MyEnumWindowsProc, (LPARAM)(&windowsInZOrder)); | 		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 | 		// Reset ZPos in Z-order | ||||||
| 		for (size_t i = 0; i < windowsInZOrder.size(); i++) | 		for (size_t i = 0; i < windowsInZOrder.size(); i++) | ||||||
| 		{ | 		{ | ||||||
| 			windowsInZOrder[i]->ChangeZPos(ZPOSITION_ONDESKTOP);  // reset | 			windowsInZOrder[i]->ChangeZPos(windowsInZOrder[i]->GetWindowZPosition());  // reset | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (logging) | 		if (logging) | ||||||
| 		{ | 		{ | ||||||
| 			LSLog(LOG_DEBUG, L"Rainmeter", L"3: -----"); | 			LSLog(LOG_DEBUG, L"Rainmeter", L"2: ----- AFTER -----"); | ||||||
| 			LSLog(LOG_DEBUG, L"Rainmeter", L" [Top-level window]"); |  | ||||||
|  |  | ||||||
| 			// Log all windows in Z-order | 			// Log all windows in Z-order | ||||||
| 			EnumWindows(MyEnumWindowsProc, (LPARAM)NULL); | 			EnumWindows(MyEnumWindowsProc, (LPARAM)NULL); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| 			if (DesktopW) | /* | ||||||
|  | ** PrepareHelperWindow | ||||||
|  | ** | ||||||
|  | ** Moves the helper window to the reference position. | ||||||
|  | ** | ||||||
|  | */ | ||||||
|  | void CSystem::PrepareHelperWindow(HWND WorkerW) | ||||||
|  | { | ||||||
|  | 	bool logging = CRainmeter::GetDebug(); | ||||||
|  |  | ||||||
|  | 	if (c_ShowDesktop && WorkerW) | ||||||
|  | 	{ | ||||||
|  | 		// Set WS_EX_TOPMOST flag | ||||||
|  | 		SetWindowPos(c_HelperWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||||
|  |  | ||||||
|  | 		// Find the "backmost" topmost window | ||||||
|  | 		HWND hwnd = WorkerW; | ||||||
|  | 		while (hwnd = ::GetNextWindow(hwnd, GW_HWNDPREV)) | ||||||
|  | 		{ | ||||||
|  | 			if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) | ||||||
| 			{ | 			{ | ||||||
| 				LSLog(LOG_DEBUG, L"Rainmeter", L" [Child of Shell's desktop window]"); | 				WCHAR className[128], windowText[128]; | ||||||
| 				EnumChildWindows(DesktopW, MyEnumWindowsProc, (LPARAM)NULL); |  | ||||||
|  | 				if (logging) | ||||||
|  | 				{ | ||||||
|  | 					GetClassName(hwnd, className, 128); | ||||||
|  | 					GetWindowText(hwnd, windowText, 128); | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				// Insert the helper window after the found window | ||||||
|  | 				if (0 != SetWindowPos(c_HelperWindow, hwnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING)) | ||||||
|  | 				{ | ||||||
|  | 					if (logging) | ||||||
|  | 					{ | ||||||
|  | 						DebugLog(L"System: HelperWindow: hwnd=0x%08X (WorkerW=0x%08X), hwndInsertAfter=0x%08X (\"%s\" %s) - %s", | ||||||
|  | 							c_HelperWindow, WorkerW, hwnd, windowText, className, (GetWindowLong(c_HelperWindow, GWL_EXSTYLE) & WS_EX_TOPMOST) ? L"TOPMOST" : L"NORMAL"); | ||||||
|  | 					} | ||||||
|  | 					return; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				if (logging) | ||||||
|  | 				{ | ||||||
|  | 					DebugLog(L"System: HelperWindow: hwnd=0x%08X (WorkerW=0x%08X), hwndInsertAfter=0x%08X (\"%s\" %s) - FAILED", | ||||||
|  | 						c_HelperWindow, WorkerW, hwnd, windowText, className); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (logging) | ||||||
|  | 		{ | ||||||
|  | 			DebugLog(L"System: HelperWindow: hwnd=0x%08X (WorkerW=0x%08X), hwndInsertAfter=HWND_TOPMOST - %s", | ||||||
|  | 				c_HelperWindow, WorkerW, (GetWindowLong(c_HelperWindow, GWL_EXSTYLE) & WS_EX_TOPMOST) ? L"TOPMOST" : L"NORMAL"); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		// Insert the helper window to the bottom | ||||||
|  | 		SetWindowPos(c_HelperWindow, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||||
|  |  | ||||||
|  | 		if (logging) | ||||||
|  | 		{ | ||||||
|  | 			DebugLog(L"System: HelperWindow: hwnd=0x%08X (WorkerW=0x%08X), hwndInsertAfter=HWND_BOTTOM - %s", | ||||||
|  | 				c_HelperWindow, WorkerW, (GetWindowLong(c_HelperWindow, GWL_EXSTYLE) & WS_EX_TOPMOST) ? L"TOPMOST" : L"NORMAL"); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | ** CheckDesktopState | ||||||
|  | ** | ||||||
|  | ** Changes the "Show Desktop" state. | ||||||
|  | ** | ||||||
|  | */ | ||||||
|  | void CSystem::CheckDesktopState(HWND WorkerW) | ||||||
|  | { | ||||||
|  | 	HWND hwnd = NULL; | ||||||
|  |  | ||||||
|  | 	if (WorkerW) | ||||||
|  | 	{ | ||||||
|  | 		hwnd = FindWindowEx(NULL, WorkerW, L"RainmeterSystemClass", L"SystemWindow"); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if ((hwnd && !c_ShowDesktop) || (!hwnd && c_ShowDesktop))  // State changed | ||||||
|  | 	{ | ||||||
|  | 		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."); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		PrepareHelperWindow(WorkerW); | ||||||
|  |  | ||||||
|  | 		ChangeZPosInOrder(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  | ** MyWinEventHook | ||||||
|  | ** | ||||||
|  | ** The event hook procedure | ||||||
|  | ** | ||||||
|  | */ | ||||||
|  | void CALLBACK CSystem::MyWinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) | ||||||
|  | { | ||||||
|  | 	if (event == EVENT_SYSTEM_FOREGROUND) | ||||||
|  | 	{ | ||||||
|  | 		if (!c_ShowDesktop) | ||||||
|  | 		{ | ||||||
|  | 			WCHAR className[128]; | ||||||
|  | 			if (GetClassName(hwnd, className, 128) > 0 && | ||||||
|  | 				wcscmp(className, L"WorkerW") == 0 && | ||||||
|  | 				hwnd == GetWorkerW()) | ||||||
|  | 			{ | ||||||
|  | 				CheckDesktopState(hwnd); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| @@ -667,6 +849,11 @@ LRESULT CALLBACK CSystem::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP | |||||||
| { | { | ||||||
| 	static int DesktopCompositionCheckCount = 0; | 	static int DesktopCompositionCheckCount = 0; | ||||||
|  |  | ||||||
|  | 	if (uMsg == WM_CREATE || hWnd != c_Window) | ||||||
|  | 	{ | ||||||
|  | 		return DefWindowProc(hWnd, uMsg, wParam, lParam); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	switch (uMsg) | 	switch (uMsg) | ||||||
| 	{ | 	{ | ||||||
| 	case WM_WINDOWPOSCHANGING: | 	case WM_WINDOWPOSCHANGING: | ||||||
| @@ -677,27 +864,7 @@ LRESULT CALLBACK CSystem::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP | |||||||
| 		switch (wParam) | 		switch (wParam) | ||||||
| 		{ | 		{ | ||||||
| 		case TIMER_SHOWDESKTOP: | 		case TIMER_SHOWDESKTOP: | ||||||
| 			{ | 			CheckDesktopState(GetWorkerW()); | ||||||
| 				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; | 			return 0; | ||||||
|  |  | ||||||
| 		case TIMER_COMPOSITION: | 		case TIMER_COMPOSITION: | ||||||
| @@ -706,12 +873,16 @@ LRESULT CALLBACK CSystem::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP | |||||||
| 				{ | 				{ | ||||||
| 					KillTimer(c_Window, TIMER_COMPOSITION); | 					KillTimer(c_Window, TIMER_COMPOSITION); | ||||||
|  |  | ||||||
| 					ChangeZPosInOrder(); | 					c_WinEventHook = SetWinEventHook( | ||||||
|  | 						EVENT_SYSTEM_FOREGROUND, | ||||||
|  | 						EVENT_SYSTEM_FOREGROUND, | ||||||
|  | 						NULL, | ||||||
|  | 						MyWinEventProc, | ||||||
|  | 						0, | ||||||
|  | 						0, | ||||||
|  | 						WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNPROCESS); | ||||||
|  |  | ||||||
| 					if (c_DwmCompositionEnabled) | 					SetTimer(c_Window, TIMER_SHOWDESKTOP, INTERVAL_SHOWDESKTOP, NULL); | ||||||
| 					{ |  | ||||||
| 						SetTimer(c_Window, TIMER_SHOWDESKTOP, INTERVAL_SHOWDESKTOP, NULL); |  | ||||||
| 					} |  | ||||||
| 				} | 				} | ||||||
| 				else | 				else | ||||||
| 				{ | 				{ | ||||||
| @@ -719,6 +890,15 @@ LRESULT CALLBACK CSystem::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP | |||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 			return 0; | 			return 0; | ||||||
|  |  | ||||||
|  | 		case TIMER_NETSTATS: | ||||||
|  | 			CMeasureNet::UpdateIFTable(); | ||||||
|  |  | ||||||
|  | 			// Statistics | ||||||
|  | 			CMeasureNet::UpdateStats(); | ||||||
|  | 			Rainmeter->WriteStats(false); | ||||||
|  |  | ||||||
|  | 			return 0; | ||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| @@ -728,6 +908,12 @@ LRESULT CALLBACK CSystem::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP | |||||||
| 		KillTimer(c_Window, TIMER_SHOWDESKTOP); | 		KillTimer(c_Window, TIMER_SHOWDESKTOP); | ||||||
| 		KillTimer(c_Window, TIMER_COMPOSITION); | 		KillTimer(c_Window, TIMER_COMPOSITION); | ||||||
|  |  | ||||||
|  | 		if (c_WinEventHook) | ||||||
|  | 		{ | ||||||
|  | 			UnhookWinEvent(c_WinEventHook); | ||||||
|  | 			c_WinEventHook = NULL; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		c_DwmCompositionEnabled = (DwmIsCompositionEnabled() == TRUE); | 		c_DwmCompositionEnabled = (DwmIsCompositionEnabled() == TRUE); | ||||||
|  |  | ||||||
| 		DesktopCompositionCheckCount = 0; | 		DesktopCompositionCheckCount = 0; | ||||||
|   | |||||||
| @@ -56,10 +56,14 @@ public: | |||||||
| 	static bool GetDwmCompositionEnabled() { return c_DwmCompositionEnabled; } | 	static bool GetDwmCompositionEnabled() { return c_DwmCompositionEnabled; } | ||||||
| 	static bool GetShowDesktop() { return c_ShowDesktop; } | 	static bool GetShowDesktop() { return c_ShowDesktop; } | ||||||
|  |  | ||||||
| 	static HWND GetShellDesktopWindow(); | 	static HWND GetShellDesktopWindow(bool findWorkerW = false); | ||||||
| 	static HWND GetWorkerW(); | 	static HWND GetWorkerW() { return GetShellDesktopWindow(true); } | ||||||
|  |  | ||||||
|  | 	static HWND GetHelperWindow() { return c_HelperWindow; } | ||||||
|  | 	static void PrepareHelperWindow(HWND WorkerW); | ||||||
|  |  | ||||||
| private: | private: | ||||||
|  | 	static void CALLBACK MyWinEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime); | ||||||
| 	static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); | 	static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); | ||||||
| 	static BOOL DwmIsCompositionEnabled(); | 	static BOOL DwmIsCompositionEnabled(); | ||||||
|  |  | ||||||
| @@ -67,9 +71,16 @@ private: | |||||||
| 	static void ClearMultiMonitorInfo() { c_Monitors.monitors.clear(); } | 	static void ClearMultiMonitorInfo() { c_Monitors.monitors.clear(); } | ||||||
| 	static void UpdateWorkareaInfo(); | 	static void UpdateWorkareaInfo(); | ||||||
|  |  | ||||||
|  | 	static HWND GetDefaultShellWindow(); | ||||||
| 	static void ChangeZPosInOrder(); | 	static void ChangeZPosInOrder(); | ||||||
|  |  | ||||||
|  | 	static void CheckDesktopState(HWND WorkerW); | ||||||
|  | 	static bool BelongToSameProcess(HWND hwndA, HWND hwndB); | ||||||
|  |  | ||||||
| 	static HWND c_Window; | 	static HWND c_Window; | ||||||
|  | 	static HWND c_HelperWindow; | ||||||
|  |  | ||||||
|  | 	static HWINEVENTHOOK c_WinEventHook; | ||||||
|  |  | ||||||
| 	static MULTIMONITOR_INFO c_Monitors;		// Multi-Monitor info | 	static MULTIMONITOR_INFO c_Monitors;		// Multi-Monitor info | ||||||
|  |  | ||||||
|   | |||||||
| @@ -77,6 +77,8 @@ CTrayWindow::CTrayWindow(HINSTANCE instance) | |||||||
| 	SetWindowLong(m_Window, GWL_USERDATA, magicDWord); | 	SetWindowLong(m_Window, GWL_USERDATA, magicDWord); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | 	SetWindowPos(m_Window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||||
|  |  | ||||||
| 	m_TrayPos = 0; | 	m_TrayPos = 0; | ||||||
| 	memset(m_TrayValues, 0, sizeof(double) * TRAYICON_SIZE); | 	memset(m_TrayValues, 0, sizeof(double) * TRAYICON_SIZE); | ||||||
| } | } | ||||||
| @@ -408,11 +410,7 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA | |||||||
| 			} | 			} | ||||||
| 			else if(wParam == ID_CONTEXT_REFRESH) | 			else if(wParam == ID_CONTEXT_REFRESH) | ||||||
| 			{ | 			{ | ||||||
| 				// Read skins and settings | 				PostMessage(tray->GetWindow(), WM_DELAYED_REFRESH_ALL, (WPARAM)NULL, (LPARAM)NULL); | ||||||
| 				Rainmeter->ReloadSettings(); |  | ||||||
|  |  | ||||||
| 				// Refresh all |  | ||||||
| 				RainmeterRefresh(tray->GetWindow(), NULL); |  | ||||||
| 			}  | 			}  | ||||||
| 			else if(wParam == ID_CONTEXT_SHOWLOGFILE) | 			else if(wParam == ID_CONTEXT_SHOWLOGFILE) | ||||||
| 			{ | 			{ | ||||||
| @@ -625,6 +623,14 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA | |||||||
| 		} | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
|  | 	case WM_DELAYED_REFRESH_ALL: | ||||||
|  | 		if (Rainmeter) | ||||||
|  | 		{ | ||||||
|  | 			// Refresh all | ||||||
|  | 			Rainmeter->RefreshAll(); | ||||||
|  | 		} | ||||||
|  | 		return 0; | ||||||
|  |  | ||||||
| 	case WM_DESTROY: | 	case WM_DESTROY: | ||||||
| 		if (Rainmeter->GetDummyLitestep()) PostQuitMessage(0); | 		if (Rainmeter->GetDummyLitestep()) PostQuitMessage(0); | ||||||
| 		break; | 		break; | ||||||
|   | |||||||
| @@ -24,6 +24,8 @@ | |||||||
| #include <windows.h> | #include <windows.h> | ||||||
| #include "Measure.h" | #include "Measure.h" | ||||||
|  |  | ||||||
|  | #define WM_DELAYED_REFRESH_ALL WM_APP + 0 | ||||||
|  |  | ||||||
| #define WM_NOTIFYICON WM_USER + 101 | #define WM_NOTIFYICON WM_USER + 101 | ||||||
| #define TRAYICON_SIZE 16 | #define TRAYICON_SIZE 16 | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 spx
					spx