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_TransitionUpdate = 100; | ||||
| 	m_ActiveTransition = false; | ||||
| 	m_HasNetMeasures = false; | ||||
| 	m_WindowHide = HIDEMODE_NONE; | ||||
| 	m_WindowStartHidden = false; | ||||
| 	m_SnapEdges = true; | ||||
| @@ -294,7 +295,7 @@ void CMeterWindow::IgnoreAeroPeek() | ||||
| ** This deletes everything and rebuilds the config again. | ||||
| ** | ||||
| */ | ||||
| void CMeterWindow::Refresh(bool init) | ||||
| void CMeterWindow::Refresh(bool init, bool all) | ||||
| { | ||||
| 	assert(m_Rainmeter != NULL); | ||||
|  | ||||
| @@ -316,13 +317,6 @@ void CMeterWindow::Refresh(bool init) | ||||
| 		KillTimer(m_Window, MOUSETIMER);	// 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(); | ||||
| 		for( ; i != m_Measures.end(); i++) | ||||
| 		{ | ||||
| @@ -348,6 +342,8 @@ void CMeterWindow::Refresh(bool init) | ||||
| 		m_FontCollection = NULL; | ||||
| 	} | ||||
|  | ||||
| 	ZPOSITION oldZPos = m_WindowZPosition; | ||||
|  | ||||
| 	//TODO: Should these be moved to a Reload command instead of hitting the disk on every refresh | ||||
| 	ReadConfig();	// Read the general settings  | ||||
| 	ReadSkin(); | ||||
| @@ -373,10 +369,7 @@ void CMeterWindow::Refresh(bool init) | ||||
| 		MapCoordsToScreen(m_ScreenX, m_ScreenY, m_WindowW, m_WindowH); | ||||
| 	} | ||||
|  | ||||
| 	ZPOSITION zPos = m_WindowZPosition; | ||||
| 	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; | ||||
| 	SetWindowPos(m_Window, NULL, m_ScreenX, m_ScreenY, m_WindowW, m_WindowH, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||
|  | ||||
| 	ScreenToWindow(); | ||||
|  | ||||
| @@ -393,7 +386,10 @@ void CMeterWindow::Refresh(bool init) | ||||
|  | ||||
| 	UpdateTransparency(m_AlphaValue, true); | ||||
|  | ||||
| 	ChangeZPos(m_WindowZPosition); | ||||
| 	if (init || all || oldZPos != m_WindowZPosition) | ||||
| 	{ | ||||
| 		ChangeZPos(m_WindowZPosition, init || all); | ||||
| 	} | ||||
|  | ||||
| 	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) | ||||
| { | ||||
| 	// 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); | ||||
|  | ||||
| 	ScreenToWindow(); | ||||
| @@ -501,7 +486,7 @@ void CMeterWindow::MoveWindow(int x, int y) | ||||
| ** Sets the window's z-position | ||||
| ** | ||||
| */ | ||||
| void CMeterWindow::ChangeZPos(ZPOSITION zPos) | ||||
| void CMeterWindow::ChangeZPos(ZPOSITION zPos, bool all) | ||||
| { | ||||
| 	if(!m_ChildWindow) | ||||
| 	{ | ||||
| @@ -517,104 +502,60 @@ void CMeterWindow::ChangeZPos(ZPOSITION zPos) | ||||
|  			break; | ||||
|  | ||||
| 		case ZPOSITION_ONBOTTOM: | ||||
| 			 winPos = HWND_BOTTOM; | ||||
| 			 break; | ||||
|  | ||||
| 		case ZPOSITION_ONDESKTOP: | ||||
| 			if (!m_NativeTransparency || !CSystem::GetDwmCompositionEnabled()) | ||||
| 			if (all) | ||||
| 			{ | ||||
| 				winPos = HWND_BOTTOM; | ||||
|  | ||||
| 				// Set the window's parent to progman, so it stays always on desktop | ||||
| 				HWND ProgmanHwnd = CSystem::GetShellDesktopWindow(); | ||||
|  | ||||
| 				if (ProgmanHwnd && (parent != ProgmanHwnd)) | ||||
| 				if (CSystem::GetShowDesktop()) | ||||
| 				{ | ||||
| 					m_PreventMoving = true;  // Prevent moving the window by SetParent | ||||
| 					SetParent(m_Window, ProgmanHwnd); | ||||
| 					// Insert after the tray window temporarily to keep order | ||||
| 					winPos = Rainmeter->GetTrayWindow()->GetWindow(); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					// Insert after the helper window | ||||
| 					winPos = CSystem::GetHelperWindow(); | ||||
| 				} | ||||
| 				//else | ||||
| 				//{ | ||||
| 				//	return;		// The window is already on desktop | ||||
| 				//} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				if (parent != GetDesktopWindow()) | ||||
| 				{ | ||||
| 					m_PreventMoving = true;  // Prevent moving the window by SetParent | ||||
| 					SetParent(m_Window, NULL); | ||||
| 				winPos = HWND_BOTTOM; | ||||
| 			} | ||||
| 			break; | ||||
|  | ||||
| 					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); | ||||
| 				} | ||||
|  | ||||
| 				if (CSystem::GetShowDesktop()) | ||||
| 				else | ||||
| 				{ | ||||
| 					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 | ||||
| 					if (WorkerW) | ||||
| 					HWND hwnd = CSystem::GetHelperWindow(); | ||||
| 					while (hwnd = ::GetNextWindow(hwnd, GW_HWNDPREV)) | ||||
| 					{ | ||||
| 						HWND hwnd = WorkerW; | ||||
| 						while (hwnd = ::GetNextWindow(hwnd, GW_HWNDPREV)) | ||||
| 						if (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) | ||||
| 						{ | ||||
| 							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]; | ||||
|  | ||||
| 								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; | ||||
| 								break; | ||||
| 							} | ||||
| 						} | ||||
| 					} | ||||
|  | ||||
| 					if (logging) | ||||
| 					{ | ||||
| 						DebugLog(L" %s: hwnd=0x%08X (WorkerW=0x%08X), hwndInsertAfter=HWND_TOPMOST - %s", | ||||
| 							m_SkinName.c_str(), m_Window, WorkerW, msg.c_str()); | ||||
| 					} | ||||
| 					return; | ||||
| 				} | ||||
| 				return; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				if (all) | ||||
| 				{ | ||||
| 					// Insert after the helper window | ||||
| 					winPos = CSystem::GetHelperWindow(); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| @@ -624,18 +565,7 @@ void CMeterWindow::ChangeZPos(ZPOSITION zPos) | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		if (zPos != ZPOSITION_ONDESKTOP && (parent != GetDesktopWindow())) | ||||
| 		{ | ||||
| 			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; | ||||
| 		SetWindowPos(m_Window, winPos, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -1762,6 +1692,8 @@ void CMeterWindow::ReadSkin() | ||||
|  | ||||
| 	// Create the meters and measures | ||||
|  | ||||
| 	m_HasNetMeasures = false; | ||||
|  | ||||
| 	// Get all the sections (i.e. different meters, measures and the other stuff) | ||||
| 	std::vector<std::wstring> arraySections = m_Parser.GetSections(); | ||||
|  | ||||
| @@ -1791,6 +1723,11 @@ void CMeterWindow::ReadSkin() | ||||
| 						m_Measures.push_back(measure); | ||||
|  | ||||
| 						m_Parser.AddMeasure(measure); | ||||
|  | ||||
| 						if (!m_HasNetMeasures && dynamic_cast<CMeasureNet*>((measure))) | ||||
| 						{ | ||||
| 							m_HasNetMeasures = true; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				catch (CError& error) | ||||
| @@ -2204,7 +2141,7 @@ void CMeterWindow::Update(bool nodraw) | ||||
| 	m_UpdateCounter++; | ||||
|  | ||||
| 	// Pre-updates | ||||
| 	CMeasureNet::UpdateIFTable(); | ||||
| 	if (m_HasNetMeasures) CMeasureNet::UpdateIFTable(); | ||||
| 	CMeasureCalc::UpdateVariableMap(*this); | ||||
|  | ||||
| 	// Update all measures | ||||
| @@ -2244,10 +2181,6 @@ void CMeterWindow::Update(bool nodraw) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Statistics | ||||
| 	CMeasureNet::UpdateStats(); | ||||
| 	Rainmeter->WriteStats(false); | ||||
|  | ||||
| 	if (!nodraw) | ||||
| 	{ | ||||
| 		if (m_DynamicWindowSize) | ||||
| @@ -3154,17 +3087,6 @@ LRESULT CMeterWindow::OnWindowPosChanging(WPARAM wParam, LPARAM 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)) | ||||
| 		{ | ||||
| 			// 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); | ||||
| 		} | ||||
|  | ||||
| 		// 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); | ||||
| @@ -3888,28 +3799,11 @@ LRESULT CMeterWindow::OnMove(WPARAM wParam, LPARAM lParam) | ||||
| 	m_ScreenX = (SHORT)LOWORD(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) | ||||
| 	{ | ||||
| 		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; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -134,11 +134,11 @@ public: | ||||
| 	void DisableMeasure(const WCHAR* name); | ||||
| 	void EnableMeasure(const WCHAR* name); | ||||
| 	void ToggleMeasure(const WCHAR* name); | ||||
| 	void Refresh(bool init); | ||||
| 	void Refresh(bool init, bool all = false); | ||||
| 	void Redraw(); | ||||
|  | ||||
| 	void MoveWindow(int x, int y); | ||||
| 	void ChangeZPos(ZPOSITION zPos); | ||||
| 	void ChangeZPos(ZPOSITION zPos, bool all = false); | ||||
| 	void FadeWindow(int from, int to); | ||||
| 	 | ||||
| 	Gdiplus::Bitmap* GetDoubleBuffer() { return m_DoubleBuffer; }; | ||||
| @@ -291,6 +291,7 @@ private: | ||||
| 	int m_WindowUpdate;							// Measure update frequency | ||||
| 	int m_TransitionUpdate;						// Transition redraw frequency | ||||
| 	bool m_ActiveTransition; | ||||
| 	bool m_HasNetMeasures; | ||||
| 	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_SavePosition;						// If true, the window's position is saved | ||||
|   | ||||
| @@ -245,55 +245,11 @@ 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++) | ||||
| 				{ | ||||
| 					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()); | ||||
| 					} | ||||
| 					((*iter).second)->RunBang(bang, argument.c_str()); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -448,6 +404,21 @@ void RainmeterRefresh(HWND, const char* arg) | ||||
| 	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 | ||||
| ** | ||||
| @@ -745,14 +716,16 @@ CRainmeter::~CRainmeter() | ||||
|  | ||||
| 	if (m_TrayWindow) delete m_TrayWindow; | ||||
|  | ||||
| 	CSystem::Finalize(); | ||||
|  | ||||
| 	CMeasureNet::UpdateIFTable(); | ||||
| 	CMeasureNet::UpdateStats(); | ||||
| 	WriteStats(true); | ||||
|  | ||||
| 	CMeasureNet::FinalizeNewApi(); | ||||
|  | ||||
| 	CMeterString::FreeFontCache(); | ||||
|  | ||||
| 	CSystem::Finalize(); | ||||
|  | ||||
| 	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); | ||||
|  | ||||
| 		AddBangCommand("!RainmeterRefresh", RainmeterRefresh); | ||||
| 		AddBangCommand("!RainmeterRefreshApp", RainmeterRefreshApp); | ||||
| 		AddBangCommand("!RainmeterRedraw", RainmeterRedraw); | ||||
| 		AddBangCommand("!RainmeterHide", RainmeterHide); | ||||
| 		AddBangCommand("!RainmeterShow", RainmeterShow); | ||||
| @@ -1040,57 +1014,16 @@ int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath) | ||||
| 		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 | ||||
| 	std::vector<std::pair<int, int> >::const_reverse_iterator iter = startup.rbegin(); | ||||
| 	for ( ; iter != startup.rend(); iter++) | ||||
| 	std::multimap<int, CONFIGORDER>::const_iterator iter = m_ConfigOrders.begin(); | ||||
| 	for ( ; iter != m_ConfigOrders.end(); 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); | ||||
| 		} | ||||
| 		ActivateConfig((*iter).second.id, (*iter).second.active - 1); | ||||
| 	} | ||||
|  | ||||
| 	//Clear order | ||||
| 	m_ConfigOrders.clear(); | ||||
|  | ||||
| 	return Result;	// Alles OK | ||||
| } | ||||
|  | ||||
| @@ -1488,6 +1421,72 @@ CMeterWindow* CRainmeter::GetMeterWindow(HWND hwnd) | ||||
| 	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 | ||||
| ** | ||||
| @@ -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); | ||||
|  | ||||
| 		RemoveBangCommand("!RainmeterRefresh"); | ||||
| 		RemoveBangCommand("!RainmeterRefreshApp"); | ||||
| 		RemoveBangCommand("!RainmeterRedraw"); | ||||
| 		RemoveBangCommand("!RainmeterHide"); | ||||
| 		RemoveBangCommand("!RainmeterShow"); | ||||
| @@ -1542,6 +1542,7 @@ void CRainmeter::ScanForConfigs(std::wstring& path) | ||||
| { | ||||
| 	m_ConfigStrings.clear(); | ||||
| 	m_ConfigMenu.clear(); | ||||
| 	m_ConfigOrders.clear(); | ||||
|  | ||||
| 	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) | ||||
| 	{ | ||||
| 		// Read skins and settings | ||||
| 		Rainmeter->ReloadSettings(); | ||||
| 		// Refresh all | ||||
| 		RainmeterRefresh(m_TrayWindow->GetWindow(), NULL); | ||||
|  | ||||
| 		// Refresh needs to be delayed since it crashes if done during Update() | ||||
| 		PostMessage(m_TrayWindow->GetWindow(), WM_DELAYED_REFRESH_ALL, (WPARAM)NULL, (LPARAM)NULL); | ||||
| 	} | ||||
| 	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()) | ||||
| 		{ | ||||
| 			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) | ||||
| //{ | ||||
| //	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::RefreshAll() | ||||
| { | ||||
| 	// Read skins and settings | ||||
| 	ReloadSettings(); | ||||
|  | ||||
| 	// Make the sending order by using LoadOrder | ||||
| 	std::multimap<int, CMeterWindow*> windows; | ||||
|  | ||||
| 	std::map<std::wstring, CMeterWindow*>::iterator iter = m_Meters.begin(); | ||||
| 	for (; iter != m_Meters.end(); iter++) | ||||
| 	{ | ||||
| 		if ((*iter).second) | ||||
| 		{ | ||||
| 			windows.insert(std::pair<int, CMeterWindow*>(GetLoadOrder((*iter).first), (*iter).second)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Prepare the helper window | ||||
| 	CSystem::PrepareHelperWindow(CSystem::GetWorkerW()); | ||||
|  | ||||
| 	// Refresh all | ||||
| 	std::multimap<int, CMeterWindow*>::const_iterator iter2 = windows.begin(); | ||||
| 	for ( ; iter2 != windows.end(); iter2++) | ||||
| 	{ | ||||
| 		if ((*iter2).second) | ||||
| 		{ | ||||
| 			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 | ||||
|   | ||||
| @@ -52,6 +52,7 @@ void RainmeterActivateConfig(HWND, const char* arg); | ||||
| void RainmeterDeactivateConfig(HWND, const char* arg); | ||||
| void RainmeterToggleConfig(HWND, const char* arg); | ||||
| void RainmeterRefresh(HWND, const char* arg); | ||||
| void RainmeterRefreshApp(HWND, const char* arg); | ||||
| void RainmeterRedraw(HWND, const char* arg); | ||||
| void RainmeterToggleMeasure(HWND, const char* arg); | ||||
| void RainmeterEnableMeasure(HWND, const char* arg); | ||||
| @@ -92,6 +93,13 @@ public: | ||||
| 		int active; | ||||
| 	}; | ||||
|  | ||||
| 	struct CONFIGORDER | ||||
| 	{ | ||||
| 		std::wstring config; | ||||
| 		int id; | ||||
| 		int active; | ||||
| 	}; | ||||
|  | ||||
| 	struct CONFIGMENU | ||||
| 	{ | ||||
| 		std::wstring name; | ||||
| @@ -115,6 +123,7 @@ public: | ||||
| 	CMeterWindow* GetMeterWindow(HWND hwnd); | ||||
| 	std::map<std::wstring, CMeterWindow*>& GetAllMeterWindows() { return m_Meters; }; | ||||
| 	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; }; | ||||
|  | ||||
| 	void ActivateConfig(int configIndex, int iniIndex); | ||||
| @@ -163,6 +172,8 @@ public: | ||||
| 	std::wstring ParseCommand(const WCHAR* command, CMeterWindow* meterWindow); | ||||
| 	void ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow); | ||||
|  | ||||
| 	void RefreshAll(); | ||||
|  | ||||
| 	void ClearDeleteLaterList(); | ||||
|  | ||||
| 	static PLATFORM IsNT(); | ||||
| @@ -175,8 +186,9 @@ private: | ||||
| 	void ScanForConfigs(std::wstring& path); | ||||
| 	void ScanForThemes(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); | ||||
| 	//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); | ||||
| @@ -193,6 +205,7 @@ private: | ||||
|  | ||||
| 	std::vector<CONFIG> m_ConfigStrings;	    // All configs found in the given folder | ||||
| 	std::vector<CONFIGMENU> m_ConfigMenu; | ||||
| 	std::multimap<int, CONFIGORDER> m_ConfigOrders; | ||||
| 	std::map<std::wstring, CMeterWindow*> m_Meters;			// The meter windows | ||||
| 	std::vector<std::wstring> m_Themes; | ||||
|  | ||||
|   | ||||
| @@ -20,22 +20,31 @@ | ||||
| #include "System.h" | ||||
| #include "Litestep.h" | ||||
| #include "Rainmeter.h" | ||||
| #include "MeasureNet.h" | ||||
| #include "Error.h" | ||||
|  | ||||
| #define DEBUG_VERBOSE  (0)  // Set 1 if you need verbose logging. | ||||
|  | ||||
| enum TIMER | ||||
| { | ||||
| 	TIMER_SHOWDESKTOP = 1, | ||||
| 	TIMER_COMPOSITION = 2 | ||||
| 	TIMER_COMPOSITION = 2, | ||||
| 	TIMER_NETSTATS    = 3 | ||||
| }; | ||||
| enum INTERVAL | ||||
| { | ||||
| 	INTERVAL_SHOWDESKTOP = 250, | ||||
| 	INTERVAL_COMPOSITION = 250 | ||||
| 	INTERVAL_COMPOSITION = 250, | ||||
| 	INTERVAL_NETSTATS    = 10000 | ||||
| }; | ||||
|  | ||||
| MULTIMONITOR_INFO CSystem::c_Monitors = { 0 }; | ||||
|  | ||||
| HWND CSystem::c_Window = NULL; | ||||
| HWND CSystem::c_HelperWindow = NULL; | ||||
|  | ||||
| HWINEVENTHOOK CSystem::c_WinEventHook = NULL; | ||||
|  | ||||
| bool CSystem::c_DwmCompositionEnabled = false; | ||||
| bool CSystem::c_ShowDesktop = false; | ||||
|  | ||||
| @@ -44,7 +53,7 @@ extern CRainmeter* Rainmeter; | ||||
| /* | ||||
| ** 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) | ||||
| @@ -59,7 +68,7 @@ void CSystem::Initialize(HINSTANCE instance) | ||||
| 	c_Window = CreateWindowEx( | ||||
| 		WS_EX_TOOLWINDOW, | ||||
| 		L"RainmeterSystemClass", | ||||
| 		NULL, | ||||
| 		L"SystemWindow", | ||||
| 		WS_POPUP, | ||||
| 		CW_USEDEFAULT, | ||||
| 		CW_USEDEFAULT, | ||||
| @@ -70,19 +79,43 @@ void CSystem::Initialize(HINSTANCE instance) | ||||
| 		instance, | ||||
| 		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 | ||||
| 	SetWindowLong(c_Window, GWL_USERDATA, magicDWord); | ||||
| 	SetWindowLong(c_HelperWindow, GWL_USERDATA, magicDWord); | ||||
| #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(); | ||||
|  | ||||
| 	c_DwmCompositionEnabled = (DwmIsCompositionEnabled() == TRUE); | ||||
| 	if (c_DwmCompositionEnabled) | ||||
| 	{ | ||||
| 		SetTimer(c_Window, TIMER_SHOWDESKTOP, INTERVAL_SHOWDESKTOP, NULL); | ||||
| 	} | ||||
|  | ||||
| 	c_WinEventHook = SetWinEventHook( | ||||
| 		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_COMPOSITION); | ||||
| 	KillTimer(c_Window, TIMER_NETSTATS); | ||||
|  | ||||
| 	if (c_WinEventHook) UnhookWinEvent(c_WinEventHook); | ||||
|  | ||||
| 	if (c_HelperWindow) DestroyWindow(c_HelperWindow); | ||||
| 	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 (!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) | ||||
| 	if (ShellW) | ||||
| 	{ | ||||
| 		HWND WorkerW = NULL; | ||||
| 		while (WorkerW = FindWindowEx(NULL, WorkerW, L"WorkerW", L"")) | ||||
| 		HWND hwnd = NULL; | ||||
| 		while (hwnd = FindWindowEx(NULL, hwnd, L"Progman", NULL)) | ||||
| 		{ | ||||
| 			if ((hwnd = FindWindowEx(WorkerW, NULL, L"SHELLDLL_DefView", L"")) && | ||||
| 				(DesktopW = FindWindowEx(hwnd, NULL, L"SysListView32", L"FolderView"))) break; | ||||
| 			if (hwnd == ShellW) return ShellW; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return DesktopW; | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| /* | ||||
| ** GetWorkerW | ||||
| ** GetShellDesktopWindow | ||||
| ** | ||||
| ** Finds the WorkerW window. | ||||
| ** If the Progman or WorkerW window is not found, this function returns NULL. | ||||
| ** Finds the Shell's desktop window or WorkerW window. | ||||
| ** 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. | ||||
| ** | ||||
| ** In Windows 7 (with Aero): | ||||
| ** 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"); | ||||
| 	if (!hwnd) return NULL;  // Default Shell (Explorer) not started | ||||
| 	HWND ShellW = GetDefaultShellWindow(); | ||||
| 	if (!ShellW) return NULL;  // Default Shell (Explorer) not running | ||||
|  | ||||
| 	if ((hwnd = FindWindowEx(hwnd, NULL, L"SHELLDLL_DefView", L"")) && | ||||
| 		(hwnd = FindWindowEx(hwnd, NULL, L"SysListView32", L"FolderView")))  // for Windows Vista / 7 (without Aero) | ||||
| 	if ((hwnd = FindWindowEx(ShellW, NULL, L"SHELLDLL_DefView", L"")) && | ||||
| 		(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 | ||||
| 				WINDOWPLACEMENT wp = {sizeof(WINDOWPLACEMENT)}; | ||||
| 				GetWindowPlacement(WorkerW, &wp); | ||||
| 				if (IsWindowVisible(WorkerW) && BelongToSameProcess(ShellW, 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; | ||||
| 					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) | ||||
| 					{ | ||||
| 						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"")) | ||||
| 		{ | ||||
| 			if ((hwnd = FindWindowEx(WorkerW, NULL, L"SHELLDLL_DefView", L"")) && | ||||
| 				FindWindowEx(hwnd, NULL, L"SysListView32", L"FolderView")) break; | ||||
| 			if (BelongToSameProcess(ShellW, WorkerW)) | ||||
| 			{ | ||||
| 				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 | ||||
| ** | ||||
| ** 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 logging = false;  // Set true if you need verbose logging. | ||||
| 	bool logging = CRainmeter::GetDebug() && DEBUG_VERBOSE; | ||||
| 	WCHAR className[128] = {0}; | ||||
| 	CMeterWindow* Window; | ||||
|  | ||||
| 	if (GetClassName(hwnd, className, 128) > 0 && | ||||
| 		wcscmp(className, L"RainmeterMeterWindow") == 0 && | ||||
| 		Rainmeter && | ||||
| 		(Window = Rainmeter->GetMeterWindow(hwnd))) | ||||
| 		Rainmeter && (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) | ||||
| 			{ | ||||
| @@ -595,7 +673,7 @@ BOOL CALLBACK MyEnumWindowsProc(HWND hwnd, LPARAM lParam) | ||||
| 		} | ||||
| 		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 | ||||
| @@ -616,42 +694,146 @@ void CSystem::ChangeZPosInOrder() | ||||
| { | ||||
| 	if (Rainmeter) | ||||
| 	{ | ||||
| 		bool logging = false;  // Set true if you need verbose logging. | ||||
| 		bool logging = CRainmeter::GetDebug() && DEBUG_VERBOSE; | ||||
| 		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 | ||||
| 		if (logging) LSLog(LOG_DEBUG, L"Rainmeter", L" [Top-level window]"); | ||||
| 		// Retrieve the Rainmeter's meter windows in Z-order | ||||
| 		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 | ||||
| 			windowsInZOrder[i]->ChangeZPos(windowsInZOrder[i]->GetWindowZPosition());  // reset | ||||
| 		} | ||||
|  | ||||
| 		if (logging) | ||||
| 		{ | ||||
| 			LSLog(LOG_DEBUG, L"Rainmeter", L"3: -----"); | ||||
| 			LSLog(LOG_DEBUG, L"Rainmeter", L" [Top-level window]"); | ||||
| 			LSLog(LOG_DEBUG, L"Rainmeter", L"2: ----- AFTER -----"); | ||||
|  | ||||
| 			// Log all windows in Z-order | ||||
| 			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]"); | ||||
| 				EnumChildWindows(DesktopW, MyEnumWindowsProc, (LPARAM)NULL); | ||||
| 				WCHAR className[128], windowText[128]; | ||||
|  | ||||
| 				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; | ||||
|  | ||||
| 	if (uMsg == WM_CREATE || hWnd != c_Window) | ||||
| 	{ | ||||
| 		return DefWindowProc(hWnd, uMsg, wParam, lParam); | ||||
| 	} | ||||
|  | ||||
| 	switch (uMsg) | ||||
| 	{ | ||||
| 	case WM_WINDOWPOSCHANGING: | ||||
| @@ -677,27 +864,7 @@ LRESULT CALLBACK CSystem::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP | ||||
| 		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(); | ||||
| 				} | ||||
| 			} | ||||
| 			CheckDesktopState(GetWorkerW()); | ||||
| 			return 0; | ||||
|  | ||||
| 		case TIMER_COMPOSITION: | ||||
| @@ -706,12 +873,16 @@ LRESULT CALLBACK CSystem::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP | ||||
| 				{ | ||||
| 					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 | ||||
| 				{ | ||||
| @@ -719,6 +890,15 @@ LRESULT CALLBACK CSystem::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP | ||||
| 				} | ||||
| 			} | ||||
| 			return 0; | ||||
|  | ||||
| 		case TIMER_NETSTATS: | ||||
| 			CMeasureNet::UpdateIFTable(); | ||||
|  | ||||
| 			// Statistics | ||||
| 			CMeasureNet::UpdateStats(); | ||||
| 			Rainmeter->WriteStats(false); | ||||
|  | ||||
| 			return 0; | ||||
| 		} | ||||
| 		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_COMPOSITION); | ||||
|  | ||||
| 		if (c_WinEventHook) | ||||
| 		{ | ||||
| 			UnhookWinEvent(c_WinEventHook); | ||||
| 			c_WinEventHook = NULL; | ||||
| 		} | ||||
|  | ||||
| 		c_DwmCompositionEnabled = (DwmIsCompositionEnabled() == TRUE); | ||||
|  | ||||
| 		DesktopCompositionCheckCount = 0; | ||||
|   | ||||
| @@ -56,10 +56,14 @@ public: | ||||
| 	static bool GetDwmCompositionEnabled() { return c_DwmCompositionEnabled; } | ||||
| 	static bool GetShowDesktop() { return c_ShowDesktop; } | ||||
|  | ||||
| 	static HWND GetShellDesktopWindow(); | ||||
| 	static HWND GetWorkerW(); | ||||
| 	static HWND GetShellDesktopWindow(bool findWorkerW = false); | ||||
| 	static HWND GetWorkerW() { return GetShellDesktopWindow(true); } | ||||
|  | ||||
| 	static HWND GetHelperWindow() { return c_HelperWindow; } | ||||
| 	static void PrepareHelperWindow(HWND WorkerW); | ||||
|  | ||||
| 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 BOOL DwmIsCompositionEnabled(); | ||||
|  | ||||
| @@ -67,9 +71,16 @@ private: | ||||
| 	static void ClearMultiMonitorInfo() { c_Monitors.monitors.clear(); } | ||||
| 	static void UpdateWorkareaInfo(); | ||||
|  | ||||
| 	static HWND GetDefaultShellWindow(); | ||||
| 	static void ChangeZPosInOrder(); | ||||
|  | ||||
| 	static void CheckDesktopState(HWND WorkerW); | ||||
| 	static bool BelongToSameProcess(HWND hwndA, HWND hwndB); | ||||
|  | ||||
| 	static HWND c_Window; | ||||
| 	static HWND c_HelperWindow; | ||||
|  | ||||
| 	static HWINEVENTHOOK c_WinEventHook; | ||||
|  | ||||
| 	static MULTIMONITOR_INFO c_Monitors;		// Multi-Monitor info | ||||
|  | ||||
|   | ||||
| @@ -77,6 +77,8 @@ CTrayWindow::CTrayWindow(HINSTANCE instance) | ||||
| 	SetWindowLong(m_Window, GWL_USERDATA, magicDWord); | ||||
| #endif | ||||
|  | ||||
| 	SetWindowPos(m_Window, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING); | ||||
|  | ||||
| 	m_TrayPos = 0; | ||||
| 	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) | ||||
| 			{ | ||||
| 				// Read skins and settings | ||||
| 				Rainmeter->ReloadSettings(); | ||||
|  | ||||
| 				// Refresh all | ||||
| 				RainmeterRefresh(tray->GetWindow(), NULL); | ||||
| 				PostMessage(tray->GetWindow(), WM_DELAYED_REFRESH_ALL, (WPARAM)NULL, (LPARAM)NULL); | ||||
| 			}  | ||||
| 			else if(wParam == ID_CONTEXT_SHOWLOGFILE) | ||||
| 			{ | ||||
| @@ -625,6 +623,14 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA | ||||
| 		} | ||||
| 		break; | ||||
|  | ||||
| 	case WM_DELAYED_REFRESH_ALL: | ||||
| 		if (Rainmeter) | ||||
| 		{ | ||||
| 			// Refresh all | ||||
| 			Rainmeter->RefreshAll(); | ||||
| 		} | ||||
| 		return 0; | ||||
|  | ||||
| 	case WM_DESTROY: | ||||
| 		if (Rainmeter->GetDummyLitestep()) PostQuitMessage(0); | ||||
| 		break; | ||||
|   | ||||
| @@ -24,6 +24,8 @@ | ||||
| #include <windows.h> | ||||
| #include "Measure.h" | ||||
|  | ||||
| #define WM_DELAYED_REFRESH_ALL WM_APP + 0 | ||||
|  | ||||
| #define WM_NOTIFYICON WM_USER + 101 | ||||
| #define TRAYICON_SIZE 16 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 spx
					spx