- 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:
spx 2010-03-29 21:50:05 +00:00
parent 24b87eab16
commit b769a7a360
8 changed files with 527 additions and 401 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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