From c7286881ee6d3078eef25d0ddf29cb4b023059ad Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Sat, 6 Oct 2012 20:12:40 +0300 Subject: [PATCH] Added !LoadLayout --- Library/Rainmeter.cpp | 100 ++++++++++++++++++++++++-------- Library/Rainmeter.h | 5 +- SkinInstaller/Application.cpp | 28 +++++---- SkinInstaller/DialogInstall.cpp | 70 +++------------------- SkinInstaller/DialogInstall.h | 2 - 5 files changed, 101 insertions(+), 104 deletions(-) diff --git a/Library/Rainmeter.cpp b/Library/Rainmeter.cpp index 33a332e8..9ce46bee 100644 --- a/Library/Rainmeter.cpp +++ b/Library/Rainmeter.cpp @@ -50,6 +50,11 @@ CRainmeter* Rainmeter; // The module */ int RainmeterMain(LPWSTR cmdLine) { + // Avoid loading a dll from current directory + SetDllDirectory(L""); + + const WCHAR* layout = NULL; + if (cmdLine[0] == L'!' || cmdLine[0] == L'[') { HWND wnd = FindWindow(RAINMETER_CLASS_NAME, RAINMETER_WINDOW_NAME); @@ -64,7 +69,15 @@ int RainmeterMain(LPWSTR cmdLine) return 0; } - return 1; + // Disallow everything except !LoadLayout. + if (_wcsnicmp(cmdLine, L"!LoadLayout ", 11) == 0) + { + layout = cmdLine + 11; // Skip "!LoadLayout ". + } + else + { + return 1; + } } else if (cmdLine[0] == L'"') { @@ -77,13 +90,10 @@ int RainmeterMain(LPWSTR cmdLine) } } - // Avoid loading a dll from current directory - SetDllDirectory(L""); - - int ret = 1; + const WCHAR* iniFile = (*cmdLine && !layout) ? cmdLine : NULL; Rainmeter = new CRainmeter; - ret = Rainmeter->Initialize(cmdLine); + int ret = Rainmeter->Initialize(iniFile, layout); if (ret == 0) { ret = Rainmeter->MessagePump(); @@ -394,6 +404,30 @@ void CRainmeter::Bang_DeactivateSkinGroup(std::vector& args) } } +/* +** !LoadLayout bang +** +*/ +void CRainmeter::Bang_LoadLayout(std::vector& args, CMeterWindow* meterWindow) +{ + if (args.size() == 1) + { + if (meterWindow) + { + // Delay to avoid loading theme in the middle of an update. + std::wstring command = L"!LoadLayout \""; + command += args[0]; + command += L'"'; + Rainmeter->DelayedExecuteCommand(command.c_str()); + } + else + { + // Not called from a skin (or called with delay). + LoadLayout(args[0]); + } + } +} + /* ** !SetClip bang ** @@ -728,7 +762,7 @@ CRainmeter::~CRainmeter() ** The main initialization function for the module. ** */ -int CRainmeter::Initialize(LPCWSTR iniPath) +int CRainmeter::Initialize(LPCWSTR iniPath, LPCWSTR layout) { InitalizeLitestep(); @@ -742,7 +776,7 @@ int CRainmeter::Initialize(LPCWSTR iniPath) m_Path.assign(buffer, pos ? pos - buffer + 1 : 0); bool bDefaultIniLocation = false; - if (*iniPath) + if (iniPath) { // The command line defines the location of Rainmeter.ini (or whatever it calls it). std::wstring iniFile = iniPath; @@ -988,8 +1022,17 @@ int CRainmeter::Initialize(LPCWSTR iniPath) UpdateDesktopWorkArea(false); } - // Create meter windows for active skins - ActivateActiveSkins(); + bool layoutLoaded = false; + if (layout) + { + std::vector args = ParseString(layout); + layoutLoaded = (args.size() == 1 && LoadLayout(args[0])); + } + + if (!layoutLoaded) + { + ActivateActiveSkins(); + } if (dataFileCreated) { @@ -2138,6 +2181,10 @@ void CRainmeter::ExecuteBang(const WCHAR* bang, std::vector& args, { BangWithArgs(BANG_PLUGIN, args, 1, meterWindow); } + else if (_wcsicmp(bang, L"LoadLayout") == 0) + { + Bang_LoadLayout(args, meterWindow); + } else if (_wcsicmp(bang, L"SetClip") == 0) { Bang_SetClip(args); @@ -2530,8 +2577,19 @@ void CRainmeter::RefreshAll() CDialogManage::UpdateSkins(NULL); } -void CRainmeter::LoadLayout(const std::wstring& name) +bool CRainmeter::LoadLayout(const std::wstring& name) { + // Replace Rainmeter.ini with layout + std::wstring layout = GetLayoutPath(); + layout += name; + std::wstring wallpaper = layout + L"\\Wallpaper.bmp"; + layout += L"\\Rainmeter.ini"; + + if (_waccess(layout.c_str(), 0) == -1) + { + return false; + } + // Delete all meter windows DeleteMeterWindow(NULL); @@ -2540,23 +2598,17 @@ void CRainmeter::LoadLayout(const std::wstring& name) CreateDirectory(backup.c_str(), NULL); backup += L"\\Rainmeter.ini"; - if (_wcsicmp(name.c_str(), L"@Backup") == 0) - { - // Just load the backup - CSystem::CopyFiles(backup, m_IniFile); - } - else + bool backupLayout = (_wcsicmp(name.c_str(), L"@Backup") == 0); + if (!backupLayout) { // Make a copy of current Rainmeter.ini CSystem::CopyFiles(m_IniFile, backup); + } - // Replace Rainmeter.ini with layout - std::wstring layout = GetLayoutPath(); - layout += name; - std::wstring wallpaper = layout + L"\\Wallpaper.bmp"; - layout += L"\\Rainmeter.ini"; - CSystem::CopyFiles(layout, GetIniFile()); + CSystem::CopyFiles(layout, m_IniFile); + if (!backupLayout) + { PreserveSetting(backup, L"SkinPath"); PreserveSetting(backup, L"ConfigEditor"); PreserveSetting(backup, L"LogViewer"); @@ -2580,6 +2632,8 @@ void CRainmeter::LoadLayout(const std::wstring& name) // Create meter windows for active skins ActivateActiveSkins(); + + return true; } void CRainmeter::PreserveSetting(const std::wstring& from, LPCTSTR key, bool replace) diff --git a/Library/Rainmeter.h b/Library/Rainmeter.h index 02bb0217..65b2e9ca 100644 --- a/Library/Rainmeter.h +++ b/Library/Rainmeter.h @@ -99,7 +99,7 @@ public: CRainmeter(); ~CRainmeter(); - int Initialize(LPCWSTR iniPath); + int Initialize(LPCWSTR iniPath, LPCWSTR layout); bool IsAlreadyRunning(); int MessagePump(); @@ -215,7 +215,7 @@ public: void RefreshAll(); - void LoadLayout(const std::wstring& name); + bool LoadLayout(const std::wstring& name); void PreserveSetting(const std::wstring& from, LPCTSTR key, bool replace = true); static std::vector ParseString(LPCTSTR str, CConfigParser* parser = NULL); @@ -233,6 +233,7 @@ private: void Bang_DeactivateSkin(std::vector& args, CMeterWindow* meterWindow); void Bang_ToggleSkin(std::vector& args); void Bang_DeactivateSkinGroup(std::vector& args); + void Bang_LoadLayout(std::vector& args, CMeterWindow* meterWindow); void Bang_SetClip(std::vector& args); void Bang_SetWallpaper(std::vector& args, CMeterWindow* meterWindow); void Bang_SkinMenu(std::vector& args, CMeterWindow* meterWindow); diff --git a/SkinInstaller/Application.cpp b/SkinInstaller/Application.cpp index c8870480..d56eb93a 100644 --- a/SkinInstaller/Application.cpp +++ b/SkinInstaller/Application.cpp @@ -120,22 +120,20 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi if (_wcsnicmp(lpCmdLine, L"/LoadTheme ", 11) == 0) { - // Skip "/LoadTheme " - lpCmdLine += 11; + // For backwards compatibility. + std::wstring args = L"!LoadLayout \""; + args += &lpCmdLine[11]; // Skip "/LoadTheme ". + args += L'"'; - if (*lpCmdLine && CloseRainmeterIfActive()) - { - CDialogInstall::LoadLayout(lpCmdLine, true); - - std::wstring file = g_Data.programPath + L"Rainmeter.exe"; - SHELLEXECUTEINFO sei = {0}; - sei.cbSize = sizeof(SHELLEXECUTEINFO); - sei.fMask = SEE_MASK_UNICODE; - sei.lpFile = file.c_str(); - sei.lpDirectory = g_Data.programPath.c_str(); - sei.nShow = SW_SHOWNORMAL; - ShellExecuteEx(&sei); - } + std::wstring file = g_Data.programPath + L"Rainmeter.exe"; + SHELLEXECUTEINFO sei = {0}; + sei.cbSize = sizeof(SHELLEXECUTEINFO); + sei.fMask = SEE_MASK_UNICODE; + sei.lpFile = file.c_str(); + sei.lpParameters = args.c_str(); + sei.lpDirectory = g_Data.programPath.c_str(); + sei.nShow = SW_SHOWNORMAL; + ShellExecuteEx(&sei); return 0; } diff --git a/SkinInstaller/DialogInstall.cpp b/SkinInstaller/DialogInstall.cpp index 2a0391f9..1689f3bd 100644 --- a/SkinInstaller/DialogInstall.cpp +++ b/SkinInstaller/DialogInstall.cpp @@ -1054,78 +1054,24 @@ void CDialogInstall::KeepVariables() } } -void CDialogInstall::LoadLayout(const std::wstring& name, bool setWallpaper) -{ - // Take a copy of current Rainmeter.ini before doing anything - std::wstring backupFile = g_Data.settingsPath; - backupFile += L"Layouts\\@Backup\\"; - CreateDirectory(backupFile.c_str(), NULL); - backupFile += L"Rainmeter.ini"; - CopyFiles(g_Data.iniFile, backupFile, false); - - if (name.empty()) - { - return; - } - - std::wstring layoutFile = g_Data.settingsPath; - layoutFile += L"Layouts\\"; - layoutFile += name; - std::wstring wallpaperFile = layoutFile + L"\\Wallpaper.bmp"; - layoutFile += L"\\Rainmeter.ini"; - if (_waccess(layoutFile.c_str(), 0) != -1) - { - CopyFiles(layoutFile, g_Data.iniFile, false); - - const WCHAR* iniFileSz = g_Data.iniFile.c_str(); - const WCHAR* backupFileSz = backupFile.c_str(); - - auto preserveOption = [&](LPCTSTR section, LPCTSTR key) - { - WCHAR buffer[MAX_LINE_LENGTH]; - if (GetPrivateProfileString(section, key, L"", buffer, MAX_LINE_LENGTH, iniFileSz) == 0 && - GetPrivateProfileString(section, key, L"", buffer, MAX_LINE_LENGTH, backupFileSz) > 0) - { - WritePrivateProfileString(section, key, buffer, iniFileSz); - } - }; - - preserveOption(L"Rainmeter", L"SkinPath"); - preserveOption(L"Rainmeter", L"ConfigEditor"); - preserveOption(L"Rainmeter", L"LogViewer"); - preserveOption(L"Rainmeter", L"Logging"); - preserveOption(L"Rainmeter", L"DisableVersionCheck"); - preserveOption(L"Rainmeter", L"Language"); - preserveOption(L"Rainmeter", L"TrayExecuteM"); - preserveOption(L"Rainmeter", L"TrayExecuteR"); - preserveOption(L"Rainmeter", L"TrayExecuteDM"); - preserveOption(L"Rainmeter", L"TrayExecuteDR"); - - // Set wallpaper if it exists - const WCHAR* wallpaperFileSz = wallpaperFile.c_str(); - if (_waccess(wallpaperFileSz, 0) != -1) - { - SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)wallpaperFileSz, SPIF_UPDATEINIFILE); - } - } -} - void CDialogInstall::LaunchRainmeter() { - // Backup Rainmeter.ini and load layout (if specified) - LoadLayout(m_LoadLayout, false); - // Execute Rainmeter and wait up to a minute for it process all messages std::wstring rainmeterExe = g_Data.programPath + L"Rainmeter.exe"; + std::wstring args; + if (!m_LoadLayout.empty()) + { + args += L"!LoadLayout \""; + args += m_LoadLayout; + args += L'"'; + } SHELLEXECUTEINFO sei = {0}; sei.cbSize = sizeof(SHELLEXECUTEINFO); sei.fMask = SEE_MASK_WAITFORINPUTIDLE | SEE_MASK_UNICODE; - sei.hwnd = NULL; - sei.lpVerb = NULL; sei.lpFile = rainmeterExe.c_str(); + sei.lpParameters = args.c_str(); sei.lpDirectory = g_Data.programPath.c_str(); - sei.lpParameters = NULL; sei.nShow = SW_SHOWNORMAL; ShellExecuteEx(&sei); diff --git a/SkinInstaller/DialogInstall.h b/SkinInstaller/DialogInstall.h index 20fc6263..869a5273 100644 --- a/SkinInstaller/DialogInstall.h +++ b/SkinInstaller/DialogInstall.h @@ -33,8 +33,6 @@ public: INT_PTR OnCommand(WPARAM wParam, LPARAM lParam); INT_PTR OnNotify(WPARAM wParam, LPARAM lParam); - static void LoadLayout(const std::wstring& name, bool setWallpaper); - static CDialogInstall* c_Dialog; protected: