diff --git a/Application/Application.vcxproj b/Application/Application.vcxproj index 6b6adec9..60140a30 100644 --- a/Application/Application.vcxproj +++ b/Application/Application.vcxproj @@ -67,10 +67,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\ .\x32\$(Configuration)\ false diff --git a/Library/DialogAbout.cpp b/Library/DialogAbout.cpp index 3b60a9b5..d2c0d5ac 100644 --- a/Library/DialogAbout.cpp +++ b/Library/DialogAbout.cpp @@ -869,13 +869,66 @@ void CDialogAbout::CTabPlugins::Initialize() // Try to get the version and author std::wstring tmpSz = Rainmeter->GetPluginPath() + fileData.cFileName; + const WCHAR* path = tmpSz.c_str(); + + vitem.iItem = index; + vitem.pszText = fileData.cFileName; + + // Try to get version and author from file resources first + DWORD handle; + DWORD versionSize = GetFileVersionInfoSize(path, &handle); + if (versionSize) + { + bool found = false; + void* data = new BYTE[versionSize]; + if (GetFileVersionInfo(path, 0, versionSize, data)) + { + UINT len; + struct LANGCODEPAGE + { + WORD wLanguage; + WORD wCodePage; + } *lcp; + + if (VerQueryValue(data, L"\\VarFileInfo\\Translation", (LPVOID*)&lcp, &len)) + { + WCHAR key[64]; + LPWSTR value; + + _snwprintf_s(key, _TRUNCATE, L"\\StringFileInfo\\%04x%04x\\ProductName", lcp[0].wLanguage, lcp[0].wCodePage); + if (VerQueryValue(data, (LPTSTR)(LPCTSTR)key, (void**)&value, &len) && + wcscmp(value, L"Rainmeter") == 0) + { + ListView_InsertItem(item, &vitem); + ++index; + found = true; + + _snwprintf_s(key, _TRUNCATE, L"\\StringFileInfo\\%04x%04x\\FileVersion", lcp[0].wLanguage, lcp[0].wCodePage); + if (VerQueryValue(data, (LPTSTR)(LPCTSTR)key, (void**)&value, &len)) + { + ListView_SetItemText(item, vitem.iItem, 1, value); + } + + _snwprintf_s(key, _TRUNCATE, L"\\StringFileInfo\\%04x%04x\\LegalCopyright", lcp[0].wLanguage, lcp[0].wCodePage); + if (VerQueryValue(data, (LPTSTR)(LPCTSTR)key, (void**)&value, &len)) + { + ListView_SetItemText(item, vitem.iItem, 2, value); + } + } + } + } + + delete [] data; + if (found) continue; + } + + // Try old calling GetPluginVersion/GetPluginAuthor for backwards compatibility DWORD err = 0; - HMODULE dll = CSystem::RmLoadLibrary(tmpSz.c_str(), &err, true); + HMODULE dll = CSystem::RmLoadLibrary(path, &err, true); if (dll) { - vitem.iItem = index; - vitem.pszText = fileData.cFileName; ListView_InsertItem(item, &vitem); + ++index; GETPLUGINVERSION GetVersionFunc = (GETPLUGINVERSION)GetProcAddress(dll, "GetPluginVersion"); if (GetVersionFunc) @@ -896,7 +949,6 @@ void CDialogAbout::CTabPlugins::Initialize() } } - ++index; FreeLibrary(dll); } else diff --git a/Library/Export.cpp b/Library/Export.cpp new file mode 100644 index 00000000..0adae28c --- /dev/null +++ b/Library/Export.cpp @@ -0,0 +1,248 @@ +/* + Copyright (C) 2011 Birunthan Mohanathas, Peter Souza + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "StdAfx.h" +#include "Rainmeter.h" +#include "Export.h" +#include "MeterWindow.h" +#include "Measure.h" +#include "MeasurePlugin.h" + +#define NULLCHECK(str) { if ((str) == NULL) { (str) = L""; } } + +extern CRainmeter* Rainmeter; + +static std::wstring g_Buffer; + +LPCWSTR RmReadString(void* rm, LPCWSTR option, LPCWSTR defValue, BOOL replaceMeasures) +{ + NULLCHECK(option); + NULLCHECK(defValue); + + CMeasurePlugin* measure = (CMeasurePlugin*)rm; + CConfigParser& parser = measure->GetMeterWindow()->GetParser(); + return parser.ReadString(measure->GetName(), option, defValue, (bool)replaceMeasures).c_str(); +} + +double RmReadFormula(void* rm, LPCWSTR option, double defValue) +{ + NULLCHECK(option); + + CMeasurePlugin* measure = (CMeasurePlugin*)rm; + CConfigParser& parser = measure->GetMeterWindow()->GetParser(); + return parser.ReadFormula(measure->GetName(), option, defValue); +} + +LPCWSTR RmPathToAbsolute(void* rm, LPCWSTR relativePath) +{ + NULLCHECK(relativePath); + + CMeasurePlugin* measure = (CMeasurePlugin*)rm; + g_Buffer = relativePath; + measure->GetMeterWindow()->MakePathAbsolute(g_Buffer); + return g_Buffer.c_str(); +} + +void* RmGet(void* rm, int type) +{ + CMeasurePlugin* measure = (CMeasurePlugin*)rm; + + switch (type) + { + case RMG_MEASURENAME: + { + return (void*)measure->GetName(); + } + + case RMG_SKIN: + { + return (void*)measure->GetMeterWindow(); + } + + case RMG_SETTINGSFILE: + { + g_Buffer = Rainmeter->GetSettingsPath(); + g_Buffer += L"Plugins.ini"; + return (void*)g_Buffer.c_str(); + } + } + + return NULL; +} + +void RmExecute(void* skin, LPCWSTR command) +{ + CMeterWindow* mw = (CMeterWindow*)skin; + + // Fake WM_COPYDATA message to deliver bang + COPYDATASTRUCT cds; + cds.cbData = 1; + cds.dwData = 1; + cds.lpData = (void*)command; + mw->OnCopyData(WM_COPYDATA, NULL, (LPARAM)&cds); +} + +BOOL LSLog(int nLevel, LPCWSTR unused, LPCWSTR pszMessage) +{ + NULLCHECK(pszMessage); + + // Ignore LOG_DEBUG messages from plugins unless in debug mode + if (nLevel != LOG_DEBUG || Rainmeter->GetDebug()) + { + Log(nLevel, pszMessage); + } + + return TRUE; +} + +// Deprecated! +LPCWSTR ReadConfigString(LPCWSTR section, LPCWSTR option, LPCWSTR defValue) +{ + NULLCHECK(section); + NULLCHECK(option); + NULLCHECK(defValue); + + CConfigParser* parser = Rainmeter->GetCurrentParser(); + if (parser) + { + return parser->ReadString(section, option, defValue, false).c_str(); + } + + return defValue; +} + +// Deprecated! +LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData) +{ + if (_sCommand == NULL || *_sCommand == L'\0') + { + return L"noop"; + } + + NULLCHECK(_sData); + + std::wstring sCommand = _sCommand; + std::transform(sCommand.begin(), sCommand.end(), sCommand.begin(), ::towlower); + + // Command GetConfig + // Data unquoted full path and filename given to the plugin on initialize + // (note: this is CaSe-SeNsItIvE!) + // Execution none + // Result the config name if found or a blank string if not + if (sCommand == L"getconfig") + { + // returns the config name, lookup by INI file + + CMeterWindow *meterWindow = Rainmeter->GetMeterWindowByINI(_sData); + if (meterWindow) + { + g_Buffer = L"\""; + g_Buffer += meterWindow->GetSkinName(); + g_Buffer += L"\""; + return g_Buffer.c_str(); + } + + return L""; + } + + // Command GetWindow + // Data [the config name] + // Execution none + // Result the HWND to the specified config window if found, 'error' otherwise + if (sCommand == L"getwindow") + { + std::vector subStrings = CRainmeter::ParseString(_sData); + + if (subStrings.size() >= 1) + { + const std::wstring& config = subStrings[0]; + + CMeterWindow *meterWindow = Rainmeter->GetMeterWindow(config); + if (meterWindow) + { + WCHAR buf1[64]; + _snwprintf_s(buf1, _TRUNCATE, L"%lu", PtrToUlong(meterWindow->GetWindow())); + g_Buffer = buf1; + return g_Buffer.c_str(); + } + } + + return L"error"; + } + + // Command GetVariable + // Data [the config name] + // Execution none + // Result the value of the variable + if (sCommand == L"getvariable") + { + std::vector subStrings = CRainmeter::ParseString(_sData); + + if (subStrings.size() >= 2) + { + const std::wstring& config = subStrings[0]; + + CMeterWindow *meterWindow = Rainmeter->GetMeterWindow(config); + if (meterWindow) + { + const std::wstring& variable = subStrings[1]; + std::wstring result_from_parser; + + if (meterWindow->GetParser().GetVariable(variable, result_from_parser)) + { + g_Buffer = result_from_parser; + return g_Buffer.c_str(); + } + } + } + + return L""; + } + + // Command SetVariable + // Data [the config name] [variable data] + // Execution the indicated variable is updated + // Result 'success' if the config was found, 'error' otherwise + if (sCommand == L"setvariable") + { + std::vector subStrings = CRainmeter::ParseString(_sData); + + if (subStrings.size() >= 2) + { + const std::wstring& config = subStrings[0]; + std::wstring arguments; + + for (size_t i = 1, isize = subStrings.size(); i < isize; ++i) + { + if (i != 1) arguments += L" "; + arguments += subStrings[i]; + } + + CMeterWindow *meterWindow = Rainmeter->GetMeterWindow(config); + if (meterWindow) + { + meterWindow->RunBang(BANG_SETVARIABLE, arguments.c_str()); + return L"success"; + } + } + + return L"error"; + } + + return L"noop"; +} diff --git a/Library/Export.h b/Library/Export.h index ed6125b6..9c92a544 100644 --- a/Library/Export.h +++ b/Library/Export.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2004 Kimmo Pekkola + Copyright (C) 2011 Kimmo Pekkola, Birunthan Mohanathas This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -20,28 +20,100 @@ #define __EXPORT_H__ #ifdef LIBRARY_EXPORTS -#define EXPORT_PLUGIN __declspec(dllexport) +#define LIBRARY_DECLSPEC __declspec(dllexport) #else -#define EXPORT_PLUGIN __declspec(dllimport) -#endif - -// log level constants -#define LOG_ERROR 1 -#define LOG_WARNING 2 -#define LOG_NOTICE 3 -#define LOG_DEBUG 4 +#define LIBRARY_DECLSPEC __declspec(dllimport) +#endif // LIBRARY_EXPORTS #ifdef __cplusplus -extern "C" +#define LIBRARY_EXPORT extern "C" LIBRARY_DECLSPEC +#define PLUGIN_EXPORT extern "C" __declspec(dllexport) +#else +#define LIBRARY_EXPORT LIBRARY_DECLSPEC +#define PLUGIN_EXPORT __declspec(dllexport) +#endif // __cplusplus + +// +// Exported functions +// + +#ifdef __cplusplus +LIBRARY_EXPORT LPCWSTR RmReadString(void* rm, LPCWSTR option, LPCWSTR defValue, BOOL replaceMeasures = TRUE); +#else +LIBRARY_EXPORT LPCWSTR RmReadString(void* rm, LPCWSTR option, LPCWSTR defValue, BOOL replaceMeasures); +#endif // __cplusplus + +LIBRARY_EXPORT double RmReadFormula(void* rm, LPCWSTR option, double defValue); + +LIBRARY_EXPORT LPCWSTR RmPathToAbsolute(void* rm, LPCWSTR relativePath); + +LIBRARY_EXPORT void RmExecute(void* skin, LPCWSTR command); + +LIBRARY_EXPORT void* RmGet(void* rm, int type); + +enum RmGetType { -#endif + RMG_MEASURENAME = 0, + RMG_SKIN = 1, + RMG_SETTINGSFILE = 2 +}; - EXPORT_PLUGIN BOOL LSLog(int nLevel, LPCTSTR pszModule, LPCTSTR pszMessage); - EXPORT_PLUGIN LPCTSTR ReadConfigString(LPCTSTR section, LPCTSTR key, LPCTSTR defValue); - EXPORT_PLUGIN LPCTSTR PluginBridge(LPCTSTR sCommand, LPCTSTR sData); +LIBRARY_EXPORT BOOL LSLog(int type, LPCWSTR unused, LPCWSTR message); -#ifdef __cplusplus +/* DEPRECATED */ LIBRARY_EXPORT __declspec(deprecated) LPCWSTR ReadConfigString(LPCWSTR section, LPCWSTR option, LPCWSTR defValue); + +/* DEPRECATED */ LIBRARY_EXPORT __declspec(deprecated) LPCWSTR PluginBridge(LPCWSTR command, LPCWSTR data); + +// +// Wrapper functions +// + +#ifndef LIBRARY_EXPORTS +__inline LPCWSTR RmReadPath(void* rm, LPCWSTR option, LPCWSTR defValue) +{ + LPCWSTR relativePath = RmReadString(rm, option, defValue, TRUE); + return RmPathToAbsolute(rm, relativePath); } -#endif -#endif \ No newline at end of file +__inline int RmReadInt(void* rm, LPCWSTR option, int defValue) +{ + LPCWSTR value = RmReadString(rm, option, L"", TRUE); + return (*value) ? _wtoi(value) : defValue; +} + +__inline double RmReadDouble(void* rm, LPCWSTR option, double defValue) +{ + LPCWSTR value = RmReadString(rm, option, L"", TRUE); + return (*value) ? wcstod(value, NULL) : defValue; +} + +__inline LPCWSTR RmGetMeasureName(void* rm) +{ + return (LPCWSTR)RmGet(rm, RMG_MEASURENAME); +} + +__inline LPCWSTR RmGetSettingsFile() +{ + return (LPCWSTR)RmGet(NULL, RMG_SETTINGSFILE); +} + +__inline void* RmGetSkin(void* rm) +{ + return (void*)RmGet(rm, RMG_SKIN); +} + +__inline void RmLog(int level, LPCWSTR message) +{ + LSLog(level, NULL, message); +} + +enum LOGLEVEL +{ + LOG_ERROR = 1, + LOG_WARNING = 2, + LOG_NOTICE = 3, + LOG_DEBUG = 4 +}; +#endif // LIBRARY_EXPORTS + +#endif diff --git a/Library/Library.vcxproj b/Library/Library.vcxproj index 1059f33c..85d52179 100644 --- a/Library/Library.vcxproj +++ b/Library/Library.vcxproj @@ -67,10 +67,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\ .\x32\$(Configuration)\ false @@ -115,7 +115,7 @@ 0x0409 - comctl32.lib;Wininet.lib;UxTheme.lib;Winmm.lib;gdiplus.lib;Iphlpapi.lib;shlwapi.lib;%(AdditionalDependencies) + comctl32.lib;Wininet.lib;UxTheme.lib;Winmm.lib;gdiplus.lib;Iphlpapi.lib;shlwapi.lib;Version.lib;%(AdditionalDependencies) ../TestBench/x32/Debug/Rainmeter.dll true %(AdditionalLibraryDirectories) @@ -123,6 +123,7 @@ .\x32/Debug/Rainmeter.pdb .\x32/Debug/Rainmeter.lib MachineX86 + Winmm.dll;Version.dll @@ -158,7 +159,7 @@ 0x0409 - comctl32.lib;Wininet.lib;UxTheme.lib;Winmm.lib;gdiplus.lib;Iphlpapi.lib;shlwapi.lib;%(AdditionalDependencies) + comctl32.lib;Wininet.lib;UxTheme.lib;Winmm.lib;gdiplus.lib;Iphlpapi.lib;shlwapi.lib;Version.lib;%(AdditionalDependencies) ../TestBench/x64/Debug/Rainmeter.dll true %(AdditionalLibraryDirectories) @@ -166,6 +167,7 @@ .\x64/Debug/Rainmeter.pdb .\x64/Debug/Rainmeter.lib MachineX64 + Winmm.dll;Version.dll @@ -204,7 +206,7 @@ 0x0409 - comctl32.lib;Wininet.lib;UxTheme.lib;Winmm.lib;gdiplus.lib;Iphlpapi.lib;shlwapi.lib;%(AdditionalDependencies) + comctl32.lib;Wininet.lib;UxTheme.lib;Winmm.lib;gdiplus.lib;Iphlpapi.lib;shlwapi.lib;Version.lib;%(AdditionalDependencies) ../TestBench/x32/Release/Rainmeter.dll true lua/lib;%(AdditionalLibraryDirectories) @@ -215,6 +217,7 @@ .rdata=.text true true + Winmm.dll;Version.dll @@ -250,7 +253,7 @@ 0x0409 - comctl32.lib;Wininet.lib;UxTheme.lib;Winmm.lib;gdiplus.lib;Iphlpapi.lib;shlwapi.lib;%(AdditionalDependencies) + comctl32.lib;Wininet.lib;UxTheme.lib;Winmm.lib;gdiplus.lib;Iphlpapi.lib;shlwapi.lib;Version.lib;%(AdditionalDependencies) ../TestBench/x64/Release/Rainmeter.dll true %(AdditionalLibraryDirectories) @@ -260,6 +263,7 @@ .rdata=.text true true + Winmm.dll;Version.dll @@ -657,6 +661,17 @@ MaxSpeed Use + + Disabled + EnableFastChecks + Use + Disabled + EnableFastChecks + MaxSpeed + Use + MaxSpeed + Use + Create Create @@ -837,7 +852,6 @@ - @@ -873,7 +887,9 @@ + + diff --git a/Library/Library.vcxproj.filters b/Library/Library.vcxproj.filters index 7431d3a4..51b05101 100644 --- a/Library/Library.vcxproj.filters +++ b/Library/Library.vcxproj.filters @@ -351,6 +351,9 @@ Source Files + + Source Files + @@ -362,9 +365,6 @@ Header Files - - Header Files - Header Files @@ -593,6 +593,9 @@ Header Files + + Header Files + diff --git a/Library/Litestep.h b/Library/Litestep.h index 051888aa..e2fbceb5 100644 --- a/Library/Litestep.h +++ b/Library/Litestep.h @@ -23,7 +23,14 @@ #include #include #include "Error.h" -#include "Export.h" + +enum LOGLEVEL +{ + LOG_ERROR = 1, + LOG_WARNING = 2, + LOG_NOTICE = 3, + LOG_DEBUG = 4 +}; void InitalizeLitestep(); void FinalizeLitestep(); @@ -38,7 +45,7 @@ std::string ConvertToUTF8(LPCWSTR str); std::wstring ConvertUTF8ToWide(LPCSTR str); void Log(int nLevel, const WCHAR* message); -void LogWithArgs(int nLevel, const WCHAR* format, ... ); +void LogWithArgs(int nLevel, const WCHAR* format, ...); void LogError(CError& error); void RunCommand(HWND Owner, LPCTSTR szCommand, int nShowCmd, bool asAdmin = false); diff --git a/Library/MeasurePlugin.cpp b/Library/MeasurePlugin.cpp index d5704208..c5237bcf 100644 --- a/Library/MeasurePlugin.cpp +++ b/Library/MeasurePlugin.cpp @@ -19,6 +19,7 @@ #include "StdAfx.h" #include "MeasurePlugin.h" #include "Rainmeter.h" +#include "Export.h" #include "System.h" #include "Error.h" @@ -32,13 +33,13 @@ extern CRainmeter* Rainmeter; */ CMeasurePlugin::CMeasurePlugin(CMeterWindow* meterWindow, const WCHAR* name) : CMeasure(meterWindow, name), m_Plugin(), + m_ReloadFunc(), m_ID(), - InitializeFunc(), - UpdateFunc(), - UpdateFunc2(), - FinalizeFunc(), - GetStringFunc(), - ExecuteBangFunc() + m_Update2(false), + m_PluginData(), + m_UpdateFunc(), + m_GetStringFunc(), + m_ExecuteBangFunc() { m_MaxValue = 0.0; } @@ -53,7 +54,19 @@ CMeasurePlugin::~CMeasurePlugin() { if (m_Plugin) { - if (FinalizeFunc) FinalizeFunc(m_Plugin, m_ID); + FARPROC finalizeFunc = GetProcAddress(m_Plugin, "Finalize"); + if (finalizeFunc) + { + if (IsNewApi()) + { + ((NEWFINALIZE)finalizeFunc)(m_PluginData); + } + else + { + ((FINALIZE)finalizeFunc)(m_Plugin, m_ID); + } + } + FreeLibrary(m_Plugin); } } @@ -68,19 +81,27 @@ bool CMeasurePlugin::Update() { if (!CMeasure::PreUpdate()) return false; - if (UpdateFunc) + if (m_UpdateFunc) { - // Update the plugin - m_Value = UpdateFunc(m_ID); - } - else if (UpdateFunc2) - { - // Update the plugin - m_Value = UpdateFunc2(m_ID); - } + if (IsNewApi()) + { + m_Value = ((NEWUPDATE)m_UpdateFunc)(m_PluginData); + } + else + { + if (m_Update2) + { + m_Value = ((UPDATE2)m_UpdateFunc)(m_ID); + } + else + { + m_Value = ((UPDATE)m_UpdateFunc)(m_ID); + } + } - // Reset to default - CSystem::ResetWorkingDirectory(); + // Reset to default + CSystem::ResetWorkingDirectory(); + } return PostUpdate(); } @@ -93,110 +114,111 @@ bool CMeasurePlugin::Update() */ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section) { - static UINT id = 1; + static UINT id = 0; CMeasure::ReadConfig(parser, section); if (m_Initialized) { - // DynamicVariables doesn't work with plugins, so stop here. + if (IsNewApi()) + { + ((NEWRELOAD)m_ReloadFunc)(m_PluginData, this, &m_MaxValue); + } + + // DynamicVariables doesn't work with old plugins return; } - m_PluginName = parser.ReadString(section, L"Plugin", L""); + std::wstring pluginName = parser.ReadString(section, L"Plugin", L""); - size_t pos = m_PluginName.rfind(L'.'); + size_t pos = pluginName.rfind(L'.'); if (pos == std::wstring::npos) { - m_PluginName += L".dll"; + pluginName += L".dll"; } - pos = m_PluginName.rfind(L'\\'); + pos = pluginName.rfind(L'\\'); if (pos != std::wstring::npos) { - m_PluginName.insert(0, L"..\\"); + pluginName.insert(0, L"..\\"); } - m_PluginName.insert(0, Rainmeter->GetPluginPath()); - - DWORD err = 0; - m_Plugin = CSystem::RmLoadLibrary(m_PluginName.c_str(), &err); + pluginName.insert(0, Rainmeter->GetPluginPath()); + m_Plugin = CSystem::RmLoadLibrary(pluginName.c_str(), NULL); if (m_Plugin == NULL) { - if (Rainmeter->GetDebug()) - { - LogWithArgs(LOG_ERROR, L"Plugin: Unable to load \"%s\" (%u)", m_PluginName.c_str(), err); - } - // Try to load from Rainmeter's folder - pos = m_PluginName.rfind(L'\\'); + pos = pluginName.rfind(L'\\'); if (pos != std::wstring::npos) { - std::wstring pluginName = Rainmeter->GetPath(); - pluginName.append(m_PluginName, pos + 1, m_PluginName.length() - (pos + 1)); + std::wstring pluginName2 = Rainmeter->GetPath(); + pluginName2.append(pluginName, pos + 1, pluginName.length() - (pos + 1)); - err = 0; - m_Plugin = CSystem::RmLoadLibrary(pluginName.c_str(), &err); - - if (m_Plugin == NULL) - { - if (Rainmeter->GetDebug()) - { - LogWithArgs(LOG_ERROR, L"Plugin: Unable to load \"%s\" (%u)", pluginName.c_str(), err); - } - } + m_Plugin = CSystem::RmLoadLibrary(pluginName2.c_str(), NULL); } if (m_Plugin == NULL) { - std::wstring error = L"Plugin: \"" + m_PluginName; + std::wstring error = L"Plugin: \"" + pluginName; error += L"\" not found"; throw CError(error); } } - InitializeFunc = (INITIALIZE)GetProcAddress(m_Plugin, "Initialize"); - FinalizeFunc = (FINALIZE)GetProcAddress(m_Plugin, "Finalize"); - UpdateFunc = (UPDATE)GetProcAddress(m_Plugin, "Update"); - UpdateFunc2 = (UPDATE2)GetProcAddress(m_Plugin, "Update2"); - GetStringFunc = (GETSTRING)GetProcAddress(m_Plugin, "GetString"); - ExecuteBangFunc = (EXECUTEBANG)GetProcAddress(m_Plugin, "ExecuteBang"); + FARPROC initializeFunc = GetProcAddress(m_Plugin, "Initialize"); + m_ReloadFunc = GetProcAddress(m_Plugin, "Reload"); + m_UpdateFunc = GetProcAddress(m_Plugin, "Update"); + m_GetStringFunc = GetProcAddress(m_Plugin, "GetString"); + m_ExecuteBangFunc = GetProcAddress(m_Plugin, "ExecuteBang"); - if (UpdateFunc == NULL && UpdateFunc2 == NULL && GetStringFunc == NULL) + // Remove current directory from DLL search path + SetDllDirectory(L""); + + if (IsNewApi()) { - FreeLibrary(m_Plugin); + m_PluginData = (void*)id; - std::wstring error = L"Plugin: \"" + m_PluginName; - error += L"\" doesn't export Update() or GetString()"; - throw CError(error); + if (initializeFunc) + { + ((NEWINITIALIZE)initializeFunc)(&m_PluginData); + } + + ((NEWRELOAD)m_ReloadFunc)(m_PluginData, this, &m_MaxValue); } - - // Initialize the plugin - m_ID = id++; - if (InitializeFunc) + else { - // Remove current directory from DLL search path - SetDllDirectory(L""); + m_ID = id; - double maxValue; - maxValue = InitializeFunc(m_Plugin, parser.GetFilename().c_str(), section, m_ID); + if (!m_UpdateFunc) + { + m_UpdateFunc = GetProcAddress(m_Plugin, "Update2"); + m_Update2 = true; + } - // Reset to default - SetDllDirectory(L""); - CSystem::ResetWorkingDirectory(); + double maxValue = 0; + if (initializeFunc) + { + maxValue = ((INITIALIZE)initializeFunc)(m_Plugin, parser.GetFilename().c_str(), section, m_ID); + } const std::wstring& szMaxValue = parser.ReadString(section, L"MaxValue", L""); if (szMaxValue.empty()) { m_MaxValue = maxValue; } + + if (m_MaxValue == 0) + { + m_MaxValue = 1; + m_LogMaxValue = true; + } } - if (m_MaxValue == 0) - { - m_MaxValue = 1; - m_LogMaxValue = true; - } + // Reset to default + SetDllDirectory(L""); + CSystem::ResetWorkingDirectory(); + + ++id; } /* @@ -207,9 +229,18 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section) */ const WCHAR* CMeasurePlugin::GetStringValue(AUTOSCALE autoScale, double scale, int decimals, bool percentual) { - if (GetStringFunc) + if (m_GetStringFunc) { - const WCHAR* ret = GetStringFunc(m_ID, 0); + const WCHAR* ret; + if (IsNewApi()) + { + ret = ((NEWGETSTRING)m_GetStringFunc)(m_PluginData); + } + else + { + ret = ((GETSTRING)m_GetStringFunc)(m_ID, 0); + } + if (ret) return CheckSubstitute(ret); } @@ -224,12 +255,19 @@ const WCHAR* CMeasurePlugin::GetStringValue(AUTOSCALE autoScale, double scale, i */ void CMeasurePlugin::ExecuteBang(const WCHAR* args) { - if (ExecuteBangFunc) + if (m_ExecuteBangFunc) { - ExecuteBangFunc(args, m_ID); + if (IsNewApi()) + { + ((NEWEXECUTEBANG)m_ExecuteBangFunc)(m_PluginData, args); + } + else + { + ((EXECUTEBANG)m_ExecuteBangFunc)(args, m_ID); + } } else { CMeasure::ExecuteBang(args); } -} \ No newline at end of file +} diff --git a/Library/MeasurePlugin.h b/Library/MeasurePlugin.h index cfddafd9..993cb1c3 100644 --- a/Library/MeasurePlugin.h +++ b/Library/MeasurePlugin.h @@ -20,14 +20,22 @@ #define __MEASUREPLUGIN_H__ #include "Measure.h" +#include "Export.h" -typedef UINT (*INITIALIZE)(HMODULE, LPCTSTR, LPCTSTR, UINT); +typedef UINT (*INITIALIZE)(HMODULE, LPCTSTR, LPCTSTR, UINT); typedef VOID (*FINALIZE)(HMODULE, UINT); -typedef UINT (*UPDATE)(UINT); -typedef double (*UPDATE2)(UINT); -typedef LPCTSTR (*GETSTRING)(UINT, UINT); +typedef UINT (*UPDATE)(UINT); +typedef double (*UPDATE2)(UINT); +typedef LPCTSTR (*GETSTRING)(UINT, UINT); typedef void (*EXECUTEBANG)(LPCTSTR, UINT); +typedef void (*NEWINITIALIZE)(void*); +typedef void (*NEWRELOAD)(void*, void*, double*); +typedef void (*NEWFINALIZE)(void*); +typedef double (*NEWUPDATE)(void*); +typedef LPCWSTR (*NEWGETSTRING)(void*); +typedef void (*NEWEXECUTEBANG)(void*, const WCHAR*); + class CMeasurePlugin : public CMeasure { public: @@ -42,16 +50,29 @@ protected: virtual void ReadConfig(CConfigParser& parser, const WCHAR* section); private: - std::wstring m_PluginName; - HMODULE m_Plugin; - UINT m_ID; + bool IsNewApi() { return m_ReloadFunc != NULL; } - INITIALIZE InitializeFunc; - FINALIZE FinalizeFunc; - UPDATE UpdateFunc; - UPDATE2 UpdateFunc2; - GETSTRING GetStringFunc; - EXECUTEBANG ExecuteBangFunc; + HMODULE m_Plugin; + + void* m_ReloadFunc; + + union + { + struct + { + UINT m_ID; + bool m_Update2; + }; + + struct + { + void* m_PluginData; + }; + }; + + void* m_UpdateFunc; + void* m_GetStringFunc; + void* m_ExecuteBangFunc; }; #endif diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index f655aef8..d3151cab 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -2110,8 +2110,6 @@ bool CMeterWindow::ReadSkin() MessageBox(m_Window, text.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION); } - m_Author = m_Parser.ReadString(L"Rainmeter", L"Author", L""); - static const RECT defMargins = {0}; m_BackgroundMargins = m_Parser.ReadRECT(L"Rainmeter", L"BackgroundMargins", defMargins); m_DragMargins = m_Parser.ReadRECT(L"Rainmeter", L"DragMargins", defMargins); diff --git a/Library/MeterWindow.h b/Library/MeterWindow.h index 2fbc1d97..fa02dfa1 100644 --- a/Library/MeterWindow.h +++ b/Library/MeterWindow.h @@ -200,7 +200,6 @@ public: CConfigParser& GetParser() { return m_Parser; } - const std::wstring& GetSkinAuthor() { return m_Author; } const std::wstring& GetSkinName() { return m_SkinName; } const std::wstring& GetSkinIniFile() { return m_SkinIniFile; } std::wstring GetSkinRootPath(); @@ -375,7 +374,6 @@ private: bool m_MouseOver; - std::wstring m_Author; // Skin's author std::wstring m_ConfigGroup; std::wstring m_BackgroundName; // Name of the background image RECT m_BackgroundMargins; diff --git a/Library/RawString.h b/Library/RawString.h new file mode 100644 index 00000000..6f57226b --- /dev/null +++ b/Library/RawString.h @@ -0,0 +1,91 @@ +/* + Copyright (C) 2011 Birunthan Mohanathas + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#ifndef __RAWSTRING_H__ +#define __RAWSTRING_H__ + +#include + +class CRawString +{ +public: + CRawString() : + m_String() + { + } + + CRawString(const WCHAR* str) : + m_String(str_alloc(str)) + { + } + + ~CRawString() + { + clear(); + } + + CRawString& operator=(const WCHAR* rhs) + { + clear(); + m_String = str_alloc(rhs); + return *this; + } + + CRawString& operator=(const CRawString& rhs) + { + if (&rhs != this) + { + clear(); + m_String = str_alloc(rhs.m_String); + } + return *this; + } + + const WCHAR* c_str() const + { + return m_String ? m_String : L""; + } + + bool empty() const + { + return !m_String || !(*m_String); + } + + void clear() + { + if (m_String) + { + free(m_String); + m_String = NULL; + } + } + +private: + CRawString(const CRawString& p) + { + } + + WCHAR* str_alloc(const WCHAR* str) + { + return str ? _wcsdup(str) : NULL; + } + + WCHAR* m_String; +}; + +#endif diff --git a/Plugins/API/DllExporter/AssemblyInfo.cs b/Plugins/API/DllExporter/AssemblyInfo.cs new file mode 100644 index 00000000..23c9f981 --- /dev/null +++ b/Plugins/API/DllExporter/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyCopyright("© 2011 - Birunthan Mohanathas")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyProduct("Rainmeter")] \ No newline at end of file diff --git a/Plugins/API/DllExporter/DllExporter.csproj b/Plugins/API/DllExporter/DllExporter.csproj new file mode 100644 index 00000000..8b427482 --- /dev/null +++ b/Plugins/API/DllExporter/DllExporter.csproj @@ -0,0 +1,101 @@ + + + + Debug + x86 + 8.0.30703 + 2.0 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1} + Exe + Properties + DllExporter + DllExporter + v2.0 + 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + x86 + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + 1607 + Program + TestBench\x32\Debug\Rainmeter.exe + + + x86 + none + true + bin\Release\ + TRACE + prompt + 4 + 1607 + Program + TestBench\x32\Release\Rainmeter.exe + + + OnOutputUpdated + + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + prompt + 1607 + Program + TestBench\x64\Debug\Rainmeter.exe + + + bin\x64\Release\ + TRACE + true + none + x64 + prompt + 1607 + Program + TestBench\x64\Release\Rainmeter.exe + + + + + + + + + + + + + move "$(TargetPath)" "$(SolutionDir)Plugins\API\DllExporter.exe" + + + \ No newline at end of file diff --git a/Plugins/API/DllExporter/Program.cs b/Plugins/API/DllExporter/Program.cs new file mode 100644 index 00000000..ec651088 --- /dev/null +++ b/Plugins/API/DllExporter/Program.cs @@ -0,0 +1,155 @@ +/* + Copyright (C) 2011 Birunthan Mohanathas + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; + +namespace DllExporter +{ + class Program + { + static int Main(string[] args) + { + string configurationName = args[0]; + string platformTarget = args[1]; + string targetDirectory = args[2]; + string targetDllName = targetDirectory + args[3]; + string targetIlName = targetDllName + ".il"; + string targetResName = targetDllName + ".res"; + string ilasmPath = args[4]; + string ildasmPath = args[5]; + + System.IO.Directory.SetCurrentDirectory(targetDirectory); + + bool is64 = platformTarget.ToLower().Equals("x64"); + bool isDebug = configurationName.ToLower().Equals("debug"); + + // Disassemble + Process ildasmProc = new Process(); + string ildasmArgs = string.Format("/nobar /output={0} {1}", targetIlName, targetDllName); + ildasmProc.StartInfo = new ProcessStartInfo(ildasmPath, ildasmArgs); + ildasmProc.StartInfo.UseShellExecute = false; + ildasmProc.StartInfo.CreateNoWindow = false; + ildasmProc.StartInfo.RedirectStandardOutput = true; + ildasmProc.Start(); + ildasmProc.WaitForExit(); + + if (ildasmProc.ExitCode != 0) + { + Console.WriteLine("DllExporter error: Unable to disassemble!"); + Console.WriteLine(ildasmProc.StandardOutput.ReadToEnd()); + return ildasmProc.ExitCode; + } + + bool hasResource = System.IO.File.Exists(targetResName); + + // Read disassembly and find methods marked with DllExport attribute + List lines = new List(System.IO.File.ReadAllLines(targetIlName)); + int attributeIndex = 0; + int exportCount = 0; + while (true) + { + attributeIndex = lines.FindIndex(attributeIndex, new Predicate(x => x.Contains(".custom instance void") && x.Contains("DllExport::.ctor()"))); + if (attributeIndex < 8) break; + + int methodIndex = lines.FindLastIndex(attributeIndex, attributeIndex, new Predicate(x => x.Contains(".method"))); + if (methodIndex == -1) + { + Console.WriteLine("DllExporter error: Unable to parse disassembly (.method not found)!"); + return 1; + } + + int functionIndex = lines.FindIndex(methodIndex, new Predicate(x => x.Contains("("))); + if (functionIndex == -1) + { + Console.WriteLine("DllExporter error: Unable to parse disassembly (bracket not found)!"); + return 1; + } + + int bracketPos = lines[functionIndex].IndexOf('('); + int functionNamePos = lines[functionIndex].LastIndexOf(' ', bracketPos); + string functionName = lines[functionIndex].Substring(functionNamePos, bracketPos - functionNamePos); + + // Change calling convention to cdecl + lines[functionIndex] = string.Format("{0} modopt([mscorlib]System.Runtime.CompilerServices.CallConvCdecl) {1}", lines[functionIndex].Substring(0, functionNamePos - 1), lines[functionIndex].Substring(functionNamePos)); + + int attributeBeginPos = lines[attributeIndex].IndexOf('.'); + string spaces = new string(' ', attributeBeginPos); + + // Replace attribute with export + ++exportCount; + lines[attributeIndex] = string.Format("{0}.export [{1}] as {2}", spaces, exportCount, functionName); + + ++attributeIndex; + } + + if (exportCount == 0) + { + Console.WriteLine("DllExporter warning: Nothing found to export."); + } + + // Remove the DllExport class + int classIndex = lines.FindIndex(new Predicate(x => x.Contains(".class ") && x.EndsWith(".DllExport"))); + if (classIndex == -1) + { + Console.WriteLine("DllExporter error: Unable to parse disassembly (DllExport class not found)!"); + return 1; + } + else + { + int classEndIndex = lines.FindIndex(classIndex, new Predicate(x => x.Contains("} // end of class") && x.EndsWith(".DllExport"))); + if (classEndIndex == -1) + { + Console.WriteLine("DllExporter error: Unable to parse disassembly (DllExport class end not found)!"); + return 1; + } + + lines.RemoveRange(classIndex, classEndIndex - classIndex + 2); + } + + // Write everything back + System.IO.File.WriteAllLines(targetIlName, lines.ToArray()); + + // Reassemble + Process ilasmProc = new Process(); + string resource = hasResource ? string.Format("/resource={0} ", targetResName) : ""; + string ilasmArgs = string.Format("/nologo /quiet /dll {0} {1} /output={2} {3}{4}", isDebug ? "/debug /pdb" : "/optimize", is64 ? "/x64 /PE64" : "", targetDllName, resource, targetIlName); + ilasmProc.StartInfo = new ProcessStartInfo(ilasmPath, ilasmArgs); + ilasmProc.StartInfo.UseShellExecute = false; + ilasmProc.StartInfo.CreateNoWindow = false; + ilasmProc.StartInfo.RedirectStandardOutput = true; + ilasmProc.Start(); + ilasmProc.WaitForExit(); + + if (ilasmProc.ExitCode != 0) + { + Console.WriteLine("DllExporter error: Unable to assemble!"); + Console.WriteLine(ilasmProc.StandardOutput.ReadToEnd()); + return ilasmProc.ExitCode; + } + + // Cleanup + System.IO.File.Delete(targetIlName); + System.IO.File.Delete(targetResName); + + return 0; + } + } +} diff --git a/Plugins/API/Rainmeter.cs b/Plugins/API/Rainmeter.cs new file mode 100644 index 00000000..8ae96cc0 --- /dev/null +++ b/Plugins/API/Rainmeter.cs @@ -0,0 +1,130 @@ +/* + Copyright (C) 2011 Birunthan Mohanathas + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +using System; +using System.Runtime.InteropServices; + +namespace Rainmeter +{ + /// + /// Wrapper around the Rainmeter C API. + /// + public class API + { + private IntPtr m_Rm; + + public API(IntPtr rm) + { + m_Rm = rm; + } + + public static unsafe char* ToUnsafe(string s) + { + fixed (char* p = s) return p; + } + + [DllImport("Rainmeter.dll", CharSet = CharSet.Auto)] + private extern static unsafe char* RmReadString(void* rm, char* option, char* defValue, int replaceMeasures); + + [DllImport("Rainmeter.dll", CharSet = CharSet.Auto)] + private extern static unsafe double RmReadFormula(void* rm, char* option, double defValue); + + [DllImport("Rainmeter.dll", CharSet = CharSet.Auto)] + private extern static unsafe char* RmPathToAbsolute(void* rm, char* relativePath); + + [DllImport("Rainmeter.dll", CharSet = CharSet.Auto)] + private extern static unsafe void RmExecute(void* rm, char* command); + + [DllImport("Rainmeter.dll", CharSet = CharSet.Auto)] + private extern static unsafe void* RmGet(void* rm, int type); + + [DllImport("Rainmeter.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)] + private extern static unsafe int LSLog(int type, char* unused, char* message); + + private enum RmGetType + { + MeasureName = 0, + Skin = 1, + SettingsFile = 2 + } + + public enum LogType + { + Error = 1, + Warning = 2, + Notice = 3, + Debug = 4 + } + + public unsafe string ReadString(string option, string defValue) + { + char* value = RmReadString((void*)m_Rm, ToUnsafe(option), ToUnsafe(defValue), 1); + return new string(value); + } + + public unsafe string ReadPath(string option, string defValue) + { + char* relativePath = RmReadString((void*)m_Rm, ToUnsafe(option), ToUnsafe(defValue), 1); + char* value = RmPathToAbsolute((void*)m_Rm, relativePath); + return new string(value); + } + + public unsafe double ReadFormula(string option, double defValue) + { + return RmReadFormula((void*)m_Rm, ToUnsafe(option), defValue); + } + + public unsafe int ReadInt(string option, int defValue) + { + string value = ReadString(option, ""); + return Convert.ToInt32(value); + } + + public unsafe string GetMeasureName() + { + char* value = (char*)RmGet((void*)m_Rm, (int)RmGetType.MeasureName); + return new string(value); + } + + public unsafe IntPtr GetSkin() + { + return (IntPtr)RmGet((void*)m_Rm, (int)RmGetType.Skin); + } + + public static unsafe void Execute(IntPtr skin, string command) + { + RmExecute((void*)skin, ToUnsafe(command)); + } + + public static unsafe void Log(LogType type, string message) + { + LSLog((int)type, null, ToUnsafe(message)); + } + } + + /// + /// Dummy attribute to mark method as exported for DllExporter.exe. + /// + [AttributeUsage(AttributeTargets.Method)] + public class DllExport : Attribute + { + public DllExport() + { + } + } +} diff --git a/Plugins/PluginAdvancedCPU/PluginAdvancedCPU.vcxproj b/Plugins/PluginAdvancedCPU/PluginAdvancedCPU.vcxproj index 31d5cd14..be5216dc 100644 --- a/Plugins/PluginAdvancedCPU/PluginAdvancedCPU.vcxproj +++ b/Plugins/PluginAdvancedCPU/PluginAdvancedCPU.vcxproj @@ -73,10 +73,10 @@ false $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true AdvancedCPU AdvancedCPU AdvancedCPU diff --git a/Plugins/PluginCoreTemp/PluginCoreTemp.cpp b/Plugins/PluginCoreTemp/PluginCoreTemp.cpp index 3ba1244f..2bed43f5 100644 --- a/Plugins/PluginCoreTemp/PluginCoreTemp.cpp +++ b/Plugins/PluginCoreTemp/PluginCoreTemp.cpp @@ -17,25 +17,11 @@ */ #include -#include -#include - +#include #include "CoreTempProxy.h" - #include "../../Library/Export.h" // Rainmeter's exported functions - #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point -extern "C" -{ - __declspec( dllexport ) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); - __declspec( dllexport ) void Finalize(HMODULE instance, UINT id); - __declspec( dllexport ) LPCTSTR GetString(UINT id, UINT flags); - __declspec( dllexport ) double Update2(UINT id); - __declspec( dllexport ) UINT GetPluginVersion(); - __declspec( dllexport ) LPCTSTR GetPluginAuthor(); -} - typedef enum eMeasureType { MeasureTemperature, @@ -49,73 +35,50 @@ typedef enum eMeasureType MeasureCpuName }; -std::map g_Types; -std::map g_Indexes; +struct MeasureData +{ + eMeasureType type; + int index; + + MeasureData() : type(), index() {} +}; + CoreTempProxy proxy; eMeasureType convertStringToMeasureType(LPCWSTR i_String); bool areStringsEqual(LPCWSTR i_String1, LPCWSTR i_Strting2); float getHighestTemp(); -/* - This function is called when the measure is initialized. - The function must return the maximum value that can be measured. - The return value can also be 0, which means that Rainmeter will - track the maximum value automatically. The parameters for this - function are: - - instance The instance of this DLL - iniFile The name of the ini-file (usually Rainmeter.ini) - section The name of the section in the ini-file for this measure - id The identifier for the measure. This is used to identify the measures that use the same plugin. -*/ -UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) +PLUGIN_EXPORT void Initialize(void** data) { - /* - Read our own settings from the ini-file - The ReadConfigString can be used for this purpose. Plugins - can also read the config some other way (e.g. with - GetPrivateProfileInt, but in that case the variables - do not work. - */ - LPCTSTR data = ReadConfigString(section, L"CoreTempType", L"Temperature"); - if (data) - { - eMeasureType type = convertStringToMeasureType(data); - - g_Types[id] = type; - if (type == MeasureTemperature || type == MeasureTjMax || type == MeasureLoad) - { - data = ReadConfigString(section, L"CoreTempIndex", L"0"); - if (data) - { - g_Indexes[id] = _wtoi(data); - } - else - { - g_Indexes[id] = 0; - LSLog(LOG_WARNING, NULL, L"CoreTemp.dll: Selected CoreTempType requires CoreTempIndex, assuming 0"); - } - } - } - - return 0; + MeasureData* measure = new MeasureData; + *data = measure; } -/* - This function is called when new value should be measured. - The function returns the new value. -*/ -double Update2(UINT id) +PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { + MeasureData* measure = (MeasureData*)data; + + LPCWSTR value = RmReadString(rm, L"CoreTempType", L"Temperature"); + eMeasureType type = convertStringToMeasureType(value); + + if (type == MeasureTemperature || type == MeasureTjMax || type == MeasureLoad) + { + measure->index = RmReadInt(rm, L"CoreTempIndex", 0); + } +} + +PLUGIN_EXPORT double Update(void* data) +{ + MeasureData* measure = (MeasureData*)data; double result = 0; if (proxy.GetData()) { - switch (g_Types[id]) + switch (measure->type) { case MeasureTemperature: - result = proxy.GetTemp(g_Indexes[id]); + result = proxy.GetTemp(measure->index); break; case MeasureMaxTemperature: @@ -123,11 +86,11 @@ double Update2(UINT id) break; case MeasureTjMax: - result = proxy.GetTjMax(g_Indexes[id]); + result = proxy.GetTjMax(measure->index); break; case MeasureLoad: - result = proxy.GetCoreLoad(g_Indexes[id]); + result = proxy.GetCoreLoad(measure->index); break; case MeasureVid: @@ -151,11 +114,12 @@ double Update2(UINT id) return result; } -LPCTSTR GetString(UINT id, UINT flags) +PLUGIN_EXPORT LPCWSTR GetString(void* data) { - static WCHAR buffer[256]; + MeasureData* measure = (MeasureData*)data; + static WCHAR buffer[128]; - switch (g_Types[id]) + switch (measure->type) { case MeasureVid: _snwprintf_s(buffer, _TRUNCATE, L"%.4f", proxy.GetVID()); @@ -172,44 +136,6 @@ LPCTSTR GetString(UINT id, UINT flags) return buffer; } -/* - If the measure needs to free resources before quitting. - The plugin can export Finalize function, which is called - when Rainmeter quits (or refreshes). -*/ -void Finalize(HMODULE instance, UINT id) -{ - std::map::iterator i1 = g_Types.find(id); - if (i1 != g_Types.end()) - { - g_Types.erase(i1); - } - - std::map::iterator i2 = g_Indexes.find(id); - if (i2 != g_Indexes.end()) - { - g_Indexes.erase(i2); - } -} - -/* - Returns the version number of the plugin. The value - can be calculated like this: Major * 1000 + Minor. - So, e.g. 2.31 would be 2031. -*/ -UINT GetPluginVersion() -{ - return 1000; -} - -/* - Returns the author of the plugin for the about dialog. -*/ -LPCTSTR GetPluginAuthor() -{ - return L"Arthur Liberman - ALCPU (arthur_liberman@hotmail.com)"; -} - bool areStringsEqual(LPCWSTR i_String1, LPCWSTR i_Strting2) { return _wcsicmp(i_String1, i_Strting2) == 0; @@ -258,7 +184,7 @@ eMeasureType convertStringToMeasureType(LPCWSTR i_String) else { result = MeasureTemperature; - LSLog(LOG_WARNING, NULL, L"CoreTemp.dll: Invalid CoreTempType"); + RmLog(LOG_WARNING, L"CoreTemp.dll: Invalid CoreTempType"); } return result; diff --git a/Plugins/PluginCoreTemp/PluginCoreTemp.rc b/Plugins/PluginCoreTemp/PluginCoreTemp.rc index a9ae1fb8..5c5f7695 100644 --- a/Plugins/PluginCoreTemp/PluginCoreTemp.rc +++ b/Plugins/PluginCoreTemp/PluginCoreTemp.rc @@ -1,10 +1,5 @@ -// Microsoft Developer Studio generated resource script. -// - +#include #include "../../Version.h" -#define APSTUDIO_READONLY_SYMBOLS -#include "windows.h" -#undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // @@ -18,7 +13,7 @@ VS_VERSION_INFO VERSIONINFO #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG #else - FILEFLAGS 0x0L + FILEFLAGS 0x0L #endif FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_DLL @@ -28,10 +23,8 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "FileDescription", "CoreTemp Plugin for Rainmeter" VALUE "FileVersion", "1.0.0.0" - VALUE "InternalName", "PluginCoreTemp" - VALUE "LegalCopyright", "Copyright (C) 2011 - Arthur Liberman" + VALUE "LegalCopyright", "© 2011 - Arthur Liberman" VALUE "OriginalFilename", "CoreTemp.dll" VALUE "ProductName", "Rainmeter" #ifdef _WIN64 diff --git a/Plugins/PluginCoreTemp/PluginCoreTemp.vcxproj b/Plugins/PluginCoreTemp/PluginCoreTemp.vcxproj index 73681a45..63b00051 100644 --- a/Plugins/PluginCoreTemp/PluginCoreTemp.vcxproj +++ b/Plugins/PluginCoreTemp/PluginCoreTemp.vcxproj @@ -68,10 +68,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ false diff --git a/Plugins/PluginExample/PluginExample.vcxproj b/Plugins/PluginExample/PluginExample.vcxproj index ecb439a1..6bd6239e 100644 --- a/Plugins/PluginExample/PluginExample.vcxproj +++ b/Plugins/PluginExample/PluginExample.vcxproj @@ -73,10 +73,10 @@ false $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true ExamplePlugin ExamplePlugin ExamplePlugin diff --git a/Plugins/PluginExampleCS/AssemblyInfo.cs b/Plugins/PluginExampleCS/AssemblyInfo.cs new file mode 100644 index 00000000..fb75abfc --- /dev/null +++ b/Plugins/PluginExampleCS/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyCopyright("© 2011 - Birunthan Mohanathas")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyInformationalVersion(Rainmeter.Version.Informational)] +[assembly: AssemblyProduct("Rainmeter")] diff --git a/Plugins/PluginExampleCS/Plugin.cs b/Plugins/PluginExampleCS/Plugin.cs new file mode 100644 index 00000000..11d98573 --- /dev/null +++ b/Plugins/PluginExampleCS/Plugin.cs @@ -0,0 +1,154 @@ +/* + Copyright (C) 2011 Birunthan Mohanathas + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +// Define/undefine to control exports. Undefine to infrom that this plugin does not support +// a particular function. +#define ExportUpdate +#undef ExportGetString +#undef ExportExecuteBang + +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using Rainmeter; + +namespace ExampleCS +{ + /// + /// Represents a measure. Members are specific to a measure. Methods are called by Rainmeter + /// when needed. + /// + internal class Measure + { + /// + /// Called when a measure is created. + /// + internal Measure() + { + } + + /// + /// Called when a measure is destroyed. Use this rather than a destructor to perform + /// cleanup. + /// + internal void Cleanup() + { + } + + /// + /// Called when the measure settings must be (re)read. + /// + internal void Reload(Rainmeter.API rm) + { + // Examples: + // string value = rm.ReadString("TestOption", "DefaultValue"); + // double value = rm.ReadFormula("TestOption", 20); + } + + /// + /// Called when the measure settings must be (re)read. + /// +#if ExportUpdate + internal double Update() + { + return 42.0; + } +#endif + + /// + /// Called when the string representation of the measure value is required. + /// + /// + /// Can be called multiple times per update cycle. Do not call heavy functions here. + /// Instead create a string member, set it in Update, and simply return it here. + /// +#if ExportGetString + internal string GetString() + { + return "Hello, world!"; + } +#endif + + /// + /// Called when as a result of a !CommandMeasure bang aimed at the measure. + /// +#if ExportExecuteBang + internal void ExecuteBang(string args) + { + } +#endif + } + + /// + /// Handles communication between Rainmeter and the plugin. + /// + public static class Plugin + { + [DllExport] + public unsafe static void Initialize(void** data) + { + IntPtr dataPtr = (IntPtr)((void*)*data); + Measures.Add(dataPtr, new Measure()); + } + + [DllExport] + public unsafe static void Finalize(void* data) + { + IntPtr dataPtr = (IntPtr)data; + Measures[dataPtr].Cleanup(); + Measures.Remove(dataPtr); + } + + [DllExport] + public unsafe static void Reload(void* data, void* rm, double* maxValue) + { + IntPtr dataPtr = (IntPtr)data; + Measures[dataPtr].Reload(new Rainmeter.API((IntPtr)rm)); + } + +#if ExportUpdate + [DllExport] + public unsafe static double Update(void* data) + { + IntPtr dataPtr = (IntPtr)data; + return Measures[dataPtr].Update(); + } +#endif + +#if ExportGetString + [DllExport] + public unsafe static char* GetString(void* data) + { + IntPtr dataPtr = (IntPtr)data; + return Rainmeter.API.ToUnsafe(Measures[dataPtr].GetString()); + } +#endif + +#if ExportExecuteBang + [DllExport] + public unsafe static void ExecuteBang(void* data, char* args) + { + IntPtr dataPtr = (IntPtr)data; + Measures[dataPtr].ExecuteBang(new string(args)); + Measures.Remove(dataPtr); + } +#endif + + internal static Dictionary Measures = new Dictionary(); + } +} diff --git a/Plugins/PluginExampleCS/PluginExampleCS.csproj b/Plugins/PluginExampleCS/PluginExampleCS.csproj new file mode 100644 index 00000000..c302d719 --- /dev/null +++ b/Plugins/PluginExampleCS/PluginExampleCS.csproj @@ -0,0 +1,100 @@ + + + + Debug + x86 + 9.0.30729 + 2.0 + {D31F73ED-3978-44FA-B599-49584BA30D3A} + Library + Properties + ExampleCS + ExampleCS + v2.0 + 512 + 3.5 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + true + full + false + $(SolutionDir)TestBench\x32\Debug\Plugins\ + TRACE;DEBUG + prompt + 4 + true + 1607 + x86 + + + none + true + $(SolutionDir)TestBench\x32\Release\Plugins\ + TRACE + prompt + 4 + true + 1607 + x86 + + + true + $(SolutionDir)TestBench\x64\Debug\Plugins\ + TRACE;DEBUG;X64 + true + full + x64 + prompt + 1607 + + + $(SolutionDir)TestBench\x64\Release\Plugins\ + TRACE;X64 + true + true + none + x64 + prompt + 1607 + + + OnOutputUpdated + + + + + + + + + + + + + + "$(SolutionDir)Plugins\API\DllExporter.exe" "$(ConfigurationName)" "$(PlatformName)" "$(TargetDir)\" "$(TargetFileName)" "$(TargetedFrameworkDir)\ilasm.exe" "$(FrameworkSDKDir)bin\ildasm.exe" + + \ No newline at end of file diff --git a/Plugins/PluginFolderInfo/PluginFolderInfo.vcxproj b/Plugins/PluginFolderInfo/PluginFolderInfo.vcxproj index ca59548b..48b9a0d9 100644 --- a/Plugins/PluginFolderInfo/PluginFolderInfo.vcxproj +++ b/Plugins/PluginFolderInfo/PluginFolderInfo.vcxproj @@ -67,10 +67,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ false diff --git a/Plugins/PluginFolderInfo/PluginFolderInfo.vcxproj.filters b/Plugins/PluginFolderInfo/PluginFolderInfo.vcxproj.filters index aa7bc244..18569717 100644 --- a/Plugins/PluginFolderInfo/PluginFolderInfo.vcxproj.filters +++ b/Plugins/PluginFolderInfo/PluginFolderInfo.vcxproj.filters @@ -1,88 +1,35 @@  - - {1ff2687f-eddb-4a75-8e79-16a5962f020b} - - - - - pcre - - - pcre - - - pcre - - - pcre - + + + + - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - - - pcre - + + + + + + + + + + + + + + + + + + + + diff --git a/Plugins/PluginInputText/AssemblyInfo.cs b/Plugins/PluginInputText/AssemblyInfo.cs new file mode 100644 index 00000000..d8745063 --- /dev/null +++ b/Plugins/PluginInputText/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +[assembly: AssemblyCopyright("© 2010 - Peter Souza IV")] +[assembly: AssemblyVersion("1.4.0.0")] +[assembly: AssemblyInformationalVersion(Rainmeter.Version.Informational)] +[assembly: AssemblyProduct("Rainmeter")] diff --git a/Plugins/PluginInputText/InputBox.Designer.cs b/Plugins/PluginInputText/InputBox.Designer.cs new file mode 100644 index 00000000..1206c36e --- /dev/null +++ b/Plugins/PluginInputText/InputBox.Designer.cs @@ -0,0 +1,105 @@ +namespace InputText +{ + partial class InputBox + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.txtInput = new System.Windows.Forms.TextBox(); + this.btnOK = new System.Windows.Forms.Button(); + this.btnCancel = new System.Windows.Forms.Button(); + this.SuspendLayout(); + // + // txtInput + // + this.txtInput.BorderStyle = System.Windows.Forms.BorderStyle.None; + this.txtInput.Location = new System.Drawing.Point(0, 0); + this.txtInput.Margin = new System.Windows.Forms.Padding(0); + this.txtInput.Multiline = true; + this.txtInput.Name = "txtInput"; + this.txtInput.Size = new System.Drawing.Size(200, 22); + this.txtInput.TabIndex = 0; + this.txtInput.Leave += new System.EventHandler(this.txtInput_Leave); + // + // btnOK + // + this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK; + this.btnOK.Location = new System.Drawing.Point(2, 2); + this.btnOK.Margin = new System.Windows.Forms.Padding(0); + this.btnOK.Name = "btnOK"; + this.btnOK.Size = new System.Drawing.Size(2, 2); + this.btnOK.TabIndex = 1; + this.btnOK.TabStop = false; + this.btnOK.Text = "OK"; + this.btnOK.UseVisualStyleBackColor = true; + this.btnOK.Click += new System.EventHandler(this.btnOK_Click); + // + // btnCancel + // + this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.btnCancel.Location = new System.Drawing.Point(2, 2); + this.btnCancel.Margin = new System.Windows.Forms.Padding(0); + this.btnCancel.Name = "btnCancel"; + this.btnCancel.Size = new System.Drawing.Size(2, 2); + this.btnCancel.TabIndex = 2; + this.btnCancel.TabStop = false; + this.btnCancel.Text = "btnCancel"; + this.btnCancel.UseVisualStyleBackColor = true; + this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); + // + // InputBox + // + this.AcceptButton = this.btnOK; + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.AutoSize = true; + this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.CancelButton = this.btnCancel; + this.ClientSize = new System.Drawing.Size(251, 42); + this.Controls.Add(this.txtInput); + this.Controls.Add(this.btnCancel); + this.Controls.Add(this.btnOK); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; + this.Name = "InputBox"; + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + this.Text = "InputBox"; + this.Deactivate += new System.EventHandler(this.InputBox_Deactivate); + this.Load += new System.EventHandler(this.InputBox_Load); + this.Shown += new System.EventHandler(this.InputBox_Shown); + this.Leave += new System.EventHandler(this.InputBox_Leave); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox txtInput; + private System.Windows.Forms.Button btnOK; + private System.Windows.Forms.Button btnCancel; + } +} \ No newline at end of file diff --git a/Plugins/PluginInputText/InputBox.cs b/Plugins/PluginInputText/InputBox.cs new file mode 100644 index 00000000..ba4006aa --- /dev/null +++ b/Plugins/PluginInputText/InputBox.cs @@ -0,0 +1,323 @@ +using System; +using System.Drawing; +using System.Windows.Forms; + +namespace InputText +{ + public partial class InputBox : Form + { + public Rainmeter.Settings.InstanceSettings Instance = null; + + #region Default form initializer + public InputBox() + { + InitializeComponent(); + } + #endregion + + // This event will make sure we have focus when the inputbox is shown ot the user. + // it will only cause focus if the window itself has focus (i.e. doesn't steal). + private void InputBox_Shown(object sender, EventArgs e) + { + this.Activate(); + this.BringToFront(); + this.Activate(); + this.BringToFront(); + this.txtInput.Focus(); + } + + // All exceptions are swallowed for the sake of this example. Since the majority + // (if not all) of these are rather simple in nature, debugging without errors + // should be fairly simple anyway. + // + // However, if you wanted to log errors, a simple way would be to add something like + // this: + // + // try + // { + // ... // code you are testing + // } + // catch (Exception ex) + // { + // Rainmeter.Log(Rainmeter.LogLevel.Warning, "InputText :: exception :: " + ex.GetType().ToString() + ": " + ex.Message); + // } + + #region TextInput -- returns the inputted text + public string TextInput + { + get + { + return this.txtInput.Text.Trim(); + } + } + #endregion + #region ChangeFontFace(string) -- changes the text's font name + public void ChangeFontFace(string sFont) + { + try + { + this.txtInput.Font = new Font(sFont, this.txtInput.Font.Size); + } + catch { } + } + #endregion + #region ChangeFontColor(string) -- changes the font's color, supports 6 and 8-digit hex or a series of 3 or 4 comma-separated numbers + public void ChangeFontColor(string sColor) + { + try + { + sColor = sColor.Trim(); + + if (sColor.Contains(",")) // #,#,# or #,#,#,# format + { + string[] sParts = sColor.Trim().Replace(" ", string.Empty).Split(new char[] { ',' }, StringSplitOptions.None); + this.txtInput.ForeColor = Color.FromArgb(int.Parse(sParts[0]), int.Parse(sParts[1]), int.Parse(sParts[2])); + this.txtInput.ForeColor = Color.FromArgb(int.Parse(sParts[3]), int.Parse(sParts[0]), int.Parse(sParts[1]), int.Parse(sParts[2])); + } + else + { + if (sColor.Length == 6) // 6-digit hex (no alpha transparency) + { + uint iColor = uint.Parse(sColor, System.Globalization.NumberStyles.HexNumber); + // Since it was omitted, force full opacity (not transparent at all) + this.txtInput.ForeColor = Color.FromArgb((int)(0xFF000000 | iColor)); + } + else if (sColor.Length == 8) // 8-digit hex (with alpha transparency) + { + uint iColor = uint.Parse(sColor, System.Globalization.NumberStyles.HexNumber); + // This swaps RRGGBBAA for AARRGGBB, which Color.FromArgb() wants + iColor = ((iColor & 0xFFFFFF00) >> 8) | ((iColor & 0x000000FF) << 24); + this.txtInput.ForeColor = Color.FromArgb((int)iColor); + } + } + } + catch { } + } + #endregion + #region ChangeBackColor(string) -- changes the background color, supports 6 and 8-digit hex or a series of 3 or 4 comma-separated numbers + public void ChangeBackColor(string sColor) + { + try + { + sColor = sColor.Trim(); + + if (sColor.Contains(",")) // #,#,# or #,#,#,# format + { + string[] sParts = sColor.Trim().Replace(" ", string.Empty).Split(new char[] { ',' }, StringSplitOptions.None); + this.txtInput.BackColor = Color.FromArgb(int.Parse(sParts[0]), int.Parse(sParts[1]), int.Parse(sParts[2])); + + // Change 0-255 transparency to a 0.0-1.0 transparency range + double dTrans = (double)int.Parse(sParts[3]); + dTrans /= 255.0; + this.Opacity = dTrans; + } + else + { + if (sColor.Length == 6) // 6-digit hex (no alpha transparency) + { + uint iColor = uint.Parse(sColor, System.Globalization.NumberStyles.HexNumber); + this.txtInput.BackColor = Color.FromArgb((int)(0xFF000000 | iColor)); + // Since it was omitted, force full opacity (not transparent at all) + this.Opacity = 1.0; + } + else if (sColor.Length == 8) // 8-digit hex (with alpha transparency) + { + uint iColor = uint.Parse(sColor, System.Globalization.NumberStyles.HexNumber); + // This swaps RRGGBBAA for AARRGGBB, which Color.FromArgb() wants + iColor = ((iColor & 0xFFFFFF00) >> 8) | ((iColor & 0x000000FF) << 24); + this.txtInput.BackColor = Color.FromArgb((int)((0xFF000000) | (0x00FFFFFF & iColor))); + + // Change 0-255 transparency to a 0.0-1.0 transparency range + double dTrans = (double)((iColor & 0xFF000000) >> 24); + dTrans /= 255.0; + this.Opacity = dTrans; + } + } + } + catch { } + } + #endregion + #region ChangeStringAlign(string) -- Changes text horizontal alignment + public void ChangeStringAlign(string sAlign) + { + try + { + sAlign = sAlign.ToUpper().Trim(); + + if (sAlign == "LEFT") + this.txtInput.TextAlign = HorizontalAlignment.Left; + else if (sAlign == "CENTER") + this.txtInput.TextAlign = HorizontalAlignment.Center; + else if (sAlign == "RIGHT") + this.txtInput.TextAlign = HorizontalAlignment.Right; + } + catch { } + } + #endregion + #region ChangeFontSize(string) -- changes the font's point size (supports floating-point values) + public void ChangeFontSize(string sSize) + { + try + { + this.txtInput.Font = new Font(this.txtInput.Font.OriginalFontName, float.Parse(sSize)); + } + catch { } + } + #endregion + #region MakeTopmost() -- forces the form to have the 'Always On Top' property + public void MakeTopmost() + { + this.TopMost = true; + } + #endregion + #region MakePassword() -- causes the textbox to be password style + public void MakePassword() + { + this.txtInput.PasswordChar = '*'; + } + #endregion + #region ChangeFontStringStyle() -- changes the font's bold/italic styles + public void ChangeFontStringStyle(string sStyle) + { + try + { + sStyle = sStyle.ToUpper().Trim(); + + if (sStyle == "NORMAL") + this.txtInput.Font = new Font(this.txtInput.Font, FontStyle.Regular); + else if (sStyle == "BOLD") + this.txtInput.Font = new Font(this.txtInput.Font, FontStyle.Bold); + else if (sStyle == "ITALIC") + this.txtInput.Font = new Font(this.txtInput.Font, FontStyle.Italic); + else if (sStyle == "BOLDITALIC") + this.txtInput.Font = new Font(this.txtInput.Font, FontStyle.Bold | FontStyle.Italic); + } + catch { } + } + #endregion + #region ChangeW(string) -- changes the width of the input textbox + public void ChangeW(string sWidth) + { + try + { + this.txtInput.Width = int.Parse(sWidth); + } + catch { } + } + #endregion + #region ChangeH(string) -- changes the height of the input textbox + public void ChangeH(string sHeight) + { + try + { + this.txtInput.Height = int.Parse(sHeight); + } + catch { } + } + #endregion + #region ChangeX(string) -- changes the X (horizontal) position of the input textbox, relative to its parent skin + public void ChangeX(Rainmeter.Settings.InstanceSettings Instance, string sX) + { + try + { + // If the position is changed, make sure the form's auto-location is disabled. + if (this.StartPosition != FormStartPosition.Manual) + this.StartPosition = FormStartPosition.Manual; + + // Notice that we need the position of the parent window for offset location. + // + // The Rainmeter class does this for us + this.Location = new System.Drawing.Point(Rainmeter.ConfigX(Rainmeter.SkinName(Instance)) + int.Parse(sX), this.Location.Y); + } + catch { } + } + #endregion + #region ChangeY(string) -- changes the Y (vertical) position of the input textbox, relative to its parent skin + public void ChangeY(Rainmeter.Settings.InstanceSettings Instance, string sY) + { + try + { + // If the position is changed, make sure the form's auto-location is disabled. + if (this.StartPosition != FormStartPosition.Manual) + this.StartPosition = FormStartPosition.Manual; + + // Notice that we need the position of the parent window for offset location. + // + // The Rainmeter class does this for us + this.Location = new System.Drawing.Point(this.Location.X, Rainmeter.ConfigY(Rainmeter.SkinName(Instance)) + int.Parse(sY)); + } + catch { } + } + #endregion + #region DefaultValue(string) -- sets the default text to appear in the input textbox + public void DefaultValue(string val) + { + this.txtInput.Text = val; + } + #endregion + #region MakeFocusDismiss(bool) -- dismisses the input textbox if it loses cursor/window focus + + private bool _FocusDismiss = true; + public DialogResult drBackup = DialogResult.None; + public string sTextValue = string.Empty; + + public void MakeFocusDismiss(bool bDismissing) + { + this._FocusDismiss = bDismissing; + } + + private void txtInput_Leave(object sender, EventArgs e) + { + if (this._FocusDismiss) + { + this.drBackup = DialogResult.Cancel; + this.Close(); + } + } + + private void InputBox_Leave(object sender, EventArgs e) + { + if (this._FocusDismiss) + { + this.drBackup = DialogResult.Cancel; + this.Close(); + } + } + + private void InputBox_Deactivate(object sender, EventArgs e) + { + if (this._FocusDismiss) + { + this.drBackup = DialogResult.Cancel; + this.Close(); + } + } + + private void btnOK_Click(object sender, EventArgs e) + { + _FocusDismiss = false; + this.sTextValue = this.txtInput.Text.Trim(); + this.drBackup = DialogResult.OK; + this.DialogResult = DialogResult.OK; + this.Close(); + } + + private void btnCancel_Click(object sender, EventArgs e) + { + _FocusDismiss = false; + this.drBackup = DialogResult.Cancel; + this.DialogResult = DialogResult.Cancel; + this.Close(); + } + + #endregion + + private void InputBox_Load(object sender, EventArgs e) + { + this.Activate(); + this.BringToFront(); + this.Activate(); + this.BringToFront(); + } + } +} diff --git a/Plugins/PluginInputText/InputBox.resx b/Plugins/PluginInputText/InputBox.resx new file mode 100644 index 00000000..5ea0895e --- /dev/null +++ b/Plugins/PluginInputText/InputBox.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/Plugins/PluginInputText/Main.cs b/Plugins/PluginInputText/Main.cs new file mode 100644 index 00000000..40a91c02 --- /dev/null +++ b/Plugins/PluginInputText/Main.cs @@ -0,0 +1,173 @@ +using System; +using Rainmeter; + +namespace InputText +{ + public class Main + { + /// + /// Your name (author) and the version of the plugin go here. The code will + /// automatically format the values and send them back when a call to GetAuthor() + /// or GetVersion() is made. + /// + /// Optionally, you may also provide an e-mail address and additional comments + /// + private static Rainmeter.Settings Plugin = new Rainmeter.Settings + ( + // Author name + "Peter Souza IV", + + // Version + 1.05, + + // E-mail + "psouza4@gmail.com", + + // Comments (try to keep it under 50 characters) + "Please visit the forums for support." + ); + + #region GetAuthor() and GetVersion() exports -- no need to modify + + [DllExport] + public static UInt32 GetPluginVersion() + { + return Rainmeter.Version(Plugin.Version); + } + + [DllExport] + public unsafe static char* GetPluginAuthor() + { + if (!string.IsNullOrEmpty(Plugin.Email) && !string.IsNullOrEmpty(Plugin.Comments)) + return Rainmeter.String(Plugin.Author + " (" + Plugin.Email + "): " + Plugin.Comments); + if (!string.IsNullOrEmpty(Plugin.Email)) + return Rainmeter.String(Plugin.Author + " (" + Plugin.Email + ")"); + if (!string.IsNullOrEmpty(Plugin.Comments)) + return Rainmeter.String(Plugin.Author + ": " + Plugin.Comments); + return Rainmeter.String(Plugin.Author); + } + + #endregion + + #region Initialize() and Finalize() -- you may add to these functions if necessary + + [DllExport] + public unsafe static UInt32 Initialize(IntPtr instance, char* iniFile, char* section, UInt32 id) + { + Plugin.AddInstance(iniFile, section, id); // required: do not remove + + //////////////////////////////////////////////////////////////// + // + // You may add code here, if necessary + // + + //////////////////////////////////////////////////////////////// + return 0; + } + + [DllExport] + public static void Finalize(IntPtr instance, UInt32 id) + { + Plugin.RemoveInstance(id); // required: do not remove + + //////////////////////////////////////////////////////////////// + // + // You may add code here, if necessary + // + + //////////////////////////////////////////////////////////////// + return; + } + #endregion + + #region Update(), Update2(), and GetString() exports -- please read notes + + // *** WARNING / NOTES *** + // + // Do not add to this code: change your code in PluginCode.cs instead + // + // However, due to the way Rainmeter works, you will probably want to + // comment-out either 'Update' or 'Update2' if your plugin will be returning + // numeric values. + // + // Rainmeter will look for 'Update' for positive integers. If you want to + // allow negative numbers or floating-point numbers, use 'Update2' instead. + // + // You *MUST* comment-out whichever function you don't want to use for this + // to work. + // + // If you don't care, such as a plugin that either doesn't return data or + // only returns string/text data, then you can leave them both here (it won't + // hurt anything). + // + // *** WARNING / NOTES *** + + + /// + /// Rainmeter's request for numeric data from the plugin. This version can only + /// return positive integers ranging from 0 to 4,294,967,296. Comment this member + /// out and use 'Update2' if you want to return negative or floating-point values. + /// + /// The unique instance ID of this request. + /// Current value for this meter. + [DllExport] + public static UInt32 Update(UInt32 id) + { + // Do not modify this member (although you can comment it out). Instead, update + // your code in 'PluginCode.cs'. + return new YourPlugin().Update(Plugin, id); + } + + /// + /// Rainmeter's request for numeric data from the plugin. This version can return + /// positive or negative floating-point numbers (32-bit precision). Comment this + /// member out and use 'Update' if you want to only return positive integers. + /// + /// The unique instance ID of this request. + /// Current value for this meter. + [DllExport] + public static double Update2(UInt32 id) + { + // Do not modify this member (although you can comment it out). Instead, update + // your code in 'PluginCode.cs'. + return new YourPlugin().Update2(Plugin, id); + } + + /// + /// Rainmeter's request for text data from the plugin. + /// + /// The unique instance ID of this request. + /// Unused still as of Dec 2nd, 2010. + /// + [DllExport] + public unsafe static char* GetString(UInt32 id, UInt32 flags) + { + // Do not modify this member. Instead, update your code in 'PluginCode.cs'. + return Rainmeter.String(new YourPlugin().GetString(Plugin, id)); + } + + #endregion + + #region ExecuteBang() export -- no need to modify (change code in PluginCode.cs) + + [DllExport] + public static unsafe void ExecuteBang(char* args, UInt32 id) + { + new YourPlugin().ExecuteBang(Plugin, id, new string(args)); + return; + } + + #endregion + } + + /// + /// Dummy attribute to mark method as exported for DllExporter.exe. + /// + [AttributeUsage(AttributeTargets.Method)] + public class DllExport : Attribute + { + public DllExport() + { + } + } +} diff --git a/Plugins/PluginInputText/PluginCode.cs b/Plugins/PluginInputText/PluginCode.cs new file mode 100644 index 00000000..a24e42b5 --- /dev/null +++ b/Plugins/PluginInputText/PluginCode.cs @@ -0,0 +1,476 @@ +using System; +using System.Collections.Generic; + +// The bulk of your plugin's code belongs in this file. +namespace InputText +{ + class PluginCode + { + // 'Update', 'Update2', and 'GetString' all return data back to Rainmeter, depending on + // if the Rainmeter measure wants a numeric value or a string/text data. + // + // The 'Instance' member contains all of the data necessary to read the INI file + // passed to your plugin when this instance was first initialized. Remember: your plugin + // may be initialized multiple times. For example, a plugin that reads the free space + // of a hard drive may be called multiple times -- once for each installed hard drive. + + public UInt32 Update(Rainmeter.Settings.InstanceSettings Instance) + { + return 0; + } + + public double Update2(Rainmeter.Settings.InstanceSettings Instance) + { + return 0.0; + } + + public string GetString(Rainmeter.Settings.InstanceSettings Instance) + { + // This plugin is unique as it is one of the first to not be used to display data + // back in Rainmeter, but to request user input and use that input during batch + // operations (and other purposes). + // + // However, Rainmeter requires that data be sent back, so we'll return temporary data + // In this case, the data is whatever the user last entered into an input textbox. + return Instance.GetTempValue("LastInput", string.Empty).ToString(); + } + + + // 'ExecuteBang' is a way of Rainmeter telling your plugin to do something *right now*. + // What it wants to do can be defined by the 'Command' parameter. + public void ExecuteBang(Rainmeter.Settings.InstanceSettings Instance, string Command) + { + #region Handle a single parameter + + // If our parameter list only contains a single word, then open a textbox immediately + // and set a value. This mode does not do any batching. + if (!Command.Trim().Contains(" ")) + { + // Assume that the parameter is the name of the variable + string sVariableName = Command.Trim(); + + // Ask for input + string sInput = GetUserInput(Instance); + + // If the user cancelled out of the inputbox (ESC key, etc.), then abort + if (sInput == null) + return; + + // Ask Rainmeter to set the variable using a bang (http://rainmeter.net/RainCMS/?q=Bangs) + Rainmeter.Bang("!RainmeterSetVariable " + sVariableName + " \"" + sInput.Replace("\"", "\\\"") + "\""); + + // Note that the skin needs DynamicVariables=1 in the measure's settings or the above + // code will have no effect. + return; + } + + #endregion + #region Handle multiple parameters + + // Our parameter list contains at least two words, so split them up + string[] sParts = Command.Trim().Split(new string[] { " " }, StringSplitOptions.None); + + // If the first parameter is 'ExecuteBatch' (not case sensitive)... + if (sParts[0].Trim().ToUpper() == "EXECUTEBATCH") + { + // ExecuteBatch tells this plugin to go through the measure's settings to look + // for lines beginning with "Command" and executing Rainmeter bangs for each one. + // If a line contains $UserInput$, then an input textbox is opened and command + // execution pauses until the user enters text or dismisses the textbox. If the + // textbox is dismissed (Escape key, for example), all processing ends, otherwise + // it continues depending on the range of commands selected. + // + // Each "Command" line allows overriding all settings that the input textbox + // supports, therefor some checking and substitution is performed, thus a + // more complex parser has been implemented. + // + // ExecuteBatch expects this syntax: + // ExecuteBatch [All|#|#-#] + // + // This allows Rainmeter to call the plugin to execute a range including: + // All All commands in the measure + // # Only a single command in the measure + // #-# A specific range of commands in the measure + + #region Determine range + // Determine range. Default is 1 to 1,000,000,000, although if processing finds + // that a requested line is blank, it will stop all processing (so 'All' will + // only parse 14 lines if "Command15" does not exist or is blank). + int iMin = 1; + int iMax = 1000000000; + try + { + if (sParts[1].Trim().ToUpper() != "ALL") + { + if (sParts[1].Contains("-")) + { + string[] sSubParts = sParts[1].Split(new string[] { "-" }, StringSplitOptions.None); + iMin = int.Parse(sSubParts[0]); + iMax = int.Parse(sSubParts[1]); + } + else + iMin = iMax = int.Parse(sParts[1]); + } + } + catch // handle all errors above + { + // Any error above will be ignored and the default range used instead. + // This can occur if the measure asks to ExecuteBatch an invalid range + // or the range could not be translated to an acceptable format. + // + // For example: ExecuteBatch asdf + iMin = 1; + iMax = 1000000000; + } + #endregion + #region Parse commands in range + // Parse each command in the range, aborting if any line returns 'false' or + // the requested command line does not exist in the config for that measure. + for (int i = iMin; i <= iMax; i++) + { + // Read this command's line + string sCurrentLine = Instance.INI_Value("Command" + i.ToString()); + + // If empty/non-existent, abort + if (string.IsNullOrEmpty(sCurrentLine)) + break; + + // Execute the line, but if there's a problem (error or they cancel the + // input textbox), then abort + if (!ExecuteLine(Instance, sCurrentLine)) + break; + + // Continue to the next line, if there is any + } + #endregion + return; + } + + // Unhandled command, log the message but otherwise do nothing + Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Received command \"" + sParts[0].Trim() + "\", left unhandled"); + + #endregion + + return; + } + + #region This is all code custom to this plugin + + #region Parse the current command line + private bool ExecuteLine(Rainmeter.Settings.InstanceSettings Instance, string sLine) + { + // If this line contains a $UserInput$ token, then we need to do some extra + // parsing + if (sLine.ToUpper().Contains("$USERINPUT$")) + { + try + { + #region Handle in-line overrides + // Create a blank list of overrides + Dictionary Overrides = new Dictionary(); + + // Start looking for overridable settings and adjust the list accordingly, + // stripping out settings from the line if they are discovered. + // + // The supporting TagData() function allows for whitespace if quotes are + // used. For example: + // + // DefaultValue="hello there, how are you" + sLine = ScanAndReplace(sLine, "DefaultValue", ref Overrides); + sLine = ScanAndReplace(sLine, "X", ref Overrides); + sLine = ScanAndReplace(sLine, "Y", ref Overrides); + sLine = ScanAndReplace(sLine, "W", ref Overrides); + sLine = ScanAndReplace(sLine, "H", ref Overrides); + sLine = ScanAndReplace(sLine, "StringStyle", ref Overrides); + sLine = ScanAndReplace(sLine, "StringAlign", ref Overrides); + sLine = ScanAndReplace(sLine, "FocusDismiss", ref Overrides); + sLine = ScanAndReplace(sLine, "FontColor", ref Overrides); + sLine = ScanAndReplace(sLine, "FontFace", ref Overrides); + sLine = ScanAndReplace(sLine, "SolidColor", ref Overrides); + sLine = ScanAndReplace(sLine, "Password", ref Overrides); + sLine = ScanAndReplace(sLine, "FontSize", ref Overrides); + sLine = ScanAndReplace(sLine, "TopMost", ref Overrides); + #endregion + + // Get user input + string sInput = GetUserInput(Instance, Overrides); + if (sInput == null) + { + // Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Aborted, user cancelled text box"); + return false; + } + + // Swap out the $UserInput$ token with what the user typed + sLine = Replace(sLine, "$USERINPUT$", sInput); + } + catch (Exception ex) + { + // If there was an error doing any of the above, log it for debugging purposes. + Rainmeter.Log(Rainmeter.LogLevel.Warning, "InputText: Exception " + ex.GetType().ToString() + ": " + ex.Message); + return false; + } + } + + // Execute the bang. This will either be the original line from CommandX= (sLine variable) or + // an adjusted line based on special parsing above. + // Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Executing bang: " + sLine); + Rainmeter.Bang(sLine); + return true; + } + #endregion + #region GetUserInput() -- creates an input textbox and handles all INI and override settings + + private string GetUserInput(Rainmeter.Settings.InstanceSettings Instance) + { + // No INI overrides provided, so create an empty list + return GetUserInput(Instance, new Dictionary()); + } + private string GetUserInput(Rainmeter.Settings.InstanceSettings Instance, Dictionary sOverrides) + { + // Create the form. 'InputBox' is a .NET form with a textbox and two button controls on it. + InputBox input = new InputBox(); + input.Instance = Instance; + input.ChangeX(Instance, "0"); + input.ChangeY(Instance, "0"); + + // Change the styles of the InputBox form based on overrides or INI values + #region Style and preference tweaks (INI and override settings) + + if (sOverrides.ContainsKey("FontFace")) + input.ChangeFontFace(sOverrides["FontFace"]); + else if (!string.IsNullOrEmpty(Instance.INI_Value("FontFace"))) + input.ChangeFontFace(Instance.INI_Value("FontFace")); + + if (sOverrides.ContainsKey("FontSize")) + input.ChangeFontSize(sOverrides["FontSize"]); + else if (!string.IsNullOrEmpty(Instance.INI_Value("FontSize"))) + input.ChangeFontSize(Instance.INI_Value("FontSize")); + + if (sOverrides.ContainsKey("W")) + input.ChangeW(sOverrides["W"]); + else if (!string.IsNullOrEmpty(Instance.INI_Value("W"))) + input.ChangeW(Instance.INI_Value("W")); + + if (sOverrides.ContainsKey("H")) + input.ChangeH(sOverrides["H"]); + else if (!string.IsNullOrEmpty(Instance.INI_Value("H"))) + input.ChangeH(Instance.INI_Value("H")); + + if (sOverrides.ContainsKey("X")) + input.ChangeX(Instance, sOverrides["X"]); + else if (!string.IsNullOrEmpty(Instance.INI_Value("X"))) + input.ChangeX(Instance, Instance.INI_Value("X")); + + if (sOverrides.ContainsKey("Y")) + input.ChangeY(Instance, sOverrides["Y"]); + else if (!string.IsNullOrEmpty(Instance.INI_Value("Y"))) + input.ChangeY(Instance, Instance.INI_Value("Y")); + + if (sOverrides.ContainsKey("StringStyle")) + input.ChangeFontStringStyle(sOverrides["StringStyle"]); + else if (!string.IsNullOrEmpty(Instance.INI_Value("StringStyle"))) + input.ChangeFontStringStyle(Instance.INI_Value("StringStyle")); + + if (sOverrides.ContainsKey("StringAlign")) + input.ChangeStringAlign(sOverrides["StringAlign"]); + else if (!string.IsNullOrEmpty(Instance.INI_Value("StringAlign"))) + input.ChangeStringAlign(Instance.INI_Value("StringAlign")); + + bool bFocusDismiss = true; + if (sOverrides.ContainsKey("FocusDismiss")) + { + input.MakeFocusDismiss(sOverrides["FocusDismiss"] == "1"); + bFocusDismiss = sOverrides["FocusDismiss"] == "1"; + } + else + { + input.MakeFocusDismiss(!(Instance.INI_Value("FocusDismiss").Trim().ToUpper() != "1")); + bFocusDismiss = !(Instance.INI_Value("FocusDismiss").Trim().ToUpper() != "1"); + } + + if (sOverrides.ContainsKey("FontColor")) + input.ChangeFontColor(sOverrides["FontColor"]); + else if (!string.IsNullOrEmpty(Instance.INI_Value("FontColor"))) + input.ChangeFontColor(Instance.INI_Value("FontColor")); + + if (sOverrides.ContainsKey("SolidColor")) + input.ChangeBackColor(sOverrides["SolidColor"]); + else if (!string.IsNullOrEmpty(Instance.INI_Value("SolidColor"))) + input.ChangeBackColor(Instance.INI_Value("SolidColor")); + + if (sOverrides.ContainsKey("Passwords")) + { + if (sOverrides["DefaultValue"] == "1") + input.MakePassword(); + } + else if (Instance.INI_Value("Password").Trim().ToUpper() == "1") + input.MakePassword(); + + bool bAutoTopMost = true; + if (sOverrides.ContainsKey("TopMost")) + { + if (sOverrides["TopMost"] == "1") + { + input.MakeTopmost(); + bAutoTopMost = false; + } + else if (sOverrides["TopMost"] == "0") + bAutoTopMost = false; + } + else if (Instance.INI_Value("TopMost").Trim().ToUpper() == "1") + { + input.MakeTopmost(); + bAutoTopMost = false; + } + else if (Instance.INI_Value("TopMost").Trim().ToUpper() != "AUTO") + if (!string.IsNullOrEmpty(Instance.INI_Value("TopMost").Trim())) + bAutoTopMost = false; + if (bAutoTopMost) + if (Rainmeter.ParentIsTopmost(Instance)) + input.MakeTopmost(); + + if (sOverrides.ContainsKey("DefaultValue")) + input.DefaultValue(sOverrides["DefaultValue"]); + else if (!string.IsNullOrEmpty(Instance.INI_Value("DefaultValue"))) + input.DefaultValue(Instance.INI_Value("DefaultValue").Trim()); + + #endregion + + if (bFocusDismiss) + { + input.Show(new WindowWrapper(Rainmeter.GetConfigWindow(Instance))); + + for (; ; ) + { + if (input.DialogResult != System.Windows.Forms.DialogResult.None || input.drBackup != System.Windows.Forms.DialogResult.None) + break; + System.Windows.Forms.Application.DoEvents(); + System.Threading.Thread.Sleep(44); + } + } + else + { + input.ShowDialog(new WindowWrapper(Rainmeter.GetConfigWindow(Instance))); + } + + + if (input.drBackup != System.Windows.Forms.DialogResult.None) + { + if (input.drBackup != System.Windows.Forms.DialogResult.OK) + return null; + } + else if (input.DialogResult != System.Windows.Forms.DialogResult.None) + { + if (input.DialogResult != System.Windows.Forms.DialogResult.OK) + return null; + } + + Instance.SetTempValue("LastInput", input.sTextValue); + return input.sTextValue; + } + #endregion + #region Replace() -- case-insensitive string replacement + private static string Replace(string sIn, string sFind, string sReplace) + { + int iReplace = sIn.ToUpper().IndexOf(sFind.ToUpper()); + + string sLineNew = string.Empty; + + if (iReplace > 0) + sLineNew += sIn.Substring(0, iReplace); + sLineNew += sReplace; + sLineNew += sIn.Substring(iReplace + (sFind.ToUpper()).Length); + + return sLineNew; + } + private static string Replace(string sIn, int iStart, int iLength, string sReplace) + { + int iReplace = iStart; + + string sLineNew = string.Empty; + + if (iReplace > 0) + sLineNew += sIn.Substring(0, iReplace); + sLineNew += sReplace; + sLineNew += sIn.Substring(iReplace + iLength); + + return sLineNew; + } + #endregion + #region TagLoc(), TagData(), FindTag() -- text parsing utilities for the override tags + private int TagLoc(string sLine, string sTag) + { + if (!FindTag(sLine, sTag)) + return -1; + + return sLine.ToUpper().IndexOf(" " + sTag.ToUpper() + "=") + 1; + } + + private string TagData(string sLine, string sTag) + { + if (!FindTag(sLine, sTag)) + return string.Empty; + + int iStart = TagLoc(sLine, sTag) + sTag.Length + 1; + + string sTagData = string.Empty; + bool bInQuote = false; + + try + { + + for (int i = 0; ; i++) + { + if (i == 0) + { + if (sLine[i + iStart] == '"') + { + bInQuote = true; + continue; + } + } + + if (sLine[i + iStart] == '"') + break; + + if (!bInQuote) + if (char.IsWhiteSpace(sLine[i + iStart])) + break; + + sTagData += sLine[i + iStart]; + } + } + catch { } + + if (bInQuote == true) + return "\"" + sTagData + "\""; + + return sTagData; + } + + private bool FindTag(string sLine, string sTag) + { + return (sLine.ToUpper().Contains(" " + sTag.ToUpper() + "=")); + } + #endregion + #region ScanAndReplace() -- searches for a tag and its value, adding it to overrides if found, and then removing it from the input line + private string ScanAndReplace(string sLine, string sTagName, ref Dictionary Overrides) + { + if (FindTag(sLine, sTagName)) + { + string sTagData = TagData(sLine, sTagName); + // Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Overriding " + sTagName + " with " + sTagData); + if (sTagData.StartsWith("\"")) + Overrides.Add(sTagName, sTagData.Substring(1, sTagData.Length - 2)); + else + Overrides.Add(sTagName, sTagData); + sLine = Replace(sLine, TagLoc(sLine, sTagName) - 1, 1 + sTagName.Length + 1 + sTagData.Length, string.Empty); + } + + return sLine; + } + #endregion + + #endregion + } +} diff --git a/Plugins/PluginInputText/PluginInputText.csproj b/Plugins/PluginInputText/PluginInputText.csproj new file mode 100644 index 00000000..f12a35cf --- /dev/null +++ b/Plugins/PluginInputText/PluginInputText.csproj @@ -0,0 +1,114 @@ + + + + Debug + x86 + 9.0.30729 + 2.0 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D} + Library + Properties + Rainmeter + InputText + v2.0 + 512 + 3.5 + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + + true + full + false + $(SolutionDir)TestBench\x32\Debug\Plugins\ + TRACE;DEBUG + prompt + 4 + true + 1607 + x86 + + + none + true + $(SolutionDir)TestBench\x32\Release\Plugins\ + TRACE + prompt + 4 + true + 1607 + x86 + + + true + $(SolutionDir)TestBench\x64\Debug\Plugins\ + TRACE;DEBUG;X64 + true + full + x64 + prompt + 1607 + + + $(SolutionDir)TestBench\x64\Release\Plugins\ + TRACE;X64 + true + true + none + x64 + prompt + 1607 + + + OnOutputUpdated + + + + + + + + + + + + + Form + + + InputBox.cs + + + + + + InputBox.cs + + + + + + "$(SolutionDir)Plugins\API\DllExporter.exe" "$(ConfigurationName)" "$(PlatformName)" "$(TargetDir)\" "$(TargetFileName)" "$(TargetedFrameworkDir)\ilasm.exe" "$(FrameworkSDKDir)bin\ildasm.exe" + + \ No newline at end of file diff --git a/Plugins/PluginInputText/Rainmeter.cs b/Plugins/PluginInputText/Rainmeter.cs new file mode 100644 index 00000000..6a924937 --- /dev/null +++ b/Plugins/PluginInputText/Rainmeter.cs @@ -0,0 +1,766 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading; + +// This is a utility class / toolkit for communicating with Rainmeter and managing +// logging, INI settings, bangs, window positioning, multiple instances, and temporary +// data storage. +// +// You should not need to edit this code except to expand the toolkit support. +// +// Rather, most of your plugin's code should go in PluginCode.cs or additional files +// that you create (such as new forms, classes, and controls). +namespace InputText +{ + public class WindowWrapper : System.Windows.Forms.IWin32Window + { + public WindowWrapper(IntPtr handle) + { + _hwnd = handle; + } + + public IntPtr Handle + { + get { return _hwnd; } + } + + private IntPtr _hwnd; + } + + public class Rainmeter + { + #region Methods for getting the screen-relative location of the current skin + + public static IntPtr GetConfigWindow(Rainmeter.Settings.InstanceSettings Instance) + { + return (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File)))); + } + public static int ConfigX(string sSkin) + { + IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin))); + RECT rct; + if (!GetWindowRect(hwnd, out rct)) + { + Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it"); + return 0; + } + return rct.Left; + } + public static int ConfigX(Rainmeter.Settings.InstanceSettings Instance) + { + IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File)))); + RECT rct; + if (!GetWindowRect(hwnd, out rct)) + { + Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it"); + return 0; + } + return rct.Left; + } + + public static int ConfigY(string sSkin) + { + IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin))); + RECT rct; + if (!GetWindowRect(hwnd, out rct)) + { + Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it"); + return 0; + } + return rct.Top; + } + public static int ConfigY(Rainmeter.Settings.InstanceSettings Instance) + { + IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File)))); + RECT rct; + if (!GetWindowRect(hwnd, out rct)) + { + Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it"); + return 0; + } + return rct.Top; + } + + public static int ConfigWidth(string sSkin) + { + IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin))); + RECT rct; + if (!GetWindowRect(hwnd, out rct)) + { + Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it"); + return 0; + } + return rct.Right - rct.Left; + } + public static int ConfigWidth(Rainmeter.Settings.InstanceSettings Instance) + { + IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File)))); + RECT rct; + if (!GetWindowRect(hwnd, out rct)) + { + Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it"); + return 0; + } + return rct.Right - rct.Left; + } + + public static int ConfigHeight(string sSkin) + { + IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin))); + RECT rct; + if (!GetWindowRect(hwnd, out rct)) + { + Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it"); + return 0; + } + return rct.Bottom - rct.Top; + } + public static int ConfigHeight(Rainmeter.Settings.InstanceSettings Instance) + { + IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File)))); + RECT rct; + if (!GetWindowRect(hwnd, out rct)) + { + Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it"); + return 0; + } + return rct.Bottom - rct.Top; + } + + #region GetWindowRect() platform invoke to get the size/location of a window + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); + + #endregion + #region GetParent() platform invoke to get the handle of a parent window + + [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] + private static extern IntPtr GetParent(IntPtr hWnd); + + [StructLayout(LayoutKind.Sequential)] + public struct RECT + { + public int Left; // x position of upper-left corner + public int Top; // y position of upper-left corner + public int Right; // x position of lower-right corner + public int Bottom; // y position of lower-right corner + } + #endregion + #region SendMessage -- SendMessage (this variant is only for WM_COPYSTRUCT messages) + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, ref COPYDATASTRUCT lParam); + + [StructLayout(LayoutKind.Sequential)] + struct COPYDATASTRUCT + { + public UInt32 dwData; + public int cbData; + public IntPtr lpData; + } + + #endregion + #region FindWindowByClass -- platform invoke to find a window given a class name + + [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)] + private static extern IntPtr FindWindowByClass(string lpClassName, IntPtr ZeroOnly); + + #endregion + + #region GetWindowInfo -- platform invoke to check a window's Z-order (Topmost=Auto) + + [DllImport("user32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi); + + [StructLayout(LayoutKind.Sequential)] + private struct WINDOWINFO + { + public uint cbSize; + public RECT rcWindow; + public RECT rcClient; + public uint dwStyle; + public uint dwExStyle; + public uint dwWindowStatus; + public uint cxWindowBorders; + public uint cyWindowBorders; + public ushort atomWindowType; + public ushort wCreatorVersion; + + public WINDOWINFO(Boolean? filler) + : this() // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)". + { + cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO))); + } + } + + // Call this function to determine if the parent skin is topmost + public static bool ParentIsTopmost(Rainmeter.Settings.InstanceSettings Instance) + { + IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File)))); + WINDOWINFO info = new WINDOWINFO(true); + GetWindowInfo(hwnd, ref info); + return ((info.dwExStyle & 0x00000008L) > 0); + } + + #endregion + #region SkinName -- gets the current skin name + + public static string SkinName(Rainmeter.Settings.InstanceSettings Instance) + { + try + { + return Instance.ConfigName; + /* + if (Instance.GetTempValue("_internal_SkinPath", string.Empty).ToString() == string.Empty) + { + string sAppDataPath = System.Environment.GetEnvironmentVariable("AppData").Trim(); + string sRainmeterINIText = System.IO.File.ReadAllText(sAppDataPath + "\\Rainmeter\\Rainmeter.ini"); + string sSkinPath = Chopper(sRainmeterINIText.Replace('\n', '\r'), "SkinPath=", "\r").Trim().TrimEnd(new char[] { '\\' }); + Instance.SetTempValue("_internal_SkinPath", sSkinPath); + } + + System.IO.FileInfo fi = new System.IO.FileInfo(Instance.INI_File); + return fi.DirectoryName.Replace(Instance.GetTempValue("_internal_SkinPath", string.Empty).ToString(), string.Empty).TrimEnd(new char[] { '\\' }).TrimStart(new char[] { '\\' }); + */ + } + catch { } + + return string.Empty; + } + #endregion + + #endregion + + #region Chopper -- string manipulation + + public static string Chopper(string sText, string sSearch, string sEnd, int offset) + { + string sIntermediate = ""; + + try + { + if ((sSearch == null) || (sSearch == string.Empty)) + { + sIntermediate = sText.Substring(offset); + } + else + { + if (sText.Contains(sSearch) == false) + return sText; + + sIntermediate = sText.Substring(sText.IndexOf(sSearch) + sSearch.Length + offset); + } + + if ((sEnd == null) || (sEnd == string.Empty)) + return sIntermediate; + + if (sIntermediate.Contains(sEnd) == false) + return sIntermediate; + + return sIntermediate.Substring(0, sIntermediate.IndexOf(sEnd)); + } + catch + { + if (sIntermediate == "") + return sText; + return sIntermediate; + } + } + + public static string Chopper(string sText, string sSearch, string sEnd) + { + return Chopper(sText, sSearch, sEnd, 0); + } + + #endregion + + #region Version helpers (converts "1.04" or "1, 4" to 1004, etc.) + + public static UInt32 Version(double dVersion) + { + return (UInt32)(dVersion * 1000.0); + } + + public static UInt32 Version(int iMajor, int iMinor) + { + return (UInt32)((iMajor * 1000) + iMinor); + } + + #endregion + + #region Converts a C# 'string' to a C++ 'char *' + public static unsafe char* String(string s) + { + fixed (char* p = s) return p; + } + #endregion + + #region Export for Rainmeter's new plugin bridge + + [DllImport("Rainmeter.dll", CharSet = CharSet.Auto)] + private extern static unsafe char* PluginBridge(char* sCommand, char* sData); + + private unsafe static string PluginBridge(string sCommand, string sData) + { + try + { + return new string(PluginBridge(Rainmeter.String(sCommand), Rainmeter.String(sData))); + } + catch { } + + return string.Empty; + } + + #endregion + + #region Read INI values using Rainmeter's 'ReadConfigString' export + + // We have to use this method rather than loading the .INI file manually because Rainmeter will + // replace tokens for us. See: http://rainmeter.net/RainCMS/?q=Settings_BuiltInVariables + // + // Please note that this is done during plugin initialization and stored in the Instance + // variable. This is done automatically, so this function should not be used by plugin developers + // directly, therefore the methods here are 'private'. + + [DllImport("Rainmeter.dll", CharSet = CharSet.Auto)] + private extern static unsafe char* ReadConfigString(char* sSection, char* key, char* defValue); + + // If an INI is missing, a blank string will be returned to avoid raising exceptions + private unsafe static string ReadConfigString(string sSection, string sKey) + { + try + { + char* szString = ReadConfigString(Rainmeter.String(sSection), Rainmeter.String(sKey), Rainmeter.String(string.Empty)); + + if (szString != null) + return new string(szString); + } + catch { } + + return string.Empty; + } + + #endregion + + #region Use Rainmeter's 'LSLog' export to log using its format and settings + + [DllImport("Rainmeter.dll", CharSet = CharSet.Auto)] + private extern static unsafe UInt16 LSLog(int nLevel, char* pszModule, char* pszMessage); + public enum LogLevel : int + { + Error = 1, + Warning = 2, + Notice = 3, + Debug = 4 + } + + // You can call this function directly to log to Rainmeter.log + // + // Rainmeter needs to be configured to allow debug logging, of course. + + public static unsafe bool Log(LogLevel level, string sText) + { + return (Rainmeter.LSLog((int)level, Rainmeter.String("C# plugin"), Rainmeter.String(sText)) != 0); + } + + #endregion + + #region Send a bang to Rainmeter (prepends a '!' if necessary) + public static void Bang(string sBang) + { + if (!sBang.StartsWith("!")) + sBang = "!" + sBang; + System.Diagnostics.Process.Start(System.Windows.Forms.Application.ExecutablePath, sBang); + } + #endregion + + #region Settings are automatically created (and set at the top of 'Main.cs'), don't edit here + + // WARNING: DO NOT EDIT THIS HERE. Change your author name, version, etc. in 'Main.cs' + public class Settings + { + public string Author = "(unknown)"; + public double Version = 0.01; + public string Email = string.Empty; + public string Comments = string.Empty; + + public Settings(string _Author, double _Version) + { + this.Author = _Author; + this.Version = _Version; + } + public Settings(string _Author, double _Version, string _Email) + { + this.Author = _Author; + this.Version = _Version; + this.Email = _Email; + } + public Settings(string _Author, double _Version, string _Email, string _Comments) + { + this.Author = _Author; + this.Version = _Version; + this.Email = _Email; + this.Comments = _Comments; + } + + public Dictionary Instances = new Dictionary(); + public List KeyValues = new List(); + + public struct SectionKey + { + public UInt32 id; + public string INI_File; + public string Section; + public string Key; + public string Value; + } + + public unsafe void AddInstance(char* iniFile, char* section, UInt32 id) + { + InstanceSettings new_instance = new InstanceSettings(); + new_instance.Initialize(this, iniFile, section, id); + this.Instances.Add(id, new_instance); + + bool bInSection = false; + foreach (string line in System.IO.File.ReadAllLines(new_instance.INI_File)) + { + if (line.Trim().StartsWith(";")) continue; // ignore comments + if (line.Trim().StartsWith("[")) bInSection = false; // new section + + // section test + if (line.Trim().ToLower() == ("[" + new_instance.Section.ToLower() + "]")) + bInSection = true; + + if (!bInSection) continue; // abort this pass if not in section + if (!line.Contains("=")) continue; // abort this pass if there's no INI setting here + + string[] sLineParts = line.Trim().Split(new char[] { '=' }); + + SectionKey sk = new SectionKey(); + sk.id = id; + sk.INI_File = new_instance.INI_File; + sk.Key = sLineParts[0].Trim(); + sk.Section = new_instance.Section; + sk.Value = ReadConfigString(new_instance.Section, sLineParts[0].Trim()); + + this.KeyValues.Add(sk); + } + } + + public void RemoveInstance(UInt32 id) + { + try + { + start_over: + for (int i = 0; i < this.KeyValues.Count; i++) + { + if (this.KeyValues[i].id == id) + { + this.KeyValues.RemoveAt(i); + goto start_over; // start over since the IEnumerable has been modified + } + } + this.Instances.Remove(id); + } + catch { } + } + + public class InstanceSettings + { + private UInt32 _ID = 0; + private string _INI_File = string.Empty; + private string _Section = string.Empty; + private Settings PluginSettings = null; + + private Dictionary TempData = new Dictionary(); + + private object locker = new object(); + + public object GetTempValue(string name, object oDefault) + { + lock (this.locker) + { + if (this.TempData.ContainsKey(name)) + return this.TempData[name]; + return oDefault; + } + } + + public void SetTempValue(string name, object o) + { + lock (this.locker) + { + if (this.TempData.ContainsKey(name)) + this.TempData[name] = o; + else + this.TempData.Add(name, o); + } + } + + public string INI_Value(string name) + { + try + { + foreach (SectionKey sk in PluginSettings.KeyValues) + if (sk.id == this.ID) + if (sk.Section == this.Section) + if (sk.Key.Trim().ToLower() == name.Trim().ToLower()) + return sk.Value; + } + catch { } + + return string.Empty; + } + + public unsafe void Initialize(Settings _PluginSettings, char* iniFile, char* section, UInt32 id) + { + this.PluginSettings = _PluginSettings; + this._ID = id; + this._INI_File = new string(iniFile); + this._Section = new string(section); + + this.ConfigName = Rainmeter.PluginBridge("GetConfig", this.INI_File); + } + + public string GetVariable(string sVariable) + { + return Rainmeter.PluginBridge("GetVariable", "\"" + this.ConfigName + "\" " + sVariable.Trim() + ""); + } + + public string SetVariable(string sVariable, object oData) + { + return Rainmeter.PluginBridge("SetVariable", "\"" + this.ConfigName + "\" " + sVariable.Trim() + " \"" + oData.ToString().Trim() + "\""); + } + + public string ConfigName = string.Empty; + + public UInt32 ID + { + get + { + return this._ID; + } + set + { + this._ID = value; + } + } + + public string INI_File + { + get + { + return this._INI_File; + } + } + + public string Section + { + get + { + return this._Section; + } + } + } + } + #endregion + } + + public class YourPlugin + { + #region YourPlugin class -- do not modify + + // This class is a simple launcher for your actual code in PluginCode.cs + // + // We make use of non-volatile data and threading to let your work run in another + // thread, making Rainmeter nice and responsive. Checks are automatically performed + // so that overlapping of execution does not occur. + + // Default values of a blank string for GetUpdate() and zero for Update()/Update2() + // are returned. + + public UInt32 Update(Rainmeter.Settings Plugin, UInt32 id) + { + bool bAlreadyRunning = (bool)Plugin.Instances[id].GetTempValue("__RMT_U_AlreadyRunning", false); + if (!bAlreadyRunning) + { + UpdateThread thread_details = new UpdateThread(Plugin.Instances[id]); + Thread thread = new Thread(new ThreadStart(thread_details.Go)); + thread.Start(); + } + + try + { + return (UInt32)Plugin.Instances[id].GetTempValue("__RMT_U_LastValue", 0); + } + catch + { + return 0; + } + } + + private class UpdateThread + { + private Rainmeter.Settings.InstanceSettings Instance = null; + + public UpdateThread(Rainmeter.Settings.InstanceSettings _Instance) + { + this.Instance = _Instance; + } + + public void Go() + { + this.Instance.SetTempValue("__RMT_U_AlreadyRunning", true); + + try + { + this.Instance.SetTempValue("__RMT_U_LastValue", new PluginCode().Update(this.Instance)); + } + catch (Exception ex) + { + Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in GetString(), " + ex.GetType().ToString() + ": " + ex.Message); + } + + this.Instance.SetTempValue("__RMT_U_AlreadyRunning", false); + } + } + + public double Update2(Rainmeter.Settings Plugin, UInt32 id) + { + bool bAlreadyRunning = (bool)Plugin.Instances[id].GetTempValue("__RMT_U2_AlreadyRunning", false); + if (!bAlreadyRunning) + { + Update2Thread thread_details = new Update2Thread(Plugin.Instances[id]); + Thread thread = new Thread(new ThreadStart(thread_details.Go)); + thread.Start(); + } + + try + { + return (double)Plugin.Instances[id].GetTempValue("__RMT_U2_LastValue", 0.0); + } + catch + { + return 0.0; + } + } + + private class Update2Thread + { + private Rainmeter.Settings.InstanceSettings Instance = null; + + public Update2Thread(Rainmeter.Settings.InstanceSettings _Instance) + { + this.Instance = _Instance; + } + + public void Go() + { + this.Instance.SetTempValue("__RMT_U2_AlreadyRunning", true); + + try + { + this.Instance.SetTempValue("__RMT_U2_LastValue", new PluginCode().Update2(this.Instance)); + } + catch (Exception ex) + { + Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in GetString(), " + ex.GetType().ToString() + ": " + ex.Message); + } + + this.Instance.SetTempValue("__RMT_U2_AlreadyRunning", false); + } + } + + public string GetString(Rainmeter.Settings Plugin, UInt32 id) + { + bool bAlreadyRunning = (bool)Plugin.Instances[id].GetTempValue("__RMT_GS_AlreadyRunning", false); + if (!bAlreadyRunning) + { + GetStringThread thread_details = new GetStringThread(Plugin.Instances[id]); + Thread thread = new Thread(new ThreadStart(thread_details.Go)); + thread.Start(); + } + + try + { + return (string)Plugin.Instances[id].GetTempValue("__RMT_GS_LastValue", string.Empty); + } + catch + { + return string.Empty; + } + } + + private class GetStringThread + { + private Rainmeter.Settings.InstanceSettings Instance = null; + + public GetStringThread(Rainmeter.Settings.InstanceSettings _Instance) + { + this.Instance = _Instance; + } + + public void Go() + { + this.Instance.SetTempValue("__RMT_GS_AlreadyRunning", true); + + try + { + this.Instance.SetTempValue("__RMT_GS_LastValue", new PluginCode().GetString(this.Instance)); + } + catch (Exception ex) + { + Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in GetString(), " + ex.GetType().ToString() + ": " + ex.Message); + } + + this.Instance.SetTempValue("__RMT_GS_AlreadyRunning", false); + } + } + + public void ExecuteBang(Rainmeter.Settings Plugin, UInt32 id, string sArguments) + { + bool bAlreadyRunning = (bool)Plugin.Instances[id].GetTempValue("__RMT_EB_AlreadyRunning", false); + if (!bAlreadyRunning) + { + ExecuteBangThread thread_details = new ExecuteBangThread(Plugin.Instances[id], sArguments); + Thread thread = new Thread(new ThreadStart(thread_details.Go)); + thread.Start(); + } + return; + } + + private class ExecuteBangThread + { + private Rainmeter.Settings.InstanceSettings Instance = null; + private string Command = string.Empty; + + public ExecuteBangThread(Rainmeter.Settings.InstanceSettings _Instance, string _Command) + { + this.Instance = _Instance; + this.Command = _Command; + } + + public void Go() + { + this.Instance.SetTempValue("__RMT_EB_AlreadyRunning", true); + + try + { + new PluginCode().ExecuteBang(this.Instance, this.Command); + } + catch (Exception ex) + { + Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in GetString(), " + ex.GetType().ToString() + ": " + ex.Message); + } + + this.Instance.SetTempValue("__RMT_EB_AlreadyRunning", false); + } + } + + #endregion + } +} diff --git a/Plugins/PluginMediaKey/PluginMediaKey.cpp b/Plugins/PluginMediaKey/PluginMediaKey.cpp index ebb30717..b6e5fcfc 100644 --- a/Plugins/PluginMediaKey/PluginMediaKey.cpp +++ b/Plugins/PluginMediaKey/PluginMediaKey.cpp @@ -17,39 +17,17 @@ */ #include -#include #include "../../Library/Export.h" // Rainmeter's exported functions - #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point -/* The exported functions */ -extern "C" -{ -__declspec( dllexport ) UINT Update(UINT id); -__declspec( dllexport ) UINT GetPluginVersion(); -__declspec( dllexport ) LPCTSTR GetPluginAuthor(); -__declspec( dllexport ) void ExecuteBang(LPCTSTR args, UINT id); -} - -void SendKey(WORD key); - -/* - This function is called when new value should be measured. - The function returns the new value. -*/ -UINT Update(UINT id) -{ - return 0; -} - void SendKey(WORD key) { KEYBDINPUT kbi; - kbi.wVk = key; // Provide your own + kbi.wVk = key; kbi.wScan = 0; - kbi.dwFlags = 0; // See docs for flags (mm keys may need Extended key flag) + kbi.dwFlags = 0; kbi.time = 0; - kbi.dwExtraInfo = (ULONG_PTR) GetMessageExtraInfo(); + kbi.dwExtraInfo = (ULONG_PTR)GetMessageExtraInfo(); INPUT input; input.type = INPUT_KEYBOARD; @@ -58,7 +36,7 @@ void SendKey(WORD key) SendInput(1, &input, sizeof(INPUT)); } -void ExecuteBang(LPCTSTR args, UINT id) +PLUGIN_EXPORT void ExecuteBang(LPCTSTR args, UINT id) { if (_wcsicmp(args, L"NextTrack") == 0) { @@ -90,16 +68,6 @@ void ExecuteBang(LPCTSTR args, UINT id) } else { - LSLog(LOG_WARNING, NULL, L"MediaKey.dll: Unknown bang"); + RmLog(LOG_WARNING, L"MediaKey.dll: Unknown bang"); } } - -UINT GetPluginVersion() -{ - return 1000; -} - -LPCTSTR GetPluginAuthor() -{ - return L"Birunthan Mohanathas (www.poiru.net)"; -} \ No newline at end of file diff --git a/Plugins/PluginMediaKey/PluginMediaKey.rc b/Plugins/PluginMediaKey/PluginMediaKey.rc index 6a239a70..d2962a6b 100644 --- a/Plugins/PluginMediaKey/PluginMediaKey.rc +++ b/Plugins/PluginMediaKey/PluginMediaKey.rc @@ -1,10 +1,5 @@ -// Microsoft Developer Studio generated resource script. -// - +#include #include "../../Version.h" -#define APSTUDIO_READONLY_SYMBOLS -#include "windows.h" -#undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // @@ -18,7 +13,7 @@ VS_VERSION_INFO VERSIONINFO #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG #else - FILEFLAGS 0x0L + FILEFLAGS 0x0L #endif FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_DLL @@ -28,11 +23,9 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "FileDescription", "MediaKey Plugin for Rainmeter" VALUE "FileVersion", "1.0.0.0" - VALUE "InternalName", "PluginMediaKey" - VALUE "LegalCopyright", "Copyright (C) 2010 - Birunthan Mohanathas" - VALUE "OriginalFilename", "PluginMediaKey.dll" + VALUE "LegalCopyright", "© 2010 - Birunthan Mohanathas" + VALUE "OriginalFilename", "MediaKey.dll" VALUE "ProductName", "Rainmeter" #ifdef _WIN64 VALUE "ProductVersion", STRPRODUCTVER " (64-bit)" @@ -45,4 +38,4 @@ BEGIN BEGIN VALUE "Translation", 0x409, 1252 END -END +END \ No newline at end of file diff --git a/Plugins/PluginMediaKey/PluginMediaKey.vcxproj b/Plugins/PluginMediaKey/PluginMediaKey.vcxproj index 66d4fc9a..47d66eec 100644 --- a/Plugins/PluginMediaKey/PluginMediaKey.vcxproj +++ b/Plugins/PluginMediaKey/PluginMediaKey.vcxproj @@ -68,10 +68,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ false diff --git a/Plugins/PluginNowPlaying/Internet.cpp b/Plugins/PluginNowPlaying/Internet.cpp index e7bb2e21..67cd0570 100644 --- a/Plugins/PluginNowPlaying/Internet.cpp +++ b/Plugins/PluginNowPlaying/Internet.cpp @@ -37,7 +37,7 @@ void CInternet::Initialize() if (!c_NetHandle) { - LSLog(LOG_ERROR, NULL, L"NowPlaying.dll: Unable to open net handle"); + RmLog(LOG_ERROR, L"NowPlaying.dll: Unable to open net handle"); } } diff --git a/Plugins/PluginNowPlaying/NowPlaying.cpp b/Plugins/PluginNowPlaying/NowPlaying.cpp index db07652e..61229a9e 100644 --- a/Plugins/PluginNowPlaying/NowPlaying.cpp +++ b/Plugins/PluginNowPlaying/NowPlaying.cpp @@ -17,7 +17,6 @@ */ #include "StdAfx.h" -#include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point #include "NowPlaying.h" #include "Internet.h" #include "PlayerAIMP.h" @@ -29,579 +28,535 @@ #include "PlayerWLM.h" #include "PlayerWMP.h" -static std::map g_Measures; +static std::vector g_ParentMeasures; std::wstring g_SettingsFile; HINSTANCE g_Instance = NULL; -/* -** Initialize -** -** Called when the measure is initialized. -** -*/ -UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - if (!g_Instance) + switch (fdwReason) { - // Get path to Plugins.ini (usually %APPDATA%\Rainmeter\Plugins.ini) - std::wstring str = PluginBridge(L"getconfig", iniFile); - if (!str.empty()) - { - str += L" \"SETTINGSPATH\""; - g_SettingsFile = PluginBridge(L"getvariable", str.c_str()); - g_SettingsFile += L"Plugins.ini"; - } + case DLL_PROCESS_ATTACH: + g_Instance = hinstDLL; - g_Instance = instance; - CInternet::Initialize(); + // Disable DLL_THREAD_ATTACH and DLL_THREAD_DETACH notification calls + DisableThreadLibraryCalls(hinstDLL); + break; } - // Data is stored in two structs: ChildMeasure and ParentMeasure. ParentMeasure is created for measures - // with PlayerName=someplayer. ChildMeasure is created for all measures and points to ParentMeasure as + return TRUE; +} + +PLUGIN_EXPORT void Initialize(void** data) +{ + Measure* measure = new Measure; + *data = measure; + + if (g_SettingsFile.empty()) + { + g_SettingsFile = RmGetSettingsFile(); + CInternet::Initialize(); + } +} + +PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) +{ + Measure* measure = (Measure*)data; + + // Data is stored in two structs: Measure and ParentMeasure. ParentMeasure is created for measures + // with PlayerName=someplayer. Measure is created for all measures and points to ParentMeasure as // referenced in PlayerName=[section]. - ChildMeasure* child = new ChildMeasure; - UINT maxValue = 0; // Read settings from the ini-file - LPCTSTR str = ReadConfigString(section, L"PlayerName", NULL); - if (str) + void* skin = RmGetSkin(rm); + LPCWSTR str = RmReadString(rm, L"PlayerName", L"", FALSE); + if (str[0] == L'[') { - if (str[0] == L'[') + if (measure->parent) + { + // Don't let a measure measure change its parent + } + else { // PlayerName starts with [ so use referenced section - int len = wcslen(str) - 2; - if (len > 0) + ++str; + int len = wcslen(str); + if (len > 0 && str[len - 1] == L']') { - std::map::iterator it = g_Measures.begin(); - for ( ; it != g_Measures.end(); ++it) + --len; + + std::vector::iterator iter = g_ParentMeasures.begin(); + for ( ; iter != g_ParentMeasures.end(); ++iter) { - if (wcsncmp(&str[1], it->second->parent->name.c_str(), len) == 0 && - wcscmp(iniFile, it->second->parent->iniFile.c_str()) == 0) + if (skin == (*iter)->skin && + wcsncmp(str, (*iter)->ownerName, len) == 0) { // Use same ParentMeasure as referenced section - child->parent = it->second->parent; - ++child->parent->childCount; + measure->parent = (*iter); + ++measure->parent->measureCount; + break; } } - - if (!child->parent) + + if (!measure->parent) { // The referenced section doesn't exist std::wstring error = L"NowPlaying.dll: Invalid PlayerName="; - error += str; + error.append(str - 1, len + 2); error += L" in ["; - error += section; + error += RmGetMeasureName(rm); error += L"]"; - LSLog(LOG_WARNING, NULL, error.c_str()); - delete child; - return maxValue; + RmLog(LOG_WARNING, error.c_str()); + return; } } } - else - { - // ParentMeasure is created when PlayerName is an actual player (and not a reference) - ParentMeasure* parent = new ParentMeasure; - parent->name = section; - parent->iniFile = iniFile; - - if (_wcsicmp(L"AIMP", str) == 0) - { - parent->player = CPlayerAIMP::Create(); - } - else if (_wcsicmp(L"CAD", str) == 0) - { - parent->player = CPlayerCAD::Create(); - } - else if (_wcsicmp(L"foobar2000", str) == 0) - { - parent->player = CPlayerFoobar::Create(); - } - else if (_wcsicmp(L"iTunes", str) == 0) - { - parent->player = CPlayerITunes::Create(); - } - else if (_wcsicmp(L"MediaMonkey", str) == 0) - { - parent->player = CPlayerWinamp::Create(WA_MEDIAMONKEY); - } - else if (_wcsicmp(L"Spotify", str) == 0) - { - parent->player = CPlayerSpotify::Create(); - } - else if (_wcsicmp(L"WinAmp", str) == 0) - { - parent->player = CPlayerWinamp::Create(WA_WINAMP); - } - else if (_wcsicmp(L"WLM", str) == 0) - { - parent->player = CPlayerWLM::Create(); - } - else if (_wcsicmp(L"WMP", str) == 0) - { - parent->player = CPlayerWMP::Create(); - } - else - { - std::wstring error = L"NowPlaying.dll: Invalid PlayerName="; - error += str; - error += L" in ["; - error += section; - error += L"]"; - LSLog(LOG_ERROR, NULL, error.c_str()); - delete parent; - delete child; - return maxValue; - } - - parent->id = id; - parent->player->AddInstance(); - parent->playerPath = ReadConfigString(section, L"PlayerPath", L""); - parent->trackChangeAction = ReadConfigString(section, L"TrackChangeAction", L""); - - if (!parent->trackChangeAction.empty()) - { - // Get window handle to send the bang later on - parent->window = FindMeterWindow(parent->iniFile); - parent->trackCount = 1; - } - - str = ReadConfigString(section, L"DisableLeadingZero", L"0"); - if (str) - { - parent->disableLeadingZero = (1 == _wtoi(str)); - } - - child->parent = parent; - } - } - - str = ReadConfigString(section, L"PlayerType", NULL); - if (str) - { - if (_wcsicmp(L"ARTIST", str) == 0) - { - child->type = MEASURE_ARTIST; - } - else if (_wcsicmp(L"TITLE", str) == 0) - { - child->type = MEASURE_TITLE; - } - else if (_wcsicmp(L"ALBUM", str) == 0) - { - child->type = MEASURE_ALBUM; - } - else if (_wcsicmp(L"COVER", str) == 0) - { - child->type = MEASURE_COVER; - } - else if (_wcsicmp(L"DURATION", str) == 0) - { - child->type = MEASURE_DURATION; - } - else if (_wcsicmp(L"POSITION", str) == 0) - { - child->type = MEASURE_POSITION; - } - else if (_wcsicmp(L"PROGRESS", str) == 0) - { - child->type = MEASURE_PROGRESS; - maxValue = 100; - } - else if (_wcsicmp(L"RATING", str) == 0) - { - child->type = MEASURE_RATING; - maxValue = 5; - } - else if (_wcsicmp(L"STATE", str) == 0) - { - child->type = MEASURE_STATE; - } - else if (_wcsicmp(L"STATUS", str) == 0) - { - child->type = MEASURE_STATUS; - } - else if (_wcsicmp(L"VOLUME", str) == 0) - { - child->type = MEASURE_VOLUME; - maxValue = 100; - } - else if (_wcsicmp(L"SHUFFLE", str) == 0) - { - child->type = MEASURE_SHUFFLE; - } - else if (_wcsicmp(L"REPEAT", str) == 0) - { - child->type = MEASURE_REPEAT; - } - else if (_wcsicmp(L"LYRICS", str) == 0) - { - LSLog(LOG_WARNING, NULL, L"NowPlaying.dll: Using undocumented PlayerType=LYRICS!"); - child->type = MEASURE_LYRICS; - } - else if (_wcsicmp(L"FILE", str) == 0) - { - child->type = MEASURE_FILE; - } - else - { - std::wstring error = L"NowPlaying.dll: Invalid PlayerType="; - error += str; - error += L" in ["; - error += section; - error += L"]"; - LSLog(LOG_WARNING, NULL, error.c_str()); - } - - child->parent->player->AddMeasure(child->type); - } - - g_Measures[id] = child; - return maxValue; -} - -/* -** Finalize -** -** Called when the measure is destroyed (during refresh/quit). -** -*/ -void Finalize(HMODULE instance, UINT id) -{ - std::map::const_iterator i = g_Measures.find(id); - if (i != g_Measures.end()) - { - ChildMeasure* child = (*i).second; - ParentMeasure* parent = child->parent; - CPlayer* player = parent->player; - - if (--parent->childCount == 0) - { - player->RemoveInstance(); - delete parent; - } - - delete child; - g_Measures.erase(i); - - if (g_Measures.empty()) - { - g_Instance = NULL; - CInternet::Finalize(); - } - } -} - -/* -** Update -** -** Called on each update. -** -*/ -UINT Update(UINT id) -{ - std::map::const_iterator i = g_Measures.find(id); - if (i != g_Measures.end()) - { - ChildMeasure* child = (*i).second; - ParentMeasure* parent = child->parent; - CPlayer* player = parent->player; - - // Only allow parent measure to update - if (parent->id == id) - { - player->UpdateMeasure(); - - // Execute TrackChangeAction= if necessary - if (!parent->trackChangeAction.empty() && - parent->trackCount != player->GetTrackCount()) - { - ExecuteCommand(parent->trackChangeAction, parent->window); - parent->trackCount = player->GetTrackCount(); - } - } - - switch (child->type) - { - case MEASURE_DURATION: - return player->GetDuration(); - - case MEASURE_POSITION: - return player->GetPosition(); - - case MEASURE_PROGRESS: - if (player->GetDuration()) - { - return (player->GetPosition() * 100) / player->GetDuration(); - } - return 0; - - case MEASURE_RATING: - return player->GetRating(); - - case MEASURE_VOLUME: - return player->GetVolume(); - - case MEASURE_STATE: - return (UINT)player->GetState(); - - case MEASURE_STATUS: - return (UINT)player->IsInitialized(); - - case MEASURE_SHUFFLE: - return (UINT)player->GetShuffle(); - - case MEASURE_REPEAT: - return (UINT)player->GetRepeat(); - } - - return 0; - } - - return 1; -} - -/* -** GetString -** -** Called when a string value is needed. -** -*/ -LPCTSTR GetString(UINT id, UINT flags) -{ - std::map::const_iterator i = g_Measures.find(id); - if (i != g_Measures.end()) - { - ChildMeasure* child = (*i).second; - ParentMeasure* parent = child->parent; - CPlayer* player = parent->player; - static WCHAR buffer[32]; - - switch (child->type) - { - case MEASURE_ARTIST: - return player->GetArtist(); - - case MEASURE_TITLE: - return player->GetTitle(); - - case MEASURE_ALBUM: - return player->GetAlbum(); - - case MEASURE_LYRICS: - return player->GetLyrics(); - - case MEASURE_COVER: - return player->GetCoverPath(); - - case MEASURE_FILE: - return player->GetFilePath(); - - case MEASURE_DURATION: - SecondsToTime(player->GetDuration(), parent->disableLeadingZero, buffer); - return buffer; - - case MEASURE_POSITION: - SecondsToTime(player->GetPosition(), parent->disableLeadingZero, buffer); - return buffer; - - case MEASURE_PROGRESS: - _itow_s(player->GetDuration() ? ((player->GetPosition() * 100) / player->GetDuration()) : 0, buffer, 10); - return buffer; - - case MEASURE_RATING: - _itow_s(player->GetRating(), buffer, 10); - return buffer; - - case MEASURE_VOLUME: - _itow_s(player->GetVolume(), buffer, 10); - return buffer; - - case MEASURE_STATE: - _itow_s(player->GetState(), buffer, 10); - return buffer; - - case MEASURE_STATUS: - _itow_s((int)player->IsInitialized(), buffer, 10); - return buffer; - - case MEASURE_SHUFFLE: - _itow_s((int)player->GetShuffle(), buffer, 10); - return buffer; - - case MEASURE_REPEAT: - _itow_s((int)player->GetRepeat(), buffer, 10); - return buffer; - } } else { - return L"Error: Invalid player name"; + // ParentMeasure is created when PlayerName is an actual player (and not a reference) + ParentMeasure* parent = measure->parent; + CPlayer* oldPlayer = NULL; + if (parent) + { + if (parent->data != data) + { + // Don't let a measure-only measure become a parent measure + return; + } + + oldPlayer = parent->player; + } + else + { + parent = new ParentMeasure; + g_ParentMeasures.push_back(parent); + parent->data = data; + parent->skin = skin; + parent->ownerName = RmGetMeasureName(rm); + measure->parent = parent; + } + + if (_wcsicmp(L"AIMP", str) == 0) + { + parent->player = CPlayerAIMP::Create(); + } + else if (_wcsicmp(L"CAD", str) == 0) + { + parent->player = CPlayerCAD::Create(); + } + else if (_wcsicmp(L"foobar2000", str) == 0) + { + parent->player = CPlayerFoobar::Create(); + } + else if (_wcsicmp(L"iTunes", str) == 0) + { + parent->player = CPlayerITunes::Create(); + } + else if (_wcsicmp(L"MediaMonkey", str) == 0) + { + parent->player = CPlayerWinamp::Create(WA_MEDIAMONKEY); + } + else if (_wcsicmp(L"Spotify", str) == 0) + { + parent->player = CPlayerSpotify::Create(); + } + else if (_wcsicmp(L"WinAmp", str) == 0) + { + parent->player = CPlayerWinamp::Create(WA_WINAMP); + } + else if (_wcsicmp(L"WLM", str) == 0) + { + parent->player = CPlayerWLM::Create(); + } + else if (_wcsicmp(L"WMP", str) == 0) + { + parent->player = CPlayerWMP::Create(); + } + else + { + std::wstring error = L"NowPlaying.dll: Invalid PlayerName="; + error += str; + error += L" in ["; + error += parent->ownerName; + error += L"]"; + RmLog(LOG_ERROR, error.c_str()); + return; + } + + parent->player->AddInstance(); + parent->playerPath = RmReadString(rm, L"PlayerPath", L"", TRUE); + parent->trackChangeAction = RmReadString(rm, L"TrackChangeAction", L"", TRUE); + parent->disableLeadingZero = RmReadInt(rm, L"DisableLeadingZero", 0); + + if (oldPlayer) + { + // Remove instance here so that player doesn't have to reinitialize if PlayerName was + // not changed. + oldPlayer->RemoveInstance(); + } + } + + str = RmReadString(rm, L"PlayerType", L""); + if (_wcsicmp(L"ARTIST", str) == 0) + { + measure->type = MEASURE_ARTIST; + } + else if (_wcsicmp(L"TITLE", str) == 0) + { + measure->type = MEASURE_TITLE; + } + else if (_wcsicmp(L"ALBUM", str) == 0) + { + measure->type = MEASURE_ALBUM; + } + else if (_wcsicmp(L"COVER", str) == 0) + { + measure->type = MEASURE_COVER; + } + else if (_wcsicmp(L"DURATION", str) == 0) + { + measure->type = MEASURE_DURATION; + } + else if (_wcsicmp(L"POSITION", str) == 0) + { + measure->type = MEASURE_POSITION; + } + else if (_wcsicmp(L"PROGRESS", str) == 0) + { + measure->type = MEASURE_PROGRESS; + *maxValue = 100.0; + } + else if (_wcsicmp(L"RATING", str) == 0) + { + measure->type = MEASURE_RATING; + *maxValue = 5.0; + } + else if (_wcsicmp(L"STATE", str) == 0) + { + measure->type = MEASURE_STATE; + } + else if (_wcsicmp(L"STATUS", str) == 0) + { + measure->type = MEASURE_STATUS; + } + else if (_wcsicmp(L"VOLUME", str) == 0) + { + measure->type = MEASURE_VOLUME; + *maxValue = 100.0; + } + else if (_wcsicmp(L"SHUFFLE", str) == 0) + { + measure->type = MEASURE_SHUFFLE; + } + else if (_wcsicmp(L"REPEAT", str) == 0) + { + measure->type = MEASURE_REPEAT; + } + else if (_wcsicmp(L"LYRICS", str) == 0) + { + RmLog(LOG_WARNING, L"NowPlaying.dll: Using undocumented PlayerType=LYRICS!"); + measure->type = MEASURE_LYRICS; + } + else if (_wcsicmp(L"FILE", str) == 0) + { + measure->type = MEASURE_FILE; + } + else + { + std::wstring error = L"NowPlaying.dll: Invalid PlayerType="; + error += str; + error += L" in ["; + error += RmGetMeasureName(rm); + error += L"]"; + RmLog(LOG_WARNING, error.c_str()); + } + + measure->parent->player->AddMeasure(measure->type); +} + +PLUGIN_EXPORT double Update(void* data) +{ + Measure* measure = (Measure*)data; + ParentMeasure* parent = measure->parent; + if (!parent) return 0.0; + + CPlayer* player = parent->player; + + // Only allow parent measure to update + if (parent->data == data) + { + player->UpdateMeasure(); + + // Execute TrackChangeAction= if necessary + if (!parent->trackChangeAction.empty() && + parent->trackCount != player->GetTrackCount()) + { + RmExecute(parent->skin, parent->trackChangeAction.c_str()); + parent->trackCount = player->GetTrackCount(); + } + } + + switch (measure->type) + { + case MEASURE_DURATION: + return player->GetDuration(); + + case MEASURE_POSITION: + return player->GetPosition(); + + case MEASURE_PROGRESS: + if (player->GetDuration()) + { + return (player->GetPosition() * 100) / player->GetDuration(); + } + return 0.0; + + case MEASURE_RATING: + return player->GetRating(); + + case MEASURE_VOLUME: + return player->GetVolume(); + + case MEASURE_STATE: + return (UINT)player->GetState(); + + case MEASURE_STATUS: + return (UINT)player->IsInitialized(); + + case MEASURE_SHUFFLE: + return (UINT)player->GetShuffle(); + + case MEASURE_REPEAT: + return (UINT)player->GetRepeat(); + } + + return 0.0; +} + +PLUGIN_EXPORT LPCWSTR GetString(void* data) +{ + Measure* measure = (Measure*)data; + ParentMeasure* parent = measure->parent; + if (!parent) return L"Invalid player"; + + const CPlayer* player = parent->player; + static WCHAR buffer[32]; + + switch (measure->type) + { + case MEASURE_ARTIST: + return player->GetArtist(); + + case MEASURE_TITLE: + return player->GetTitle(); + + case MEASURE_ALBUM: + return player->GetAlbum(); + + case MEASURE_LYRICS: + return player->GetLyrics(); + + case MEASURE_COVER: + return player->GetCoverPath(); + + case MEASURE_FILE: + return player->GetFilePath(); + + case MEASURE_DURATION: + SecondsToTime(player->GetDuration(), parent->disableLeadingZero, buffer); + return buffer; + + case MEASURE_POSITION: + SecondsToTime(player->GetPosition(), parent->disableLeadingZero, buffer); + return buffer; + + case MEASURE_PROGRESS: + _itow_s(player->GetDuration() ? ((player->GetPosition() * 100) / player->GetDuration()) : 0, buffer, 10); + return buffer; + + case MEASURE_RATING: + _itow_s(player->GetRating(), buffer, 10); + return buffer; + + case MEASURE_VOLUME: + _itow_s(player->GetVolume(), buffer, 10); + return buffer; + + case MEASURE_STATE: + _itow_s(player->GetState(), buffer, 10); + return buffer; + + case MEASURE_STATUS: + _itow_s((int)player->IsInitialized(), buffer, 10); + return buffer; + + case MEASURE_SHUFFLE: + _itow_s((int)player->GetShuffle(), buffer, 10); + return buffer; + + case MEASURE_REPEAT: + _itow_s((int)player->GetRepeat(), buffer, 10); + return buffer; } return NULL; } -/* -** ExecuteBang -** -** Called when a !RainmeterPluginBang is executed. -** -*/ -void ExecuteBang(LPCTSTR bang, UINT id) +PLUGIN_EXPORT void Finalize(void* data) { - std::map::const_iterator i = g_Measures.find(id); - if (i != g_Measures.end()) + Measure* measure = (Measure*)data; + ParentMeasure* parent = measure->parent; + if (parent) { - ChildMeasure* child = (*i).second; - ParentMeasure* parent = child->parent; CPlayer* player = parent->player; - - if (!player->IsInitialized()) + if (--parent->measureCount == 0) { - if (_wcsicmp(bang, L"OpenPlayer") == 0 || _wcsicmp(bang, L"TogglePlayer") == 0) + player->RemoveInstance(); + delete parent; + + std::vector::iterator iter = std::find(g_ParentMeasures.begin(), g_ParentMeasures.end(), parent); + g_ParentMeasures.erase(iter); + + if (g_ParentMeasures.empty()) { - player->OpenPlayer(parent->playerPath); + CInternet::Finalize(); } } - else if (_wcsicmp(bang, L"Pause") == 0) - { - player->Pause(); - } - else if (_wcsicmp(bang, L"Play") == 0) - { - player->Play(); - } - else if (_wcsicmp(bang, L"PlayPause") == 0) - { - (player->GetState() != PLAYER_PLAYING) ? player->Play() : player->Pause(); - } - else if (_wcsicmp(bang, L"Next") == 0) - { - player->Next(); - } - else if (_wcsicmp(bang, L"Previous") == 0) - { - player->Previous(); - } - else if (_wcsicmp(bang, L"Stop") == 0) - { - player->Stop(); - } - else if (_wcsicmp(bang, L"OpenPlayer") == 0) + } + + delete measure; +} + +PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) +{ + Measure* measure = (Measure*)data; + ParentMeasure* parent = measure->parent; + if (!parent) return; + + CPlayer* player = parent->player; + + if (!player->IsInitialized()) + { + if (_wcsicmp(args, L"OpenPlayer") == 0 || _wcsicmp(args, L"TogglePlayer") == 0) { player->OpenPlayer(parent->playerPath); } - else if (_wcsicmp(bang, L"ClosePlayer") == 0 || _wcsicmp(bang, L"TogglePlayer") == 0) - { - player->ClosePlayer(); - } - else - { - LPCTSTR arg = wcschr(bang, L' '); + } + else if (_wcsicmp(args, L"Pause") == 0) + { + player->Pause(); + } + else if (_wcsicmp(args, L"Play") == 0) + { + player->Play(); + } + else if (_wcsicmp(args, L"PlayPause") == 0) + { + (player->GetState() != STATE_PLAYING) ? player->Play() : player->Pause(); + } + else if (_wcsicmp(args, L"Next") == 0) + { + player->Next(); + } + else if (_wcsicmp(args, L"Previous") == 0) + { + player->Previous(); + } + else if (_wcsicmp(args, L"Stop") == 0) + { + player->Stop(); + } + else if (_wcsicmp(args, L"OpenPlayer") == 0) + { + player->OpenPlayer(parent->playerPath); + } + else if (_wcsicmp(args, L"ClosePlayer") == 0 || _wcsicmp(args, L"TogglePlayer") == 0) + { + player->ClosePlayer(); + } + else + { + LPCWSTR arg = wcschr(args, L' '); - if (arg) + if (arg) + { + ++arg; // Skip the space + + if (wcsnicmp(args, L"SetPosition", 11) == 0) { - ++arg; // Skip the space - - if (wcsnicmp(bang, L"SetPosition", 11) == 0) + int position = (_wtoi(arg) * (int)player->GetDuration()) / 100; + if (arg[0] == L'+' || arg[0] == L'-') { - int position = (_wtoi(arg) * (int)player->GetDuration()) / 100; - if (arg[0] == L'+' || arg[0] == L'-') - { - position += player->GetPosition(); - } - - player->SetPosition(position); + position += player->GetPosition(); } - else if (wcsnicmp(bang, L"SetRating", 9) == 0) + + player->SetPosition(position); + } + else if (wcsnicmp(args, L"SetRating", 9) == 0) + { + int rating = _wtoi(arg); + if (rating >= 0 && rating <= 5) { - int rating = _wtoi(arg); - if (rating >= 0 && rating <= 5) - { - player->SetRating(rating); - } + player->SetRating(rating); } - else if (wcsnicmp(bang, L"SetVolume", 9) == 0) + } + else if (wcsnicmp(args, L"SetVolume", 9) == 0) + { + int volume = _wtoi(arg); + if (arg[0] == L'+' || arg[0] == L'-') { - int volume = _wtoi(arg); - if (arg[0] == L'+' || arg[0] == L'-') - { - // Relative to current volume - volume += player->GetVolume(); - } + // Relative to current volume + volume += player->GetVolume(); + } - if (volume < 0) - { - volume = 0; - } - else if (volume > 100) - { - volume = 100; - } - player->SetVolume(volume);; - } - else if (wcsnicmp(bang, L"SetShuffle", 9) == 0) + if (volume < 0) { - int state = _wtoi(arg); - if (state == -1) - { - player->SetShuffle(!player->GetShuffle()); - } - else if (state == 0 || state == 1) - { - player->SetShuffle((bool)state); - } + volume = 0; } - else if (wcsnicmp(bang, L"SetRepeat", 9) == 0) + else if (volume > 100) { - int state = _wtoi(arg); - if (state == -1) - { - player->SetRepeat(!player->GetRepeat()); - } - else if (state == 0 || state == 1) - { - player->SetRepeat((bool)state); - } + volume = 100; } - else + player->SetVolume(volume);; + } + else if (wcsnicmp(args, L"SetShuffle", 9) == 0) + { + int state = _wtoi(arg); + if (state == -1) { - LSLog(LOG_WARNING, NULL, L"NowPlaying.dll: Unknown bang"); + player->SetShuffle(!player->GetShuffle()); + } + else if (state == 0 || state == 1) + { + player->SetShuffle((bool)state); + } + } + else if (wcsnicmp(args, L"SetRepeat", 9) == 0) + { + int state = _wtoi(arg); + if (state == -1) + { + player->SetRepeat(!player->GetRepeat()); + } + else if (state == 0 || state == 1) + { + player->SetRepeat((bool)state); } } else { - LSLog(LOG_WARNING, NULL, L"NowPlaying.dll: Unknown bang"); + RmLog(LOG_WARNING, L"NowPlaying.dll: Unknown args"); } } + else + { + RmLog(LOG_WARNING, L"NowPlaying.dll: Unknown args"); + } } } -/* -** GetPluginVersion -** -** Returns the version number of the plugin. -** -*/ -UINT GetPluginVersion() -{ - // Major * 1000 + Minor - return 1001; -} - -/* -** GetPluginAuthor -** -** Returns the author of the plugin for the About dialog. -** -*/ -LPCTSTR GetPluginAuthor() -{ - return L"Birunthan Mohanathas (www.poiru.net)"; -} - void SecondsToTime(UINT seconds, bool leadingZero, WCHAR* buffer) { int hours = seconds; @@ -626,51 +581,3 @@ void SecondsToTime(UINT seconds, bool leadingZero, WCHAR* buffer) _snwprintf_s(buffer, 32, _TRUNCATE, leadingZero ? L"%i:%02i" : L"%02i:%02i", mins, secs); } } - -void ExecuteCommand(std::wstring& command, HWND wnd) -{ - COPYDATASTRUCT cds; - cds.dwData = 1; - cds.cbData = (DWORD)(command.size() + 1) * sizeof(WCHAR); - cds.lpData = (void*)command.c_str(); - - // Send bang to the Rainmeter window - SendMessage(wnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&cds); -} - -bool BelongToSameProcess(HWND wnd) -{ - DWORD procId = 0; - GetWindowThreadProcessId(wnd, &procId); - - return (procId == GetCurrentProcessId()); -} - -HWND FindMeterWindow(HWND parent) -{ - HWND wnd = NULL; - while (wnd = FindWindowEx(parent, wnd, L"RainmeterMeterWindow", NULL)) - { - if (BelongToSameProcess(wnd)) - { - return wnd; - } - } - - return NULL; -} - -HWND FindMeterWindow(const std::wstring& iniFile) -{ - std::wstring str = PluginBridge(L"getconfig", iniFile.c_str()); - if (!str.empty()) - { - str = PluginBridge(L"getwindow", str.c_str()); - if (str != L"error") - { - return (HWND)UlongToPtr(wcstoul(str.c_str(), NULL, 10)); - } - } - - return FindMeterWindow(NULL); // Use old way to find -} diff --git a/Plugins/PluginNowPlaying/NowPlaying.h b/Plugins/PluginNowPlaying/NowPlaying.h index 0e7d198e..015a489c 100644 --- a/Plugins/PluginNowPlaying/NowPlaying.h +++ b/Plugins/PluginNowPlaying/NowPlaying.h @@ -24,51 +24,37 @@ struct ParentMeasure { ParentMeasure() : - player(NULL), - childCount(1), - trackCount(0), + player(), + data(), + skin(), + ownerName(), + measureCount(1), + trackCount(1), disableLeadingZero(false) {} - UINT id; - UINT childCount; - UINT trackCount; CPlayer* player; - HWND window; - std::wstring name; - std::wstring iniFile; + void* data; + void* skin; + LPCWSTR ownerName; std::wstring trackChangeAction; std::wstring playerPath; + UINT measureCount; + UINT trackCount; bool disableLeadingZero; }; -struct ChildMeasure +struct Measure { - ChildMeasure() : - type(MEASURE_NONE), - parent(NULL) + Measure() : + parent(), + type(MEASURE_NONE) {} - MEASURETYPE type; ParentMeasure* parent; + MeasureType type; }; void SecondsToTime(UINT seconds, bool leadingZero, WCHAR* buffer); -void ExecuteCommand(std::wstring& command, HWND wnd); -bool BelongToSameProcess(HWND wnd); -HWND FindMeterWindow(HWND parent); -HWND FindMeterWindow(const std::wstring& iniFile); - -/* The exported functions */ -extern "C" -{ -__declspec( dllexport ) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); -__declspec( dllexport ) void Finalize(HMODULE instance, UINT id); -__declspec( dllexport ) UINT Update(UINT id); -__declspec( dllexport ) LPCTSTR GetString(UINT id, UINT flags); -__declspec( dllexport ) LPCTSTR GetPluginAuthor(); -__declspec( dllexport ) UINT GetPluginVersion(); -__declspec( dllexport ) void ExecuteBang(LPCTSTR bang, UINT id); -} #endif diff --git a/Plugins/PluginNowPlaying/Player.cpp b/Plugins/PluginNowPlaying/Player.cpp index 5254363b..e0e2db65 100644 --- a/Plugins/PluginNowPlaying/Player.cpp +++ b/Plugins/PluginNowPlaying/Player.cpp @@ -162,7 +162,7 @@ void CPlayer::FindLyrics() } else { - LSLog(LOG_DEBUG, NULL, L"NowPlaying.dll: Failed to start lyrics thread"); + RmLog(LOG_DEBUG, L"NowPlaying.dll: Failed to start lyrics thread"); } } } @@ -214,7 +214,7 @@ unsigned __stdcall CPlayer::LyricsThreadProc(void* pParam) */ void CPlayer::ClearData() { - m_State = PLAYER_STOPPED; + m_State = STATE_STOPPED; m_Artist.clear(); m_Album.clear(); m_Title.clear(); diff --git a/Plugins/PluginNowPlaying/Player.h b/Plugins/PluginNowPlaying/Player.h index 2d91cd84..f72156ff 100644 --- a/Plugins/PluginNowPlaying/Player.h +++ b/Plugins/PluginNowPlaying/Player.h @@ -25,14 +25,14 @@ #include "Internet.h" #include "Lyrics.h" -enum PLAYSTATE +enum StateType { - PLAYER_STOPPED, - PLAYER_PLAYING, - PLAYER_PAUSED + STATE_STOPPED, + STATE_PLAYING, + STATE_PAUSED }; -enum MEASURETYPE +enum MeasureType { MEASURE_NONE = 0x00000000, MEASURE_ARTIST = 0x00000001, @@ -64,8 +64,8 @@ public: void AddMeasure(INT type); virtual void UpdateData() = 0; - bool IsInitialized() { return m_Initialized; } - UINT GetTrackCount() { return m_TrackCount; } + bool IsInitialized() const { return m_Initialized; } + UINT GetTrackCount() const { return m_TrackCount; } void FindCover(); void FindLyrics(); @@ -83,19 +83,19 @@ public: virtual void OpenPlayer(std::wstring& path) {} virtual void ClosePlayer() {} - PLAYSTATE GetState() { return m_State; } - LPCTSTR GetArtist() { return m_Artist.c_str(); } - LPCTSTR GetAlbum() { return m_Album.c_str(); } - LPCTSTR GetTitle() { return m_Title.c_str(); } - LPCTSTR GetLyrics() { return m_Lyrics.c_str(); } - LPCTSTR GetCoverPath() { return m_CoverPath.c_str(); } - LPCTSTR GetFilePath() { return m_FilePath.c_str(); } - UINT GetDuration() { return m_Duration; } - UINT GetPosition() { return m_Position; } - UINT GetRating() { return m_Rating; } - UINT GetVolume() { return m_Volume; } - bool GetShuffle() { return m_Shuffle; } - bool GetRepeat() { return m_Repeat; } + StateType GetState() const { return m_State; } + LPCTSTR GetArtist() const{ return m_Artist.c_str(); } + LPCTSTR GetAlbum() const{ return m_Album.c_str(); } + LPCTSTR GetTitle() const{ return m_Title.c_str(); } + LPCTSTR GetLyrics() const{ return m_Lyrics.c_str(); } + LPCTSTR GetCoverPath() const{ return m_CoverPath.c_str(); } + LPCTSTR GetFilePath() const{ return m_FilePath.c_str(); } + UINT GetDuration() const{ return m_Duration; } + UINT GetPosition() const{ return m_Position; } + UINT GetRating() const{ return m_Rating; } + UINT GetVolume() const{ return m_Volume; } + bool GetShuffle() const { return m_Shuffle; } + bool GetRepeat() const { return m_Repeat; } protected: void ClearData(); @@ -107,7 +107,7 @@ protected: std::wstring m_TempCoverPath; INT m_Measures; - PLAYSTATE m_State; + StateType m_State; std::wstring m_Artist; std::wstring m_Title; std::wstring m_Album; diff --git a/Plugins/PluginNowPlaying/PlayerAIMP.cpp b/Plugins/PluginNowPlaying/PlayerAIMP.cpp index c8888bb0..bb6ba8c7 100644 --- a/Plugins/PluginNowPlaying/PlayerAIMP.cpp +++ b/Plugins/PluginNowPlaying/PlayerAIMP.cpp @@ -124,8 +124,8 @@ void CPlayerAIMP::UpdateData() } // If initialized - m_State = (PLAYSTATE)SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_STATUS_GET, AIMP_STS_Player); - if (m_State == PLAYER_STOPPED) + m_State = (StateType)SendMessage(m_Window, WM_AIMP_COMMAND, WM_AIMP_STATUS_GET, AIMP_STS_Player); + if (m_State == STATE_STOPPED) { // Make sure AIMP is still active if (!IsWindow(m_Window)) @@ -270,7 +270,7 @@ void CPlayerAIMP::SetPosition(int position) void CPlayerAIMP::SetRating(int rating) { // Set rating through the AIMP Winamp API - if (m_State != PLAYER_STOPPED) + if (m_State != STATE_STOPPED) { SendMessage(m_WinampWindow, WM_WA_IPC, rating, IPC_SETRATING); m_Rating = rating; diff --git a/Plugins/PluginNowPlaying/PlayerCAD.cpp b/Plugins/PluginNowPlaying/PlayerCAD.cpp index 4d8285d5..bb0c6815 100644 --- a/Plugins/PluginNowPlaying/PlayerCAD.cpp +++ b/Plugins/PluginNowPlaying/PlayerCAD.cpp @@ -178,9 +178,9 @@ void CPlayerCAD::Initialize() } SendMessage(m_PlayerWindow, WM_USER, (WPARAM)m_Window, IPC_SET_CALLBACK_HWND); - m_State = (PLAYSTATE)SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_STATE); + m_State = (StateType)SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_STATE); - if (m_State != PLAYER_STOPPED) + if (m_State != STATE_STOPPED) { SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_CURRENT_TRACK); } @@ -235,8 +235,8 @@ LRESULT CALLBACK CPlayerCAD::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM case IPC_STATE_CHANGED_NOTIFICATION: { - player->m_State = (PLAYSTATE)wParam; - if (player->m_State == PLAYER_STOPPED) + player->m_State = (StateType)wParam; + if (player->m_State == STATE_STOPPED) { player->ClearData(); } @@ -363,9 +363,9 @@ LRESULT CALLBACK CPlayerCAD::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM { player->m_Initialized = true; player->m_ExtendedAPI = (classSz && wcscmp(classSz, L"CD Art Display IPC Class") == 0); - player->m_State = (PLAYSTATE)SendMessage(player->m_PlayerWindow, WM_USER, 0, IPC_GET_STATE); + player->m_State = (StateType)SendMessage(player->m_PlayerWindow, WM_USER, 0, IPC_GET_STATE); - if (player->m_State != PLAYER_STOPPED) + if (player->m_State != STATE_STOPPED) { PostMessage(player->m_PlayerWindow, WM_USER, 0, IPC_GET_CURRENT_TRACK); } @@ -388,7 +388,7 @@ LRESULT CALLBACK CPlayerCAD::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM */ void CPlayerCAD::UpdateData() { - if (m_State != PLAYER_STOPPED) + if (m_State != STATE_STOPPED) { m_Position = SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_POSITION); m_Volume = SendMessage(m_PlayerWindow, WM_USER, 0, IPC_GET_VOLUME); diff --git a/Plugins/PluginNowPlaying/PlayerFoobar.cpp b/Plugins/PluginNowPlaying/PlayerFoobar.cpp index cba7d690..c43359ea 100644 --- a/Plugins/PluginNowPlaying/PlayerFoobar.cpp +++ b/Plugins/PluginNowPlaying/PlayerFoobar.cpp @@ -155,8 +155,8 @@ LRESULT CALLBACK CPlayerFoobar::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR case FOO_STATECHANGE: { - PLAYSTATE ps = (PLAYSTATE)wParam; - if (ps == PLAYER_STOPPED) + StateType ps = (StateType)wParam; + if (ps == STATE_STOPPED) { player->ClearData(); } @@ -199,9 +199,9 @@ LRESULT CALLBACK CPlayerFoobar::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR if (cds->dwData == FOO_TRACKCHANGE) { - if (player->m_State != PLAYER_PLAYING) + if (player->m_State != STATE_PLAYING) { - player->m_State = PLAYER_PLAYING; + player->m_State = STATE_PLAYING; } // In the format "TITLE ARTIST ALBUM LENGTH RATING" (seperated by \t) @@ -331,7 +331,7 @@ void CPlayerFoobar::Pause() */ void CPlayerFoobar::Play() { - SendMessage(m_FooWindow, WM_USER, 0, (m_State == PLAYER_PAUSED) ? FOO_PLAYPAUSE : FOO_PLAY); + SendMessage(m_FooWindow, WM_USER, 0, (m_State == STATE_PAUSED) ? FOO_PLAYPAUSE : FOO_PLAY); } /* diff --git a/Plugins/PluginNowPlaying/PlayerITunes.cpp b/Plugins/PluginNowPlaying/PlayerITunes.cpp index 35536be5..44d5e78f 100644 --- a/Plugins/PluginNowPlaying/PlayerITunes.cpp +++ b/Plugins/PluginNowPlaying/PlayerITunes.cpp @@ -224,13 +224,13 @@ void CPlayerITunes::Initialize() if (position != 0) { - m_State = PLAYER_PAUSED; + m_State = STATE_PAUSED; OnTrackChange(); } } else if (state == ITPlayerStatePlaying) { - m_State = PLAYER_PLAYING; + m_State = STATE_PLAYING; OnTrackChange(); } } @@ -337,7 +337,7 @@ bool CPlayerITunes::CheckWindow() */ void CPlayerITunes::UpdateData() { - if ((m_Initialized || CheckWindow()) && m_State != PLAYER_STOPPED) + if ((m_Initialized || CheckWindow()) && m_State != STATE_STOPPED) { long position; m_iTunes->get_PlayerPosition(&position); @@ -487,12 +487,12 @@ void CPlayerITunes::OnStateChange(bool playing) { if (playing) { - m_State = PLAYER_PLAYING; + m_State = STATE_PLAYING; } else { // Guess if paused or stopped from track time - m_State = (m_Position == 0) ? PLAYER_STOPPED : PLAYER_PAUSED; + m_State = (m_Position == 0) ? STATE_STOPPED : STATE_PAUSED; } } diff --git a/Plugins/PluginNowPlaying/PlayerSpotify.cpp b/Plugins/PluginNowPlaying/PlayerSpotify.cpp index c346346f..c13213bf 100644 --- a/Plugins/PluginNowPlaying/PlayerSpotify.cpp +++ b/Plugins/PluginNowPlaying/PlayerSpotify.cpp @@ -110,7 +110,7 @@ void CPlayerSpotify::UpdateData() if (track != m_Title || artist != m_Artist) { - m_State = PLAYER_PLAYING; + m_State = STATE_PLAYING; m_Title = track; m_Artist = artist; ++m_TrackCount; @@ -125,7 +125,7 @@ void CPlayerSpotify::UpdateData() } else if (IsWindow(m_Window)) { - m_State = PLAYER_PAUSED; + m_State = STATE_PAUSED; } else { diff --git a/Plugins/PluginNowPlaying/PlayerWLM.cpp b/Plugins/PluginNowPlaying/PlayerWLM.cpp index b61f7eb5..2fbdbab6 100644 --- a/Plugins/PluginNowPlaying/PlayerWLM.cpp +++ b/Plugins/PluginNowPlaying/PlayerWLM.cpp @@ -117,7 +117,7 @@ LRESULT CALLBACK CPlayerWLM::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM if (playing) { ++player->m_TrackCount; - player->m_State = PLAYER_PLAYING; + player->m_State = STATE_PLAYING; data.erase(0, 3); // Get rid of the status // TODO: Handle invalid diff --git a/Plugins/PluginNowPlaying/PlayerWMP.cpp b/Plugins/PluginNowPlaying/PlayerWMP.cpp index 5c8aa28b..cc82c89a 100644 --- a/Plugins/PluginNowPlaying/PlayerWMP.cpp +++ b/Plugins/PluginNowPlaying/PlayerWMP.cpp @@ -116,15 +116,15 @@ void CPlayerWMP::CRemoteHost::PlayStateChange(long NewState) break; case wmppsPaused: - m_Player->m_State = PLAYER_PAUSED; + m_Player->m_State = STATE_PAUSED; break; case wmppsPlaying: - if (m_Player->m_State == PLAYER_STOPPED) + if (m_Player->m_State == STATE_STOPPED) { m_Player->m_TrackChanged = true; } - m_Player->m_State = PLAYER_PLAYING; + m_Player->m_State = STATE_PLAYING; break; default: @@ -329,14 +329,14 @@ void CPlayerWMP::Initialize() m_IPlayer->get_playState(&state); if (state == wmppsPlaying) { - m_State = PLAYER_PLAYING; + m_State = STATE_PLAYING; } else if (state == wmppsPaused) { - m_State = PLAYER_PAUSED; + m_State = STATE_PAUSED; } - if (m_State != PLAYER_STOPPED) + if (m_State != STATE_STOPPED) { m_TrackChanged = true; } @@ -380,7 +380,7 @@ void CPlayerWMP::UpdateData() m_ISettings->get_volume(&volume); m_Volume = (UINT)volume; - if (m_State != PLAYER_STOPPED) + if (m_State != STATE_STOPPED) { double position; m_IControls->get_currentPosition(&position); @@ -520,7 +520,7 @@ void CPlayerWMP::Stop() { m_IControls->stop(); // TODO: FIXME - m_State = PLAYER_STOPPED; + m_State = STATE_STOPPED; } /* @@ -564,7 +564,7 @@ void CPlayerWMP::SetPosition(int position) */ void CPlayerWMP::SetRating(int rating) { - if (m_State != PLAYER_STOPPED) + if (m_State != STATE_STOPPED) { CComPtr spMedia; m_IPlayer->get_currentMedia(&spMedia); diff --git a/Plugins/PluginNowPlaying/PlayerWinamp.cpp b/Plugins/PluginNowPlaying/PlayerWinamp.cpp index 34200ab7..bcc1775a 100644 --- a/Plugins/PluginNowPlaying/PlayerWinamp.cpp +++ b/Plugins/PluginNowPlaying/PlayerWinamp.cpp @@ -125,7 +125,7 @@ void CPlayerWinamp::UpdateData() if (m_WinampHandle) CloseHandle(m_WinampHandle); } - if (m_State != PLAYER_STOPPED) + if (m_State != STATE_STOPPED) { ClearData(); } @@ -135,7 +135,7 @@ void CPlayerWinamp::UpdateData() } else { - m_State = (playing == 1) ? PLAYER_PLAYING : PLAYER_PAUSED; + m_State = (playing == 1) ? STATE_PLAYING : STATE_PAUSED; m_Position = SendMessage(m_Window, WM_WA_IPC, 0, IPC_GETOUTPUTTIME) / 1000; // ms to secs m_Volume = (SendMessage(m_Window, WM_WA_IPC, -666, IPC_SETVOLUME) * 100) / 255; // 0 - 255 to 0 - 100 } diff --git a/Plugins/PluginNowPlaying/PluginNowPlaying.rc b/Plugins/PluginNowPlaying/PluginNowPlaying.rc index 7127e057..9af74db7 100644 --- a/Plugins/PluginNowPlaying/PluginNowPlaying.rc +++ b/Plugins/PluginNowPlaying/PluginNowPlaying.rc @@ -1,10 +1,5 @@ -// Microsoft Developer Studio generated resource script. -// - +#include #include "../../Version.h" -#define APSTUDIO_READONLY_SYMBOLS -#include "windows.h" -#undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // @@ -20,7 +15,7 @@ VS_VERSION_INFO VERSIONINFO #else FILEFLAGS 0x0L #endif - FILEOS VOS_NT_WINDOWS32 + FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_DLL FILESUBTYPE VFT_UNKNOWN BEGIN @@ -28,10 +23,8 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "FileDescription", "NowPlaying Plugin for Rainmeter" VALUE "FileVersion", "1.1.3.7" - VALUE "InternalName", "NowPlaying" - VALUE "LegalCopyright", "Copyright (C) 2011 - Birunthan Mohanathas" + VALUE "LegalCopyright", "© 2011 - Birunthan Mohanathas" VALUE "OriginalFilename", "NowPlaying.dll" VALUE "ProductName", "Rainmeter" #ifdef _WIN64 diff --git a/Plugins/PluginNowPlaying/PluginNowPlaying.vcxproj b/Plugins/PluginNowPlaying/PluginNowPlaying.vcxproj index 35ea6fef..aa1af183 100644 --- a/Plugins/PluginNowPlaying/PluginNowPlaying.vcxproj +++ b/Plugins/PluginNowPlaying/PluginNowPlaying.vcxproj @@ -68,10 +68,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ false diff --git a/Plugins/PluginPerfMon/PluginPerfMon.vcxproj b/Plugins/PluginPerfMon/PluginPerfMon.vcxproj index 89b6c2fb..6089e08b 100644 --- a/Plugins/PluginPerfMon/PluginPerfMon.vcxproj +++ b/Plugins/PluginPerfMon/PluginPerfMon.vcxproj @@ -73,10 +73,10 @@ false $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true PerfMon PerfMon PerfMon diff --git a/Plugins/PluginPing/Ping.cpp b/Plugins/PluginPing/Ping.cpp index 8dd7e8fc..d78ddfc6 100644 --- a/Plugins/PluginPing/Ping.cpp +++ b/Plugins/PluginPing/Ping.cpp @@ -17,29 +17,13 @@ */ #include -#include -#include -#include -#include -#include #include -#include -#include +#include #include "../../Library/Export.h" // Rainmeter's exported functions #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point -/* The exported functions */ -extern "C" -{ -__declspec( dllexport ) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); -__declspec( dllexport ) void Finalize(HMODULE instance, UINT id); -__declspec( dllexport ) double Update2(UINT id); -__declspec( dllexport ) UINT GetPluginVersion(); -__declspec( dllexport ) LPCTSTR GetPluginAuthor(); -} - -struct pingData +struct MeasureData { IPAddr destAddr; DWORD timeout; @@ -48,275 +32,164 @@ struct pingData DWORD updateCounter; HANDLE threadHandle; double value; + + MeasureData() : + destAddr(), + timeout(), + timeoutValue(), + updateRate(), + updateCounter(), + threadHandle(), + value() + { + } }; -typedef struct tagIPINFO -{ - u_char nTtl; // Time To Live - u_char nTos; // Type Of Service - u_char nIPFlags; // IP flags - u_char nOptSize; // Size of options data - u_char FAR* pOptions; // Options data buffer - -} IPINFO; - -typedef IPINFO* PIPINFO; - -static std::map g_Values; static CRITICAL_SECTION g_CriticalSection; -static bool g_Initialized = false; -static HINSTANCE g_ICMPInstance = NULL; +static UINT g_Instances = 0; -typedef HANDLE (WINAPI *IcmpCreateFile)(VOID); -typedef BOOL (WINAPI *IcmpCloseHandle)(HANDLE); -typedef DWORD (WINAPI *IcmpSendEcho)(HANDLE, DWORD, LPVOID, WORD, PIPINFO, LPVOID, DWORD, DWORD); -typedef DWORD (WINAPI *IcmpSendEcho2)(HANDLE, HANDLE, FARPROC, PVOID, IPAddr, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD); - -static IcmpCreateFile g_IcmpCreateFile = NULL; -static IcmpCloseHandle g_IcmpCloseHandle = NULL; -static IcmpSendEcho g_IcmpSendEcho = NULL; -static IcmpSendEcho2 g_IcmpSendEcho2 = NULL; - -std::string ConvertToAscii(LPCTSTR str) +PLUGIN_EXPORT void Initialize(void** data) { - std::string szAscii; + MeasureData* measure = new MeasureData; + *data = measure; - if (str && *str) - { - int strLen = (int)wcslen(str); - int bufLen = WideCharToMultiByte(CP_ACP, 0, str, strLen, NULL, 0, NULL, NULL); - if (bufLen > 0) - { - szAscii.resize(bufLen); - WideCharToMultiByte(CP_ACP, 0, str, strLen, &szAscii[0], bufLen, NULL, NULL); - } - } - return szAscii; -} - -/* - This function is called when the measure is initialized. - The function must return the maximum value that can be measured. - The return value can also be 0, which means that Rainmeter will - track the maximum value automatically. The parameters for this - function are: - - instance The instance of this DLL - iniFile The name of the ini-file (usually Rainmeter.ini) - section The name of the section in the ini-file for this measure - id The identifier for the measure. This is used to identify the measures that use the same plugin. -*/ -UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) -{ - bool valid = false; - pingData* pData = new pingData; - - if (!g_Initialized) + if (g_Instances == 0) { InitializeCriticalSection(&g_CriticalSection); - - g_ICMPInstance = LoadLibrary(L"ICMP.DLL"); - - if (g_ICMPInstance) - { - g_IcmpCreateFile = (IcmpCreateFile)GetProcAddress(g_ICMPInstance, "IcmpCreateFile"); - g_IcmpCloseHandle = (IcmpCloseHandle)GetProcAddress(g_ICMPInstance, "IcmpCloseHandle"); - g_IcmpSendEcho = (IcmpSendEcho)GetProcAddress(g_ICMPInstance,"IcmpSendEcho"); - g_IcmpSendEcho2 = (IcmpSendEcho2)GetProcAddress(g_ICMPInstance,"IcmpSendEcho2"); - } - - g_Initialized = true; } - memset(pData, 0, sizeof(pingData)); + ++g_Instances; +} - /* Read our own settings from the ini-file */ - LPCTSTR data = ReadConfigString(section, L"DestAddress", NULL); - if (data) +PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) +{ + MeasureData* measure = (MeasureData*)data; + + LPCWSTR value = RmReadString(rm, L"DestAddress", L""); + if (*value) { - std::string szData = ConvertToAscii(data); - - pData->destAddr = inet_addr(szData.c_str()); - if (pData->destAddr == INADDR_NONE) + int strLen = (int)wcslen(value) + 1; + int bufLen = WideCharToMultiByte(CP_ACP, 0, value, strLen, NULL, 0, NULL, NULL); + if (bufLen > 0) { - WSADATA wsaData; - if (WSAStartup(0x0101, &wsaData) == 0) - { - LPHOSTENT pHost; + char* buffer = new char[bufLen]; + WideCharToMultiByte(CP_ACP, 0, value, strLen, buffer, bufLen, NULL, NULL); - pHost = gethostbyname(szData.c_str()); - if (pHost) + measure->destAddr = inet_addr(buffer); + if (measure->destAddr == INADDR_NONE) + { + WSADATA wsaData; + if (WSAStartup(0x0101, &wsaData) == 0) { - pData->destAddr = *(DWORD*)pHost->h_addr; + LPHOSTENT pHost = gethostbyname(buffer); + if (pHost) + { + measure->destAddr = *(DWORD*)pHost->h_addr; + } + else + { + RmLog(LOG_WARNING, L"PingPlugin.dll: Unable to get host by name"); + } + + WSACleanup(); } else { - LSLog(LOG_WARNING, NULL, L"PingPlugin.dll: Unable to get host by name"); + RmLog(LOG_WARNING, L"PingPlugin.dll: Unable to start WSA"); } + } - WSACleanup(); - } - else - { - LSLog(LOG_WARNING, NULL, L"PingPlugin.dll: Unable to start WSA"); - } + delete [] buffer; } - valid = true; } - data = ReadConfigString(section, L"UpdateRate", L"32"); - if (data) - { - pData->updateRate = _wtoi(data); - } - - data = ReadConfigString(section, L"Timeout", L"30000"); - if (data) - { - pData->timeout = _wtoi(data); - } - - data = ReadConfigString(section, L"TimeoutValue", L"30000"); - if (data) - { - pData->timeoutValue = wcstod(data, NULL); - } - - if (valid) - { - g_Values[id] = pData; - } - - return pData->timeout; + measure->updateRate = RmReadInt(rm, L"UpdateRate", 32); + measure->timeout = RmReadInt(rm, L"Timeout", 30000); + measure->timeoutValue = RmReadDouble(rm, L"TimeoutValue", 30000.0); } DWORD WINAPI NetworkThreadProc(LPVOID pParam) { - if (g_IcmpCreateFile && g_IcmpCloseHandle && g_IcmpSendEcho) + MeasureData* measure = (MeasureData*)pParam; + + const DWORD replySize = sizeof(ICMP_ECHO_REPLY) + 32; + BYTE* reply = new BYTE[replySize]; + + HANDLE hIcmpFile = IcmpCreateFile(); + + if (hIcmpFile != INVALID_HANDLE_VALUE) { - pingData* pData = (pingData*)pParam; - - const DWORD replySize = sizeof(ICMP_ECHO_REPLY) + 32; - BYTE* reply = new BYTE[replySize]; - - HANDLE hIcmpFile; - hIcmpFile = g_IcmpCreateFile(); - - if (hIcmpFile != INVALID_HANDLE_VALUE) - { - DWORD res = g_IcmpSendEcho( - hIcmpFile, - pData->destAddr, - NULL, - 0, - NULL, - reply, - replySize, - pData->timeout); - - g_IcmpCloseHandle(hIcmpFile); - } - - EnterCriticalSection(&g_CriticalSection); - ICMP_ECHO_REPLY* pReply = (ICMP_ECHO_REPLY*)reply; - if (pReply->Status == IP_REQ_TIMED_OUT) - { - pData->value = pData->timeoutValue; - } - else - { - pData->value = pReply->RoundTripTime; - } - - delete [] reply; - CloseHandle(pData->threadHandle); - pData->threadHandle = 0; - LeaveCriticalSection(&g_CriticalSection); + IcmpSendEcho(hIcmpFile, measure->destAddr, NULL, 0, NULL, reply, replySize, measure->timeout); + IcmpCloseHandle(hIcmpFile); } - return 0; // thread completed successfully + + EnterCriticalSection(&g_CriticalSection); + + ICMP_ECHO_REPLY* pReply = (ICMP_ECHO_REPLY*)reply; + if (pReply->Status == IP_REQ_TIMED_OUT) + { + measure->value = measure->timeoutValue; + } + else + { + measure->value = pReply->RoundTripTime; + } + + delete [] reply; + + CloseHandle(measure->threadHandle); + measure->threadHandle = NULL; + + LeaveCriticalSection(&g_CriticalSection); + + return 0; } -/* -This function is called when new value should be measured. -The function returns the new value. -*/ -double Update2(UINT id) +PLUGIN_EXPORT double Update(void* data) { + MeasureData* measure = (MeasureData*)data; double value = 0.0; - std::map::iterator i = g_Values.find(id); - if (i != g_Values.end()) + EnterCriticalSection(&g_CriticalSection); + value = measure->value; + LeaveCriticalSection(&g_CriticalSection); + + if (measure->threadHandle == NULL) { - pingData* pData = (*i).second; - - EnterCriticalSection(&g_CriticalSection); - value = pData->value; - LeaveCriticalSection(&g_CriticalSection); - - if (pData->threadHandle == NULL) + if (measure->updateCounter == 0) { - if (pData->updateCounter == 0) - { - // Launch a new thread to fetch the web data - DWORD id; - pData->threadHandle = CreateThread(NULL, 0, NetworkThreadProc, pData, 0, &id); - } + // Launch a new thread to fetch the web data + DWORD id; + measure->threadHandle = CreateThread(NULL, 0, NetworkThreadProc, measure, 0, &id); + } - pData->updateCounter++; - if (pData->updateCounter >= pData->updateRate) - { - pData->updateCounter = 0; - } + measure->updateCounter++; + if (measure->updateCounter >= measure->updateRate) + { + measure->updateCounter = 0; } } + return value; } -/* - If the measure needs to free resources before quitting. - The plugin can export Finalize function, which is called - when Rainmeter quits (or refreshes). -*/ -void Finalize(HMODULE instance, UINT id) +PLUGIN_EXPORT void Finalize(void* data) { - std::map::iterator i1 = g_Values.find(id); - if (i1 != g_Values.end()) - { - EnterCriticalSection(&g_CriticalSection); - if ((*i1).second->threadHandle) - { - // Should really wait until the thread finishes instead terminating it... - TerminateThread((*i1).second->threadHandle, 0); - } - LeaveCriticalSection(&g_CriticalSection); + MeasureData* measure = (MeasureData*)data; - delete (*i1).second; - g_Values.erase(i1); + EnterCriticalSection(&g_CriticalSection); + if (measure->threadHandle) + { + // Should really wait until the thread finishes instead terminating it... + TerminateThread(measure->threadHandle, 0); + } + LeaveCriticalSection(&g_CriticalSection); + + --g_Instances; + if (g_Instances == 0) + { + DeleteCriticalSection(&g_CriticalSection); } - // Last instance deletes the critical section - if (g_Values.empty()) - { - if (g_ICMPInstance) - { - FreeLibrary(g_ICMPInstance); - g_ICMPInstance = NULL; - } - - if (g_Initialized) - { - DeleteCriticalSection(&g_CriticalSection); - g_Initialized = false; - } - } -} - -UINT GetPluginVersion() -{ - return 1002; -} - -LPCTSTR GetPluginAuthor() -{ - return L"Rainy (rainy@iki.fi)"; + delete measure; } \ No newline at end of file diff --git a/Plugins/PluginPing/PluginPing.rc b/Plugins/PluginPing/PluginPing.rc index 5f45320a..3e087998 100644 --- a/Plugins/PluginPing/PluginPing.rc +++ b/Plugins/PluginPing/PluginPing.rc @@ -1,10 +1,5 @@ -// Microsoft Developer Studio generated resource script. -// - +#include #include "../../Version.h" -#define APSTUDIO_READONLY_SYMBOLS -#include "windows.h" -#undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // @@ -18,7 +13,7 @@ VS_VERSION_INFO VERSIONINFO #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG #else - FILEFLAGS 0x0L + FILEFLAGS 0x0L #endif FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_DLL @@ -28,10 +23,8 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "FileDescription", "Ping Plugin for Rainmeter" VALUE "FileVersion", "1.2.0.0" - VALUE "InternalName", "PluginPing" - VALUE "LegalCopyright", "Copyright (C) 2010 - Rainy" + VALUE "LegalCopyright", "© 2010 - Rainy" VALUE "OriginalFilename", "PluginPing.dll" VALUE "ProductName", "Rainmeter" #ifdef _WIN64 diff --git a/Plugins/PluginPing/PluginPing.vcxproj b/Plugins/PluginPing/PluginPing.vcxproj index 436c6c86..91d77fbd 100644 --- a/Plugins/PluginPing/PluginPing.vcxproj +++ b/Plugins/PluginPing/PluginPing.vcxproj @@ -73,10 +73,10 @@ false $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true PingPlugin PingPlugin PingPlugin @@ -115,7 +115,7 @@ 0x0409 - Rainmeter.lib;Ws2_32.lib;%(AdditionalDependencies) + Rainmeter.lib;Ws2_32.lib;Iphlpapi.lib;%(AdditionalDependencies) ../../TestBench/x32/Release/Plugins/PingPlugin.dll true ..\..\Library\x32\$(Configuration);%(AdditionalLibraryDirectories) @@ -161,7 +161,7 @@ /LTCG %(AdditionalOptions) - Rainmeter.lib;Ws2_32.lib;%(AdditionalDependencies) + Rainmeter.lib;Ws2_32.lib;Iphlpapi.lib;%(AdditionalDependencies) ../../TestBench/x64/Release/Plugins/PingPlugin.dll true ..\..\Library\x64\$(Configuration);%(AdditionalLibraryDirectories) @@ -204,7 +204,7 @@ 0x0409 - Rainmeter.lib;Ws2_32.lib;%(AdditionalDependencies) + Rainmeter.lib;Ws2_32.lib;Iphlpapi.lib;%(AdditionalDependencies) ../../TestBench/x32/Debug/Plugins/PingPlugin.dll true true @@ -245,7 +245,7 @@ 0x0409 - Rainmeter.lib;Ws2_32.lib;%(AdditionalDependencies) + Rainmeter.lib;Ws2_32.lib;Iphlpapi.lib;%(AdditionalDependencies) ../../TestBench/x64/Debug/Plugins/PingPlugin.dll true true diff --git a/Plugins/PluginPower/PluginPower.vcxproj b/Plugins/PluginPower/PluginPower.vcxproj index 674ffcf7..74cf4480 100644 --- a/Plugins/PluginPower/PluginPower.vcxproj +++ b/Plugins/PluginPower/PluginPower.vcxproj @@ -67,10 +67,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ false @@ -120,6 +120,8 @@ .\x32/Debug/PowerPlugin.lib MachineX86 ..\..\Library\x32\$(Configuration);%(AdditionalLibraryDirectories) + Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies) + PowrProf.dll @@ -160,6 +162,8 @@ .\x64/Debug/PowerPlugin.lib MachineX64 ..\..\Library\x64\$(Configuration);%(AdditionalLibraryDirectories) + Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies) + PowrProf.dll @@ -195,7 +199,7 @@ 0x0409 - Rainmeter.lib;%(AdditionalDependencies) + Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies) ../../TestBench/x32/Release/Plugins/PowerPlugin.dll true ..\..\Library\x32\$(Configuration);%(AdditionalLibraryDirectories) @@ -206,6 +210,7 @@ .rdata=.text true true + PowrProf.dll @@ -241,7 +246,7 @@ /LTCG %(AdditionalOptions) - Rainmeter.lib;%(AdditionalDependencies) + Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies) ../../TestBench/x64/Release/Plugins/PowerPlugin.dll true ..\..\Library\x64\$(Configuration);%(AdditionalLibraryDirectories) @@ -251,6 +256,7 @@ .rdata=.text true true + PowrProf.dll diff --git a/Plugins/PluginPower/PowerPlugin.cpp b/Plugins/PluginPower/PowerPlugin.cpp index a7ecfb84..12bcadf1 100644 --- a/Plugins/PluginPower/PowerPlugin.cpp +++ b/Plugins/PluginPower/PowerPlugin.cpp @@ -17,13 +17,12 @@ */ #include -#include -#include -#include -#include #include +#include +#include +#include +#include "../../Library/RawString.h" #include "../../Library/Export.h" // Rainmeter's exported functions - #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point typedef struct _PROCESSOR_POWER_INFORMATION @@ -36,20 +35,7 @@ typedef struct _PROCESSOR_POWER_INFORMATION ULONG CurrentIdleState; } PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION; -typedef LONG (WINAPI *FPCALLNTPOWERINFORMATION)(POWER_INFORMATION_LEVEL, PVOID, ULONG, PVOID, ULONG); - -/* The exported functions */ -extern "C" -{ -__declspec( dllexport ) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); -__declspec( dllexport ) void Finalize(HMODULE instance, UINT id); -__declspec( dllexport ) LPCTSTR GetString(UINT id, UINT flags); -__declspec( dllexport ) double Update2(UINT id); -__declspec( dllexport ) UINT GetPluginVersion(); -__declspec( dllexport ) LPCTSTR GetPluginAuthor(); -} - -enum POWER_STATE +enum MeasureType { POWER_UNKNOWN, POWER_ACLINE, @@ -61,272 +47,187 @@ enum POWER_STATE POWER_HZ }; -std::map g_States; -std::map g_Formats; -HINSTANCE hDLL = NULL; -int g_Instances, g_NumOfProcessors = 0; -FPCALLNTPOWERINFORMATION fpCallNtPowerInformation = NULL; +struct MeasureData +{ + MeasureType type; + CRawString format; + + MeasureData() : type(POWER_UNKNOWN) {} +}; + +UINT g_NumOfProcessors = 0; void NullCRTInvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved) { // Do nothing. } -/* - This function is called when the measure is initialized. - The function must return the maximum value that can be measured. - The return value can also be 0, which means that Rainmeter will - track the maximum value automatically. The parameters for this - function are: - - instance The instance of this DLL - iniFile The name of the ini-file (usually Rainmeter.ini) - section The name of the section in the ini-file for this measure - id The identifier for the measure. This is used to identify the measures that use the same plugin. -*/ -UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) +PLUGIN_EXPORT void Initialize(void** data) { - g_Instances++; - if (hDLL == NULL) + MeasureData* measure = new MeasureData; + *data = measure; + + if (!g_NumOfProcessors) { - hDLL = LoadLibrary(L"powrprof.dll"); - if (hDLL) - { - fpCallNtPowerInformation = (FPCALLNTPOWERINFORMATION)GetProcAddress(hDLL, "CallNtPowerInformation"); - } + SYSTEM_INFO si; + GetSystemInfo(&si); + g_NumOfProcessors = (UINT)si.dwNumberOfProcessors; } - - POWER_STATE powerState = POWER_UNKNOWN; - - SYSTEM_INFO systemInfo = {0}; - GetSystemInfo(&systemInfo); - g_NumOfProcessors = (int)systemInfo.dwNumberOfProcessors; - - /* Read our own settings from the ini-file */ - LPCTSTR type = ReadConfigString(section, L"PowerState", L""); - if (type) - { - if (_wcsicmp(L"ACLINE", type) == 0) - { - powerState = POWER_ACLINE; - } - else if (_wcsicmp(L"STATUS", type) == 0) - { - powerState = POWER_STATUS; - } - else if (_wcsicmp(L"STATUS2", type) == 0) - { - powerState = POWER_STATUS2; - } - else if (_wcsicmp(L"LIFETIME", type) == 0) - { - powerState= POWER_LIFETIME; - - LPCTSTR format = ReadConfigString(section, L"Format", L"%H:%M"); - if (format) - { - g_Formats[id] = format; - } - } - else if (_wcsicmp(L"MHZ", type) == 0) - { - powerState= POWER_MHZ; - } - else if (_wcsicmp(L"HZ", type) == 0) - { - powerState= POWER_HZ; - } - else if (_wcsicmp(L"PERCENT", type) == 0) - { - powerState = POWER_PERCENT; - } - - g_States[id] = powerState; - } - - switch(powerState) - { - case POWER_ACLINE: - return 1; - - case POWER_STATUS: - return 4; - - case POWER_STATUS2: - return 255; - - case POWER_LIFETIME: - { - SYSTEM_POWER_STATUS status; - if (GetSystemPowerStatus(&status)) - { - return status.BatteryFullLifeTime; - } - } - break; - - case POWER_PERCENT: - return 100; - } - - return 0; } -/* - This function is called when new value should be measured. - The function returns the new value. -*/ -double Update2(UINT id) +PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { - SYSTEM_POWER_STATUS status; - if (GetSystemPowerStatus(&status)) + MeasureData* measure = (MeasureData*)data; + + LPCWSTR value = RmReadString(rm, L"PowerState", L""); + if (_wcsicmp(L"ACLINE", value) == 0) { - std::map::iterator i = g_States.find(id); - if (i != g_States.end()) + measure->type = POWER_ACLINE; + *maxValue = 1.0; + } + else if (_wcsicmp(L"STATUS", value) == 0) + { + measure->type = POWER_STATUS; + *maxValue = 4.0; + } + else if (_wcsicmp(L"STATUS2", value) == 0) + { + measure->type = POWER_STATUS2; + *maxValue = 255.0; + } + else if (_wcsicmp(L"LIFETIME", value) == 0) + { + measure->type= POWER_LIFETIME; + + value = RmReadString(rm, L"Format", L"%H:%M"); + measure->format = value; + + SYSTEM_POWER_STATUS sps; + if (GetSystemPowerStatus(&sps)) { - switch ((*i).second) + *maxValue = sps.BatteryFullLifeTime; + } + } + else if (_wcsicmp(L"MHZ", value) == 0) + { + measure->type = POWER_MHZ; + } + else if (_wcsicmp(L"HZ", value) == 0) + { + measure->type = POWER_HZ; + } + else if (_wcsicmp(L"PERCENT", value) == 0) + { + measure->type = POWER_PERCENT; + *maxValue = 100.0; + } +} + +PLUGIN_EXPORT double Update(void* data) +{ + MeasureData* measure = (MeasureData*)data; + + SYSTEM_POWER_STATUS sps; + if (GetSystemPowerStatus(&sps)) + { + switch (measure->type) + { + case POWER_ACLINE: + return sps.ACLineStatus == 1 ? 1.0 : 0.0; + + case POWER_STATUS: + if (sps.BatteryFlag & 128) { - case POWER_ACLINE: - return status.ACLineStatus == 1 ? 1 : 0; + return 0.0; // No battery + } + else if (sps.BatteryFlag & 8) + { + return 1.0; // Charging + } + else if (sps.BatteryFlag & 4) + { + return 2.0; // Critical + } + else if (sps.BatteryFlag & 2) + { + return 3.0; // Low + } + else if (sps.BatteryFlag & 1) + { + return 4.0; // High + } + break; - case POWER_STATUS: - if (status.BatteryFlag & 128) - { - return 0; // No battery - } - else if (status.BatteryFlag & 8) - { - return 1; // Charging - } - else if (status.BatteryFlag & 4) - { - return 2; // Critical - } - else if (status.BatteryFlag & 2) - { - return 3; // Low - } - else if (status.BatteryFlag & 1) - { - return 4; // High - } - break; + case POWER_STATUS2: + return sps.BatteryFlag; - case POWER_STATUS2: - return status.BatteryFlag; + case POWER_LIFETIME: + return sps.BatteryLifeTime; - case POWER_LIFETIME: - return status.BatteryLifeTime; + case POWER_PERCENT: + return sps.BatteryLifePercent == 255 ? 100.0 : sps.BatteryLifePercent; - case POWER_PERCENT: - return status.BatteryLifePercent > 100 ? 100 : status.BatteryLifePercent; - - case POWER_MHZ: - case POWER_HZ: - if (fpCallNtPowerInformation && g_NumOfProcessors > 0) - { - PROCESSOR_POWER_INFORMATION* ppi = new PROCESSOR_POWER_INFORMATION[g_NumOfProcessors]; - memset(ppi, 0, sizeof(PROCESSOR_POWER_INFORMATION) * g_NumOfProcessors); - fpCallNtPowerInformation(ProcessorInformation, NULL, 0, ppi, sizeof(PROCESSOR_POWER_INFORMATION) * g_NumOfProcessors); - double value = ((*i).second == POWER_MHZ) ? ppi[0].CurrentMhz : ppi[0].CurrentMhz * 1000000.0; - delete [] ppi; - return value; - } + case POWER_MHZ: + case POWER_HZ: + if (g_NumOfProcessors > 0) + { + PROCESSOR_POWER_INFORMATION* ppi = new PROCESSOR_POWER_INFORMATION[g_NumOfProcessors]; + memset(ppi, 0, sizeof(PROCESSOR_POWER_INFORMATION) * g_NumOfProcessors); + CallNtPowerInformation(ProcessorInformation, NULL, 0, ppi, sizeof(PROCESSOR_POWER_INFORMATION) * g_NumOfProcessors); + double value = (measure->type == POWER_MHZ) ? ppi[0].CurrentMhz : ppi[0].CurrentMhz * 1000000.0; + delete [] ppi; + return value; } } } - return 0; + return 0.0; } -/* - This function is called when the value should be - returned as a string. -*/ -LPCTSTR GetString(UINT id, UINT flags) +PLUGIN_EXPORT LPCWSTR GetString(void* data) { static WCHAR buffer[128]; - std::map::iterator i = g_States.find(id); - if (i != g_States.end()) + MeasureData* measure = (MeasureData*)data; + + if (measure->type == POWER_LIFETIME) { - if ((*i).second == POWER_LIFETIME) + SYSTEM_POWER_STATUS sps; + if (GetSystemPowerStatus(&sps)) { - SYSTEM_POWER_STATUS status; - if (GetSystemPowerStatus(&status)) + // Change it to time string + if (sps.BatteryLifeTime == -1) { - // Change it to time string - if (status.BatteryLifeTime == -1) + return L"Unknown"; + } + else + { + tm time = {0}; + time.tm_sec = sps.BatteryLifeTime % 60; + time.tm_min = (sps.BatteryLifeTime / 60) % 60; + time.tm_hour = sps.BatteryLifeTime / 60 / 60; + + _invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(NullCRTInvalidParameterHandler); + _CrtSetReportMode(_CRT_ASSERT, 0); + + errno = 0; + wcsftime(buffer, 128, measure->format.c_str(), &time); + if (errno == EINVAL) { - return L"Unknown"; + buffer[0] = L'\0'; } - else - { - std::map::iterator iter = g_Formats.find(id); - if (iter != g_Formats.end()) - { - tm time = {0}; - time.tm_sec = status.BatteryLifeTime % 60; - time.tm_min = (status.BatteryLifeTime / 60) % 60; - time.tm_hour = status.BatteryLifeTime / 60 / 60; - _invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(NullCRTInvalidParameterHandler); - _CrtSetReportMode(_CRT_ASSERT, 0); + _set_invalid_parameter_handler(oldHandler); - errno = 0; - wcsftime(buffer, 128, (*iter).second.c_str(), &time); - if (errno == EINVAL) - { - buffer[0] = L'\0'; - } - - _set_invalid_parameter_handler(oldHandler); - } - else - { - wsprintf(buffer, L"%i:%02i:%02i", status.BatteryLifeTime / 60 / 60, (status.BatteryLifeTime / 60) % 60, status.BatteryLifeTime % 60); - } - return buffer; - } + return buffer; } } } + return NULL; } -/* - If the measure needs to free resources before quitting. - The plugin can export Finalize function, which is called - when Rainmeter quits (or refreshes). -*/ -void Finalize(HMODULE instance, UINT id) +PLUGIN_EXPORT void Finalize(void* data) { - std::map::iterator i = g_States.find(id); - if (i != g_States.end()) - { - g_States.erase(i); - } - - std::map::iterator i2 = g_Formats.find(id); - if (i2 != g_Formats.end()) - { - g_Formats.erase(i2); - } - - g_Instances--; - if (hDLL != NULL && g_Instances == 0) - { - FreeLibrary(hDLL); - hDLL = NULL; - fpCallNtPowerInformation = NULL; - } + MeasureData* measure = (MeasureData*)data; + delete measure; } - -UINT GetPluginVersion() -{ - return 1004; -} - -LPCTSTR GetPluginAuthor() -{ - return L"Rainy (rainy@iki.fi)"; -} \ No newline at end of file diff --git a/Plugins/PluginProcess/PluginProcess.cpp b/Plugins/PluginProcess/PluginProcess.cpp index 68159cd5..07001a3f 100644 --- a/Plugins/PluginProcess/PluginProcess.cpp +++ b/Plugins/PluginProcess/PluginProcess.cpp @@ -18,117 +18,72 @@ #include #include -#include -#include +#include +#include +#include "../../Library/RawString.h" #include "../../Library/Export.h" // Rainmeter's exported functions - #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point -/* The exported functions */ -extern "C" -{ -__declspec(dllexport) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); -__declspec(dllexport) void Finalize(HMODULE instance, UINT id); -__declspec(dllexport) double Update2(UINT id); -__declspec(dllexport) UINT GetPluginVersion(); -__declspec(dllexport) LPCTSTR GetPluginAuthor(); -} - struct MeasureData { - std::wstring processName; + CRawString processName; bool isRunning; MeasureData() : isRunning(false) {} }; -static std::map g_Values; static UINT g_UpdateCount = 0; +static std::vector g_Measures; void CheckProcesses(); -/* - This function is called when the measure is initialized. - The function must return the maximum value that can be measured. - The return value can also be 0, which means that Rainmeter will - track the maximum value automatically. The parameters for this - function are: - - instance The instance of this DLL - iniFile The name of the ini-file (usually Rainmeter.ini) - section The name of the section in the ini-file for this measure - id The identifier for the measure. This is used to identify the measures that use the same plugin. -*/ -UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) +PLUGIN_EXPORT void Initialize(void** data) { - MeasureData data; + MeasureData* measure = new MeasureData; + g_Measures.push_back(measure); - const WCHAR* value = ReadConfigString(section, L"ProcessName", L""); - if (*value) + *data = measure; +} + +PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) +{ + MeasureData* measure = (MeasureData*)data; + + LPCWSTR value = RmReadString(rm, L"ProcessName", L""); + measure->processName = value; +} + +PLUGIN_EXPORT double Update(void* data) +{ + MeasureData* measure = (MeasureData*)data; + + // Updates the measure only once per combined updates of all measures + ++g_UpdateCount; + if (g_UpdateCount >= g_Measures.size()) { - data.processName = value; - g_Values[id] = std::move(data); + CheckProcesses(); + g_UpdateCount = 0; } - return 1; + return measure->isRunning ? 1.0 : -1.0; } -/* - This function is called when new value should be measured. - The function returns the new value. -*/ -double Update2(UINT id) +PLUGIN_EXPORT void Finalize(void* data) { - double result = -1.0; + MeasureData* measure = (MeasureData*)data; + std::vector::iterator iter = std::find(g_Measures.begin(), g_Measures.end(), measure); + g_Measures.erase(iter); - std::map::const_iterator iter = g_Values.find(id); - if (iter != g_Values.end()) - { - // Updates the measure only once per combined updates of all measures - ++g_UpdateCount; - if (g_UpdateCount >= g_Values.size()) - { - CheckProcesses(); - g_UpdateCount = 0; - } - - result = (*iter).second.isRunning ? 1.0 : -1.0; - } - - return result; -} - -/* - If the measure needs to free resources before quitting. - The plugin can export Finalize function, which is called - when Rainmeter quits (or refreshes). -*/ -void Finalize(HMODULE instance, UINT id) -{ - std::map::iterator iter = g_Values.find(id); - if (iter != g_Values.end()) - { - g_Values.erase(iter); - } -} - -UINT GetPluginVersion() -{ - return 1000; -} - -LPCTSTR GetPluginAuthor() -{ - return L"Birunthan Mohanathas (poiru.net)"; + delete measure; } void CheckProcesses() { // Set everything to false - std::map::iterator iter = g_Values.begin(); - for ( ; iter != g_Values.end(); ++iter) + std::vector::iterator iter = g_Measures.begin(); + for ( ; iter != g_Measures.end(); ++iter) { - (*iter).second.isRunning = false; + (*iter)->isRunning = false; } int bufSize = 256; @@ -151,12 +106,12 @@ void CheckProcesses() WCHAR buffer[MAX_PATH]; if (GetModuleBaseName(hProcess, NULL, buffer, _countof(buffer))) { - iter = g_Values.begin(); - for ( ; iter != g_Values.end(); ++iter) + iter = g_Measures.begin(); + for ( ; iter != g_Measures.end(); ++iter) { - if (_wcsicmp(buffer, (*iter).second.processName.c_str()) == 0) + if (_wcsicmp(buffer, (*iter)->processName.c_str()) == 0) { - (*iter).second.isRunning = true; + (*iter)->isRunning = true; } } } diff --git a/Plugins/PluginProcess/PluginProcess.rc b/Plugins/PluginProcess/PluginProcess.rc index 82341f7b..495a275a 100644 --- a/Plugins/PluginProcess/PluginProcess.rc +++ b/Plugins/PluginProcess/PluginProcess.rc @@ -29,7 +29,7 @@ BEGIN BLOCK "040904E4" BEGIN VALUE "FileVersion", "1.0.0.0" - VALUE "LegalCopyright", "Copyright (C) 2011 - Birunthan Mohanathas" + VALUE "LegalCopyright", "© 2011 - Birunthan Mohanathas" VALUE "OriginalFilename", "Process.dll" VALUE "ProductName", "Rainmeter" #ifdef _WIN64 diff --git a/Plugins/PluginProcess/PluginProcess.vcxproj b/Plugins/PluginProcess/PluginProcess.vcxproj index 8fcb3214..1e3a57c0 100644 --- a/Plugins/PluginProcess/PluginProcess.vcxproj +++ b/Plugins/PluginProcess/PluginProcess.vcxproj @@ -67,10 +67,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ false diff --git a/Plugins/PluginQuote/PluginQuote.rc b/Plugins/PluginQuote/PluginQuote.rc index 902aa267..c3824469 100644 --- a/Plugins/PluginQuote/PluginQuote.rc +++ b/Plugins/PluginQuote/PluginQuote.rc @@ -1,10 +1,5 @@ -// Microsoft Developer Studio generated resource script. -// - +#include #include "../../Version.h" -#define APSTUDIO_READONLY_SYMBOLS -#include "windows.h" -#undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // @@ -18,7 +13,7 @@ VS_VERSION_INFO VERSIONINFO #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG #else - FILEFLAGS 0x0L + FILEFLAGS 0x0L #endif FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_DLL @@ -28,11 +23,9 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "FileDescription", "Quote Plugin for Rainmeter" VALUE "FileVersion", "1.1.0.0" - VALUE "InternalName", "PluginQuote" - VALUE "LegalCopyright", "Copyright (C) 2010 - Rainy" - VALUE "OriginalFilename", "PluginQuote.dll" + VALUE "LegalCopyright", "© 2010 - Rainy" + VALUE "OriginalFilename", "QuotePlugin.dll" VALUE "ProductName", "Rainmeter" #ifdef _WIN64 VALUE "ProductVersion", STRPRODUCTVER " (64-bit)" diff --git a/Plugins/PluginQuote/PluginQuote.vcxproj b/Plugins/PluginQuote/PluginQuote.vcxproj index 03e3d3f5..280ea51e 100644 --- a/Plugins/PluginQuote/PluginQuote.vcxproj +++ b/Plugins/PluginQuote/PluginQuote.vcxproj @@ -73,10 +73,10 @@ false $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true QuotePlugin QuotePlugin QuotePlugin diff --git a/Plugins/PluginQuote/Quote.cpp b/Plugins/PluginQuote/Quote.cpp index a03cb471..e9672ff5 100644 --- a/Plugins/PluginQuote/Quote.cpp +++ b/Plugins/PluginQuote/Quote.cpp @@ -17,56 +17,35 @@ */ #include -#include #include -#include #include #include -#include #include #include "../../Library/Export.h" // Rainmeter's exported functions - #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point -/* The exported functions */ -extern "C" -{ -__declspec( dllexport ) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); -__declspec( dllexport ) void Finalize(HMODULE instance, UINT id); -__declspec( dllexport ) double Update2(UINT id); -__declspec( dllexport ) LPCTSTR GetString(UINT id, UINT flags); -__declspec( dllexport ) UINT GetPluginVersion(); -__declspec( dllexport ) LPCTSTR GetPluginAuthor(); -} +#define BUFFER_SIZE 4096 -struct quoteData +struct MeasureData { std::wstring pathname; std::wstring separator; - std::vector fileFilters; std::vector files; std::wstring value; }; -void ScanFolder(quoteData& qData, bool bSubfolders, const std::wstring& path); - -static std::map g_Values; - std::string ConvertToAscii(LPCTSTR str) { std::string szAscii; if (str && *str) { - int strLen = (int)wcslen(str) + 1; + int strLen = (int)wcslen(str); int bufLen = WideCharToMultiByte(CP_ACP, 0, str, strLen, NULL, 0, NULL, NULL); if (bufLen > 0) { - char* tmpSz = new char[bufLen]; - tmpSz[0] = 0; - WideCharToMultiByte(CP_ACP, 0, str, strLen, tmpSz, bufLen, NULL, NULL); - szAscii = tmpSz; - delete [] tmpSz; + szAscii.resize(bufLen); + WideCharToMultiByte(CP_ACP, 0, str, strLen, &szAscii[0], bufLen, NULL, NULL); } } return szAscii; @@ -78,110 +57,18 @@ std::wstring ConvertToWide(LPCSTR str) if (str && *str) { - int strLen = (int)strlen(str) + 1; + int strLen = (int)strlen(str); int bufLen = MultiByteToWideChar(CP_ACP, 0, str, strLen, NULL, 0); if (bufLen > 0) { - WCHAR* wideSz = new WCHAR[bufLen]; - wideSz[0] = 0; - MultiByteToWideChar(CP_ACP, 0, str, strLen, wideSz, bufLen); - szWide = wideSz; - delete [] wideSz; + szWide.resize(bufLen); + MultiByteToWideChar(CP_ACP, 0, str, strLen, &szWide[0], bufLen); } } return szWide; } -/* - This function is called when the measure is initialized. - The function must return the maximum value that can be measured. - The return value can also be 0, which means that Rainmeter will - track the maximum value automatically. The parameters for this - function are: - - instance The instance of this DLL - iniFile The name of the ini-file (usually Rainmeter.ini) - section The name of the section in the ini-file for this measure - id The identifier for the measure. This is used to identify the measures that use the same plugin. -*/ -UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) -{ - quoteData qData; - LPCTSTR data; - bool bSubfolders = false; - - data = ReadConfigString(section, L"Subfolders", L"0"); - if (data && _ttoi(data) == 1) - { - bSubfolders = true; - } - - data = ReadConfigString(section, L"Separator", L"\n"); - if (data) - { - qData.separator = data; - } - - data = ReadConfigString(section, L"FileFilter", L""); - if (data && wcslen(data) > 0) - { - std::wstring ext = data; - - size_t start = 0; - size_t pos = ext.find(L';'); - while (pos != std::wstring::npos) - { - qData.fileFilters.push_back(ext.substr(start, pos - start)); - start = pos + 1; - pos = ext.find(L';', pos + 1); - } - qData.fileFilters.push_back(ext.substr(start)); - - qData.separator = data; - } - - /* Read our own settings from the ini-file */ - data = ReadConfigString(section, L"PathName", L""); - if (data && wcslen(data) > 0) - { - qData.pathname = data; - - if (qData.pathname.find(':') == -1) // Not found - { - std::wstring path = iniFile; - size_t pos = path.rfind('\\'); - if (pos >= 0) - { - path.erase(pos + 1); - qData.pathname = path + qData.pathname; - } - } - - if (PathIsDirectory(qData.pathname.c_str())) - { - if (qData.pathname[qData.pathname.size() - 1] != L'\\') - { - qData.pathname += L"\\"; - } - - // Scan files - ScanFolder(qData, bSubfolders, qData.pathname); - } - } - - if (!qData.pathname.empty()) - { - g_Values[id] = qData; - } - - // TODO: Random=0, load stuff sequentially (store to somewhere) - - srand( (unsigned)time( NULL ) ); - - return 0; -} - -void ScanFolder(quoteData& qData, bool bSubfolders, const std::wstring& path) +void ScanFolder(std::vector& files, std::vector& filters, bool bSubfolders, const std::wstring& path) { // Get folder listing WIN32_FIND_DATA fileData; // Data structure describes the file found @@ -196,264 +83,276 @@ void ScanFolder(quoteData& qData, bool bSubfolders, const std::wstring& path) if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - if (bSubfolders) + if (bSubfolders && + wcscmp(fileData.cFileName, L".") != 0 && + wcscmp(fileData.cFileName, L"..") != 0) { - if (wcscmp(fileData.cFileName, L".") != 0 && wcscmp(fileData.cFileName, L"..") != 0) - { - ScanFolder(qData, bSubfolders, path + fileData.cFileName + L"\\"); - } + ScanFolder(files, filters, bSubfolders, path + fileData.cFileName + L"\\"); } } else { - if (!qData.fileFilters.empty()) + if (!filters.empty()) { - for (int i = 0; i < qData.fileFilters.size(); i++) + for (int i = 0; i < filters.size(); ++i) { - if (!qData.fileFilters[i].empty() && PathMatchSpec(fileData.cFileName, qData.fileFilters[i].c_str())) + if (!filters[i].empty() && PathMatchSpec(fileData.cFileName, filters[i].c_str())) { - qData.files.push_back(path + fileData.cFileName); + files.push_back(path + fileData.cFileName); break; } } } else { - qData.files.push_back(path + fileData.cFileName); + files.push_back(path + fileData.cFileName); } } } while (FindNextFile(hSearch, &fileData)); } -#define BUFFER_SIZE 4096 - -/* -This function is called when new value should be measured. -The function returns the new value. -*/ -double Update2(UINT id) +PLUGIN_EXPORT void Initialize(void** data) { - std::map::iterator i = g_Values.find(id); - if (i != g_Values.end()) + MeasureData* measure = new MeasureData; + *data = measure; +} + +PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) +{ + MeasureData* measure = (MeasureData*)data; + + measure->pathname = RmReadPath(rm, L"PathName", L""); + + if (PathIsDirectory(measure->pathname.c_str())) { - quoteData& qData = (*i).second; - - if (qData.files.empty()) + std::vector fileFilters; + LPCWSTR filter = RmReadString(rm, L"FileFilter", L""); + if (*filter) { - BYTE buffer[BUFFER_SIZE + 2]; - buffer[BUFFER_SIZE] = 0; + std::wstring ext = filter; - // Read the file - FILE* file = _wfopen(qData.pathname.c_str(), L"r"); - if (file) + size_t start = 0; + size_t pos = ext.find(L';'); + while (pos != std::wstring::npos) { - // Check if the file is unicode or ascii - fread(buffer, sizeof(WCHAR), 1, file); + fileFilters.push_back(ext.substr(start, pos - start)); + start = pos + 1; + pos = ext.find(L';', pos + 1); + } + fileFilters.push_back(ext.substr(start)); + } - fseek(file, 0, SEEK_END); - int size = ftell(file); + if (measure->pathname[measure->pathname.size() - 1] != L'\\') + { + measure->pathname += L"\\"; + } - if (size > 0) + // Scan files + measure->files.clear(); + bool bSubfolders = RmReadInt(rm, L"Subfolders", 1) == 1; + ScanFolder(measure->files, fileFilters, bSubfolders, measure->pathname); + } + else + { + measure->separator = RmReadString(rm, L"Separator", L"\n"); + } + + srand((unsigned)time(NULL)); +} + +PLUGIN_EXPORT double Update(void* data) +{ + MeasureData* measure = (MeasureData*)data; + + if (measure->files.empty()) + { + BYTE buffer[BUFFER_SIZE + 2]; + buffer[BUFFER_SIZE] = 0; + + // Read the file + FILE* file = _wfopen(measure->pathname.c_str(), L"r"); + if (file) + { + // Check if the file is unicode or ascii + fread(buffer, sizeof(WCHAR), 1, file); + + fseek(file, 0, SEEK_END); + long size = ftell(file); + + if (size > 0) + { + // Go to a random place + int pos = rand() % size; + fseek(file, (pos / 2) * 2, SEEK_SET); + + measure->value.clear(); + + if (0xFEFF == *(WCHAR*)buffer) { - // Go to a random place - int pos = rand() % size; - fseek(file, (pos / 2) * 2, SEEK_SET); + // It's unicode + WCHAR* wBuffer = (WCHAR*)buffer; - qData.value.erase(); - - if (0xFEFF == *(WCHAR*)buffer) + // Read until we find the first separator + WCHAR* sepPos1 = NULL; + WCHAR* sepPos2 = NULL; + do { - // It's unicode - WCHAR* wBuffer = (WCHAR*)buffer; + size_t len = fread(buffer, sizeof(BYTE), BUFFER_SIZE, file); + buffer[len] = 0; + buffer[len + 1] = 0; - // Read until we find the first separator - WCHAR* sepPos1 = NULL; - WCHAR* sepPos2 = NULL; - do + sepPos1 = wcsstr(wBuffer, measure->separator.c_str()); + if (sepPos1 == NULL) { - size_t len = fread(buffer, sizeof(BYTE), BUFFER_SIZE, file); - buffer[len] = 0; - buffer[len + 1] = 0; - - sepPos1 = wcsstr(wBuffer, qData.separator.c_str()); - if (sepPos1 == NULL) + // The separator wasn't found + if (feof(file)) { - // The separator wasn't found - if (feof(file)) - { - // End of file reached -> read from start - fseek(file, 2, SEEK_SET); - len = fread(buffer, sizeof(BYTE), BUFFER_SIZE, file); - buffer[len] = 0; - buffer[len + 1] = 0; - sepPos1 = wBuffer; - } - // else continue reading - } - else - { - sepPos1 += qData.separator.size(); + // End of file reached -> read from start + fseek(file, 2, SEEK_SET); + len = fread(buffer, sizeof(BYTE), BUFFER_SIZE, file); + buffer[len] = 0; + buffer[len + 1] = 0; + sepPos1 = wBuffer; } + // else continue reading } - while (sepPos1 == NULL); - - // Find the second separator - do + else { - sepPos2 = wcsstr(sepPos1, qData.separator.c_str()); - if (sepPos2 == NULL) - { - // The separator wasn't found - if (feof(file)) - { - // End of file reached -> read the rest - qData.value += sepPos1; - break; - } - else - { - qData.value += sepPos1; - - // else continue reading - size_t len = fread(buffer, sizeof(BYTE), BUFFER_SIZE, file); - buffer[len] = 0; - buffer[len + 1] = 0; - sepPos1 = wBuffer; - } - } - else - { - if (sepPos2) - { - *sepPos2 = 0; - } - - // Read until we find the second separator - qData.value += sepPos1; - } + sepPos1 += measure->separator.size(); } - while (sepPos2 == NULL); } - else + while (sepPos1 == NULL); + + // Find the second separator + do { - // It's ascii - char* aBuffer = (char*)buffer; - - // Read until we find the first separator - char* sepPos1 = NULL; - char* sepPos2 = NULL; - do + sepPos2 = wcsstr(sepPos1, measure->separator.c_str()); + if (sepPos2 == NULL) { - size_t len = fread(buffer, sizeof(char), BUFFER_SIZE, file); - aBuffer[len] = 0; - - sepPos1 = strstr(aBuffer, ConvertToAscii(qData.separator.c_str()).c_str()); - if (sepPos1 == NULL) + // The separator wasn't found + if (feof(file)) { - // The separator wasn't found - if (feof(file)) - { - // End of file reached -> read from start - fseek(file, 0, SEEK_SET); - len = fread(buffer, sizeof(char), BUFFER_SIZE, file); - aBuffer[len] = 0; - sepPos1 = aBuffer; - } + // End of file reached -> read the rest + measure->value += sepPos1; + break; + } + else + { + measure->value += sepPos1; + // else continue reading - } - else - { - sepPos1 += qData.separator.size(); + size_t len = fread(buffer, sizeof(BYTE), BUFFER_SIZE, file); + buffer[len] = 0; + buffer[len + 1] = 0; + sepPos1 = wBuffer; } } - while (sepPos1 == NULL); - - // Find the second separator - do + else { - sepPos2 = strstr(sepPos1, ConvertToAscii(qData.separator.c_str()).c_str()); - if (sepPos2 == NULL) + if (sepPos2) { - // The separator wasn't found - if (feof(file)) - { - // End of file reached -> read the rest - qData.value += ConvertToWide(sepPos1); - break; - } - else - { - qData.value += ConvertToWide(sepPos1); - - // else continue reading - size_t len = fread(buffer, sizeof(char), BUFFER_SIZE, file); - aBuffer[len] = 0; - sepPos1 = aBuffer; - } + *sepPos2 = 0; } - else - { - if (sepPos2) - { - *sepPos2 = 0; - } - // Read until we find the second separator - qData.value += ConvertToWide(sepPos1); - } + // Read until we find the second separator + measure->value += sepPos1; } - while (sepPos2 == NULL); } + while (sepPos2 == NULL); } + else + { + // It's ascii + char* aBuffer = (char*)buffer; - fclose(file); - } - } - else - { - // Select the filename - if (qData.files.size() > 0) - { - qData.value = qData.files[rand() % qData.files.size()]; + // Read until we find the first separator + char* sepPos1 = NULL; + char* sepPos2 = NULL; + do + { + size_t len = fread(buffer, sizeof(char), BUFFER_SIZE, file); + aBuffer[len] = 0; + + sepPos1 = strstr(aBuffer, ConvertToAscii(measure->separator.c_str()).c_str()); + if (sepPos1 == NULL) + { + // The separator wasn't found + if (feof(file)) + { + // End of file reached -> read from start + fseek(file, 0, SEEK_SET); + len = fread(buffer, sizeof(char), BUFFER_SIZE, file); + aBuffer[len] = 0; + sepPos1 = aBuffer; + } + // else continue reading + } + else + { + sepPos1 += measure->separator.size(); + } + } + while (sepPos1 == NULL); + + // Find the second separator + do + { + sepPos2 = strstr(sepPos1, ConvertToAscii(measure->separator.c_str()).c_str()); + if (sepPos2 == NULL) + { + // The separator wasn't found + if (feof(file)) + { + // End of file reached -> read the rest + measure->value += ConvertToWide(sepPos1); + break; + } + else + { + measure->value += ConvertToWide(sepPos1); + + // else continue reading + size_t len = fread(buffer, sizeof(char), BUFFER_SIZE, file); + aBuffer[len] = 0; + sepPos1 = aBuffer; + } + } + else + { + if (sepPos2) + { + *sepPos2 = 0; + } + + // Read until we find the second separator + measure->value += ConvertToWide(sepPos1); + } + } + while (sepPos2 == NULL); + } } + + fclose(file); } } + else + { + // Select the filename + measure->value = measure->files[rand() % measure->files.size()]; + } return 0; } -LPCTSTR GetString(UINT id, UINT flags) +PLUGIN_EXPORT LPCWSTR GetString(void* data) { - std::map::iterator i = g_Values.find(id); - if (i != g_Values.end()) - { - return ((*i).second).value.c_str(); - } - - return NULL; + MeasureData* measure = (MeasureData*)data; + return measure->value.c_str(); } -/* - If the measure needs to free resources before quitting. - The plugin can export Finalize function, which is called - when Rainmeter quits (or refreshes). -*/ -void Finalize(HMODULE instance, UINT id) +PLUGIN_EXPORT void Finalize(void* data) { - std::map::iterator i1 = g_Values.find(id); - if (i1 != g_Values.end()) - { - g_Values.erase(i1); - } -} - -UINT GetPluginVersion() -{ - return 1001; -} - -LPCTSTR GetPluginAuthor() -{ - return L"Rainy (rainy@iki.fi)"; + MeasureData* measure = (MeasureData*)data; + delete measure; } \ No newline at end of file diff --git a/Plugins/PluginRecycleManager/PluginRecycleManager.rc b/Plugins/PluginRecycleManager/PluginRecycleManager.rc index 5ccb55d7..5bb043f2 100644 --- a/Plugins/PluginRecycleManager/PluginRecycleManager.rc +++ b/Plugins/PluginRecycleManager/PluginRecycleManager.rc @@ -1,10 +1,5 @@ -// Microsoft Developer Studio generated resource script. -// - +#include #include "../../Version.h" -#define APSTUDIO_READONLY_SYMBOLS -#include "windows.h" -#undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // @@ -18,7 +13,7 @@ VS_VERSION_INFO VERSIONINFO #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG #else - FILEFLAGS 0x0L + FILEFLAGS 0x0L #endif FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_DLL @@ -28,11 +23,9 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "FileDescription", "RecycleManager Plugin for Rainmeter" VALUE "FileVersion", "1.0.0.0" - VALUE "InternalName", "PluginRecycleManager" - VALUE "LegalCopyright", "Copyright (C) 2010 - gschoppe" - VALUE "OriginalFilename", "PluginRecycleManager.dll" + VALUE "LegalCopyright", "© 2010 - gschoppe" + VALUE "OriginalFilename", "RecycleManager.dll" VALUE "ProductName", "Rainmeter" #ifdef _WIN64 VALUE "ProductVersion", STRPRODUCTVER " (64-bit)" diff --git a/Plugins/PluginRecycleManager/PluginRecycleManager.vcxproj b/Plugins/PluginRecycleManager/PluginRecycleManager.vcxproj index 0a219fdd..f609b8c5 100644 --- a/Plugins/PluginRecycleManager/PluginRecycleManager.vcxproj +++ b/Plugins/PluginRecycleManager/PluginRecycleManager.vcxproj @@ -73,10 +73,10 @@ false $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true RecycleManager RecycleManager RecycleManager diff --git a/Plugins/PluginRecycleManager/RecycleManager.cpp b/Plugins/PluginRecycleManager/RecycleManager.cpp index 7d1e41ca..c305136d 100644 --- a/Plugins/PluginRecycleManager/RecycleManager.cpp +++ b/Plugins/PluginRecycleManager/RecycleManager.cpp @@ -18,25 +18,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include -#include -#include -#include -#include +#include +#include "../../Library/RawString.h" #include "../../Library/Export.h" // Rainmeter's exported functions - #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point -/* The exported functions */ -extern "C" -{ - __declspec( dllexport ) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); - __declspec( dllexport ) void Finalize(HMODULE instance, UINT id); - __declspec( dllexport ) double Update2(UINT id); - __declspec( dllexport ) UINT GetPluginVersion(); - __declspec( dllexport ) LPCTSTR GetPluginAuthor(); - __declspec( dllexport ) void ExecuteBang(LPCTSTR args, UINT id); -} - // System resources that can be counted enum MEASURETYPE { @@ -44,96 +30,61 @@ enum MEASURETYPE SIZERECYCLE }; -static std::map g_Values; -static std::map g_DriveList; - -/* - This function is called when the measure is initialized. - The function must return the maximum value that can be measured. - The return value can also be 0, which means that Rainmeter will - track the maximum value automatically. The parameters for this - function are: - - instance The instance of this DLL - iniFile The name of the ini-file (usually Rainmeter.ini) - section The name of the section in the ini-file for this measure - id The identifier for the measure. This is used to identify the measures that use the same plugin. -*/ -UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) +struct MeasureData { - MEASURETYPE dataType = NUMRECYCLE; + MEASURETYPE type; + CRawString drives; - /* Read our own settings from the ini-file */ - LPCTSTR type = ReadConfigString(section, L"RecycleType", L"COUNT"); - if (type) - { - if (_wcsicmp(L"COUNT", type) == 0) - { - dataType = NUMRECYCLE; - } - else if (_wcsicmp(L"SIZE", type) == 0) - { - dataType = SIZERECYCLE; - } - else - { - std::wstring error = L"RecycleManager.dll: RecycleType="; - error += type; - error += L" is not valid in ["; - error += section; - error += L"]"; - LSLog(LOG_ERROR, NULL, error.c_str()); - } - } + MeasureData() : type(NUMRECYCLE) {} +}; - g_Values[id] = dataType; - - LPCTSTR drives = ReadConfigString(section, L"Drives", L""); - g_DriveList[id] = (drives && *drives) ? drives : L"ALL"; - - return 0; +PLUGIN_EXPORT void Initialize(void** data) +{ + MeasureData* measure = new MeasureData; + *data = measure; } -void Tokenize(const std::wstring& str, std::vector& tokens, const std::wstring& delimiters = L"|") +PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { - // Skip delimiters at beginning. - std::wstring::size_type lastPos = str.find_first_not_of(delimiters, 0); - // Find first "non-delimiter". - std::wstring::size_type pos = str.find_first_of(delimiters, lastPos); + MeasureData* measure = (MeasureData*)data; - while (std::wstring::npos != pos || std::wstring::npos != lastPos) + LPCWSTR value = RmReadString(rm, L"RecycleType", L"COUNT"); + if (_wcsicmp(L"COUNT", value) == 0) { - // Found a token, add it to the vector. - tokens.push_back(str.substr(lastPos, pos - lastPos)); - // Skip delimiters. Note the "not_of" - lastPos = str.find_first_not_of(delimiters, pos); - // Find next "non-delimiter" - pos = str.find_first_of(delimiters, lastPos); + measure->type = NUMRECYCLE; } + else if (_wcsicmp(L"SIZE", value) == 0) + { + measure->type = SIZERECYCLE; + } + else + { + WCHAR buffer[256]; + _snwprintf_s(buffer, _TRUNCATE, L"RecycleManager.dll: RecycleType=%s is not valid in [%s]", value, RmGetMeasureName(rm)); + RmLog(LOG_ERROR, buffer); + } + + value = RmReadString(rm, L"Drives", L"ALL"); + measure->drives = (_wcsicmp(value, L"ALL") == 0) ? NULL : value; } -/* - This function is called when new value should be measured. - The function returns the new value. -*/ -double Update2(UINT id) +PLUGIN_EXPORT double Update(void* data) { + MeasureData* measure = (MeasureData*)data; double retVal = 0; - MEASURETYPE dataType = g_Values[id]; - const std::wstring& driveSet = g_DriveList[id]; SHQUERYRBINFO rbi = {0}; rbi.cbSize = sizeof(SHQUERYRBINFO); - if (_wcsicmp(driveSet.c_str(), L"ALL") == 0) + if (measure->drives.empty()) { if (SHQueryRecycleBin(NULL, &rbi) == S_OK) { - if (dataType == SIZERECYCLE) + if (measure->type == SIZERECYCLE) { retVal = (double)rbi.i64Size; // size in bytes } - else if (dataType == NUMRECYCLE) + else if (measure->type == NUMRECYCLE) { retVal = (double)rbi.i64NumItems; // number of items in bin } @@ -141,100 +92,70 @@ double Update2(UINT id) } else { - std::vector tokens; - Tokenize(driveSet, tokens); - - for (int i = 0, isize = (int)tokens.size(); i < isize; i++) + WCHAR* drives = _wcsdup(measure->drives.c_str()); + WCHAR* token = wcstok(drives, L"|"); + while (token) { - if (SHQueryRecycleBin(tokens[i].c_str(), &rbi) == S_OK) + if (SHQueryRecycleBin(token, &rbi) == S_OK) { - if (dataType == SIZERECYCLE) + if (measure->type == SIZERECYCLE) { retVal += (double)rbi.i64Size; // size in bytes } - else if (dataType == NUMRECYCLE) + else if (measure->type == NUMRECYCLE) { retVal += (double)rbi.i64NumItems; // number of items in bin } } + + token = wcstok(NULL, L"|"); } + free(drives); } return retVal; } -/* - If the measure needs to free resources before quitting. - The plugin can export Finalize function, which is called - when Rainmeter quits (or refreshes). -*/ -void Finalize(HMODULE instance, UINT id) +PLUGIN_EXPORT void Finalize(void* data) { - std::map::iterator i1 = g_Values.find(id); - if (i1 != g_Values.end()) + MeasureData* measure = (MeasureData*)data; + delete measure; +} + +PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) +{ + MeasureData* measure = (MeasureData*)data; + + auto emptyBin = [&](DWORD flags) { - g_Values.erase(i1); - } -} - -UINT GetPluginVersion() -{ - return 1000; -} - -LPCTSTR GetPluginAuthor() -{ - return L"gschoppe (gschoppe@gmail.com)"; -} - -void ExecuteBang(LPCTSTR args, UINT id) -{ - const std::wstring& driveSet = g_DriveList[id]; - if (_wcsicmp(args, L"EmptyBin") == 0) - { - // Empty the Recycle Bin - if (_wcsicmp(driveSet.c_str(), L"ALL") == 0) + if (measure->drives.empty()) { - SHEmptyRecycleBin( NULL, NULL, NULL ); + SHEmptyRecycleBin(NULL, NULL, flags); } else { - std::vector tokens; - Tokenize(driveSet, tokens); - - for (int i = 0, isize = (int)tokens.size(); i < isize; i++) + WCHAR* drives = _wcsdup(measure->drives.c_str()); + WCHAR* token = wcstok(drives, L"|"); + while (token) { - SHEmptyRecycleBin( NULL, tokens[i].c_str(), NULL ); // empty bin + SHEmptyRecycleBin(NULL, token, flags); + token = wcstok(NULL, L"|"); } + free(drives); } - return; - } - else + }; + + if (_wcsicmp(args, L"EmptyBin") == 0) { - if (_wcsicmp(args, L"EmptyBinSilent") == 0) - { - // Empty the Recycle Bin (no prompt) - if (_wcsicmp(driveSet.c_str(), L"ALL") == 0) - { - SHEmptyRecycleBin( NULL, NULL, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND ); - } - else - { - std::vector tokens; - Tokenize(driveSet, tokens); - - for (int i = 0, isize = (int)tokens.size(); i < isize; i++) - { - SHEmptyRecycleBin( NULL, tokens[i].c_str(), SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND ); // empty bin - } - } - } - else if (_wcsicmp(args, L"OpenBin") == 0) - { - // Open the Recycle Bin folder - ShellExecute(NULL, L"open", L"explorer.exe", L"/N,::{645FF040-5081-101B-9F08-00AA002F954E}", NULL, SW_SHOW); - return; - } + emptyBin(0); + } + else if (_wcsicmp(args, L"EmptyBinSilent") == 0) + { + emptyBin(SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND); + } + else if (_wcsicmp(args, L"OpenBin") == 0) + { + // Open the Recycle Bin folder + ShellExecute(NULL, L"open", L"explorer.exe", L"/N,::{645FF040-5081-101B-9F08-00AA002F954E}", NULL, SW_SHOW); } } - diff --git a/Plugins/PluginResMon/PluginResMon.rc b/Plugins/PluginResMon/PluginResMon.rc index 58b12ea9..3ef24d92 100644 --- a/Plugins/PluginResMon/PluginResMon.rc +++ b/Plugins/PluginResMon/PluginResMon.rc @@ -1,10 +1,5 @@ -// Microsoft Developer Studio generated resource script. -// - +#include #include "../../Version.h" -#define APSTUDIO_READONLY_SYMBOLS -#include "windows.h" -#undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // @@ -18,7 +13,7 @@ VS_VERSION_INFO VERSIONINFO #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG #else - FILEFLAGS 0x0L + FILEFLAGS 0x0L #endif FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_DLL @@ -28,11 +23,9 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "FileDescription", "ResMon Plugin for Rainmeter" VALUE "FileVersion", "1.3.0.0" - VALUE "InternalName", "PluginResMon" - VALUE "LegalCopyright", "Copyright (C) 2010 - David Negstad" - VALUE "OriginalFilename", "PluginResMon.dll" + VALUE "LegalCopyright", "© 2010 - David Negstad" + VALUE "OriginalFilename", "ResMon.dll" VALUE "ProductName", "Rainmeter" #ifdef _WIN64 VALUE "ProductVersion", STRPRODUCTVER " (64-bit)" diff --git a/Plugins/PluginResMon/PluginResMon.vcxproj b/Plugins/PluginResMon/PluginResMon.vcxproj index 693f8749..6b72ab33 100644 --- a/Plugins/PluginResMon/PluginResMon.vcxproj +++ b/Plugins/PluginResMon/PluginResMon.vcxproj @@ -73,10 +73,10 @@ false $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true ResMon ResMon ResMon diff --git a/Plugins/PluginResMon/ResMon.cpp b/Plugins/PluginResMon/ResMon.cpp index 5e7642aa..e85b3972 100644 --- a/Plugins/PluginResMon/ResMon.cpp +++ b/Plugins/PluginResMon/ResMon.cpp @@ -26,26 +26,14 @@ #define _WIN32_WINNT 0x0501 #include -#include -#include -#include +#include #include +#include "../../Library/RawString.h" #include "../../Library/Export.h" // Rainmeter's exported functions - #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point -/* The exported functions */ -extern "C" -{ - __declspec( dllexport ) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); - __declspec( dllexport ) UINT Update(UINT id); - __declspec( dllexport ) void Finalize(HMODULE instance, UINT id); - __declspec( dllexport ) UINT GetPluginVersion(); - __declspec( dllexport ) LPCTSTR GetPluginAuthor(); -} - // system resources that can be counted -enum COUNTER +enum MEASURETYPE { GDI_COUNT, USER_COUNT, @@ -53,138 +41,103 @@ enum COUNTER WINDOW_COUNT }; -// list of counter types corresponding to gauges -static std::map g_Counters; -static std::map g_ProcessNames; +struct MeasureData +{ + MEASURETYPE type; + CRawString process; + + MeasureData() : type(GDI_COUNT) {} +}; // used to track the number of existing windows UINT g_WindowCount = 0; -// count the child windows of a system window -BOOL CALLBACK EnumChildProc ( HWND hWndChild, LPARAM lParam ) +// count the windows +BOOL CALLBACK EnumWindowProc(HWND hWnd, LPARAM lParam) { ++g_WindowCount; return TRUE; } -// count the system windows -BOOL CALLBACK EnumWindowProc ( HWND hWnd, LPARAM lParam ) +PLUGIN_EXPORT void Initialize(void** data) { - ++g_WindowCount; - EnumChildWindows ( hWnd, EnumChildProc, lParam ); - return TRUE; + MeasureData* measure = new MeasureData; + *data = measure; } -/* - This function is called when the measure is initialized. - The function must return the maximum value that can be measured. - The return value can also be 0, which means that Rainmeter will - track the maximum value automatically. The parameters for this - function are: - instance The instance of this DLL - iniFile The name of the ini-file (usually Rainmeter.ini) - section The name of the section in the ini-file for this measure - id The identifier for the measure. This is used to identify the measures that use the same plugin. -*/ -UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) +PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { - LPCTSTR type = ReadConfigString(section, L"ResCountType", L"GDI"); + MeasureData* measure = (MeasureData*)data; - /* Read our own settings from the ini-file */ - if (type) + LPCWSTR type = RmReadString(rm, L"ResCountType", L"GDI"); + if (_wcsicmp(L"GDI", type) == 0) { - if ( _wcsicmp ( L"GDI", type ) == 0 ) - { - g_Counters[id] = GDI_COUNT; - } - else if ( _wcsicmp ( L"USER", type ) == 0 ) - { - g_Counters[id] = USER_COUNT; - } - else if ( _wcsicmp ( L"HANDLE", type ) == 0 ) - { - g_Counters[id] = HANDLE_COUNT; - } - else if ( _wcsicmp ( L"WINDOW", type ) == 0 ) - { - g_Counters[id] = WINDOW_COUNT; - } - else - { - std::wstring error = L"ResMon.dll: GDICountType="; - error += type; - error += L" is not valid in ["; - error += section; - error += L"]"; - LSLog(LOG_ERROR, NULL, error.c_str()); - } + measure->type = GDI_COUNT; + } + else if (_wcsicmp(L"USER", type) == 0) + { + measure->type = USER_COUNT; + } + else if (_wcsicmp(L"HANDLE", type) == 0) + { + measure->type = HANDLE_COUNT; + } + else if (_wcsicmp(L"WINDOW", type) == 0) + { + measure->type = WINDOW_COUNT; + } + else + { + WCHAR buffer[256]; + _snwprintf_s(buffer, _TRUNCATE, L"ResMon.dll: GDICountType=%s is not valid in [%s]", type, RmGetMeasureName(rm)); + RmLog(LOG_ERROR, buffer); } - LPCTSTR process = ReadConfigString(section, L"ProcessName", L""); - if (process && wcslen(process) > 0) - { - g_ProcessNames[id] = process; - } - - return 0; + measure->process = RmReadString(rm, L"ProcessName", L""); } -/* - This function is called when new value should be measured. - The function returns the new value. -*/ -UINT Update(UINT id) +PLUGIN_EXPORT double Update(void* data) { - std::map::iterator countItor = g_Counters.find ( id ); - if ( countItor == g_Counters.end () ) - { - return 0; - } - - COUNTER counter = ( *countItor ).second; + MeasureData* measure = (MeasureData*)data; // count the existing window objects - if ( counter == WINDOW_COUNT ) + if (measure->type == WINDOW_COUNT) { g_WindowCount = 0; - EnumChildWindows ( NULL, EnumWindowProc, 0 ); + EnumChildWindows(NULL, EnumWindowProc, 0); return g_WindowCount; } - const WCHAR* processName = NULL; - std::map::iterator processItor = g_ProcessNames.find ( id ); - if ( processItor != g_ProcessNames.end () ) - { - processName = ((*processItor).second).c_str(); - } + const WCHAR* processName = measure->process.c_str(); + bool name = !measure->process.empty(); DWORD aProcesses[1024]; DWORD bytesNeeded; WCHAR buffer[1024]; HMODULE hMod[1024]; - DWORD cbNeeded; + DWORD cbNeeded; - if ( !EnumProcesses ( aProcesses, sizeof ( aProcesses ), &bytesNeeded ) ) + if (!EnumProcesses(aProcesses, sizeof(aProcesses), &bytesNeeded)) { - return 0; + return 0.0; } // step through the running processes DWORD flags = PROCESS_QUERY_INFORMATION; - if (processName) + if (name) { flags |= PROCESS_VM_READ; } UINT resourceCount = 0; - for ( UINT i = 0; i < bytesNeeded / sizeof ( DWORD ); ++i ) + for (UINT i = 0, isize = bytesNeeded / sizeof(DWORD); i < isize; ++i) { - HANDLE hProcess = OpenProcess ( flags, true, aProcesses[i] ); - if ( hProcess != NULL ) + HANDLE hProcess = OpenProcess(flags, true, aProcesses[i]); + if (hProcess != NULL) { - if (processName) + if (name) { if (EnumProcessModules(hProcess, hMod, sizeof(hMod), &cbNeeded)) { @@ -192,70 +145,46 @@ UINT Update(UINT id) { if (_wcsicmp(buffer, processName) != 0) { - CloseHandle ( hProcess ); + CloseHandle(hProcess); continue; } } else { - CloseHandle ( hProcess ); + CloseHandle(hProcess); continue; } } else { - CloseHandle ( hProcess ); + CloseHandle(hProcess); continue; } } - if ( counter == GDI_COUNT ) + if (measure->type == GDI_COUNT) { - resourceCount += GetGuiResources ( hProcess, GR_GDIOBJECTS ); + resourceCount += GetGuiResources(hProcess, GR_GDIOBJECTS); } - else if ( counter == USER_COUNT ) + else if (measure->type == USER_COUNT) { - resourceCount += GetGuiResources ( hProcess, GR_USEROBJECTS ); + resourceCount += GetGuiResources(hProcess, GR_USEROBJECTS); } - else if ( counter == HANDLE_COUNT ) + else if (measure->type == HANDLE_COUNT) { DWORD tempHandleCount = 0; - GetProcessHandleCount ( hProcess, &tempHandleCount ); + GetProcessHandleCount(hProcess, &tempHandleCount); resourceCount += tempHandleCount; } } - CloseHandle ( hProcess ); + CloseHandle(hProcess); } return resourceCount; } -/* - If the measure needs to free resources before quitting. - The plugin can export Finalize function, which is called - when Rainmeter quits (or refreshes). -*/ -void Finalize(HMODULE instance, UINT id) +PLUGIN_EXPORT void Finalize(void* data) { - std::map::iterator i1 = g_Counters.find(id); - if (i1 != g_Counters.end()) - { - g_Counters.erase(i1); - } - - std::map::iterator i2 = g_ProcessNames.find(id); - if (i2 != g_ProcessNames.end()) - { - g_ProcessNames.erase(i2); - } + MeasureData* measure = (MeasureData*)data; + delete measure; } - -UINT GetPluginVersion() -{ - return 1003; -} - -LPCTSTR GetPluginAuthor() -{ - return L"David Negstad"; -} \ No newline at end of file diff --git a/Plugins/PluginSpeedFan/PluginSpeedFan.rc b/Plugins/PluginSpeedFan/PluginSpeedFan.rc index 62924414..c0c74441 100644 --- a/Plugins/PluginSpeedFan/PluginSpeedFan.rc +++ b/Plugins/PluginSpeedFan/PluginSpeedFan.rc @@ -1,10 +1,5 @@ -// Microsoft Developer Studio generated resource script. -// - +#include #include "../../Version.h" -#define APSTUDIO_READONLY_SYMBOLS -#include "windows.h" -#undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // @@ -18,7 +13,7 @@ VS_VERSION_INFO VERSIONINFO #ifdef _DEBUG FILEFLAGS VS_FF_DEBUG #else - FILEFLAGS 0x0L + FILEFLAGS 0x0L #endif FILEOS VOS_NT_WINDOWS32 FILETYPE VFT_DLL @@ -28,11 +23,9 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "FileDescription", "SpeedFan Plugin for Rainmeter" VALUE "FileVersion", "1.2.0.0" - VALUE "InternalName", "PluginSpeedFan" - VALUE "LegalCopyright", "Copyright (C) 2010 - Rainy" - VALUE "OriginalFilename", "PluginSpeedFan.dll" + VALUE "LegalCopyright", "© 2010 - Rainy" + VALUE "OriginalFilename", "SpeedFanPlugin.dll" VALUE "ProductName", "Rainmeter" #ifdef _WIN64 VALUE "ProductVersion", STRPRODUCTVER " (64-bit)" diff --git a/Plugins/PluginSpeedFan/PluginSpeedFan.vcxproj b/Plugins/PluginSpeedFan/PluginSpeedFan.vcxproj index c810f1c3..f031e1aa 100644 --- a/Plugins/PluginSpeedFan/PluginSpeedFan.vcxproj +++ b/Plugins/PluginSpeedFan/PluginSpeedFan.vcxproj @@ -73,10 +73,10 @@ false $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true SpeedFanPlugin SpeedFanPlugin SpeedFanPlugin diff --git a/Plugins/PluginSpeedFan/SpeedFanPlugin.cpp b/Plugins/PluginSpeedFan/SpeedFanPlugin.cpp index 4676632a..0eb5efb6 100644 --- a/Plugins/PluginSpeedFan/SpeedFanPlugin.cpp +++ b/Plugins/PluginSpeedFan/SpeedFanPlugin.cpp @@ -17,25 +17,13 @@ */ #include -#include -#include -#include +#include #include "../../Library/Export.h" // Rainmeter's exported functions #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point -/* The exported functions */ -extern "C" -{ -__declspec( dllexport ) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); -__declspec( dllexport ) void Finalize(HMODULE instance, UINT id); -__declspec( dllexport ) double Update2(UINT id); -__declspec( dllexport ) UINT GetPluginVersion(); -__declspec( dllexport ) LPCTSTR GetPluginAuthor(); -} - -#pragma pack(1) +#pragma pack(push, 1) struct SpeedFanData { WORD version; @@ -49,6 +37,7 @@ struct SpeedFanData INT fans[32]; INT volts[32]; }; +#pragma pack(pop) enum SensorType { @@ -57,7 +46,7 @@ enum SensorType TYPE_VOLT }; -enum TempScale +enum ScaleType { SCALE_SOURCE, SCALE_CENTIGRADE, @@ -65,166 +54,99 @@ enum TempScale SCALE_KELVIN }; -bool ReadSharedData(SensorType type, TempScale scale, UINT number, double* value); - -static std::map g_Types; -static std::map g_Scales; -static std::map g_Numbers; - -/* - This function is called when the measure is initialized. - The function must return the maximum value that can be measured. - The return value can also be 0, which means that Rainmeter will - track the maximum value automatically. The parameters for this - function are: - - instance The instance of this DLL - iniFile The name of the ini-file (usually Rainmeter.ini) - section The name of the section in the ini-file for this measure - id The identifier for the measure. This is used to identify the measures that use the same plugin. -*/ -UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) +struct MeasureData { - /* Read our own settings from the ini-file */ - LPCTSTR type = ReadConfigString(section, L"SpeedFanType", L"TEMPERATURE"); - if (type) - { - if (_wcsicmp(L"TEMPERATURE", type) == 0) - { - g_Types[id] = TYPE_TEMP; + SensorType type; + ScaleType scale; + UINT number; - LPCTSTR scale = ReadConfigString(section, L"SpeedFanScale", L"C"); - if (scale) - { - if (_wcsicmp(L"C", scale) == 0) - { - g_Scales[id] = SCALE_CENTIGRADE; - } - else if (_wcsicmp(L"F", scale) == 0) - { - g_Scales[id] = SCALE_FARENHEIT; - } - else if (_wcsicmp(L"K", scale) == 0) - { - g_Scales[id] = SCALE_KELVIN; - } - else - { - std::wstring error = L"SpeedFanPlugin.dll: SpeedFanScale="; - error += scale; - error += L" is not valid in ["; - error += section; - error += L"]"; - LSLog(LOG_ERROR, NULL, error.c_str()); - } - } - } - else if (_wcsicmp(L"FAN", type) == 0) + MeasureData() : type(TYPE_TEMP), scale(SCALE_SOURCE), number() {} +}; + +void ReadSharedData(SensorType type, ScaleType scale, UINT number, double* value); + +PLUGIN_EXPORT void Initialize(void** data) +{ + MeasureData* measure = new MeasureData; + *data = measure; +} + +PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) +{ + MeasureData* measure = (MeasureData*)data; + + LPCWSTR type = RmReadString(rm, L"SpeedFanType", L"TEMPERATURE"); + if (_wcsicmp(L"TEMPERATURE", type) == 0) + { + measure->type = TYPE_TEMP; + + LPCWSTR scale = RmReadString(rm, L"SpeedFanScale", L"C"); + if (_wcsicmp(L"C", scale) == 0) { - g_Types[id] = TYPE_FAN; + measure->scale = SCALE_CENTIGRADE; } - else if (_wcsicmp(L"VOLTAGE", type) == 0) + else if (_wcsicmp(L"F", scale) == 0) { - g_Types[id] = TYPE_VOLT; + measure->scale = SCALE_FARENHEIT; + } + else if (_wcsicmp(L"K", scale) == 0) + { + measure->scale = SCALE_KELVIN; } else { - std::wstring error = L"SpeedFanPlugin.dll: SpeedFanType="; - error += type; - error += L" is not valid in ["; - error += section; - error += L"]"; - LSLog(LOG_ERROR, NULL, error.c_str()); + WCHAR buffer[256]; + _snwprintf_s(buffer, _TRUNCATE, L"SpeedFanPlugin.dll: SpeedFanScale=%s is not valid in [%s]", scale, RmGetMeasureName(rm)); + RmLog(LOG_ERROR, buffer); } } - - LPCTSTR data = ReadConfigString(section, L"SpeedFanNumber", L"0"); - if (data) + else if (_wcsicmp(L"FAN", type) == 0) { - g_Numbers[id] = _wtoi(data); + measure->type = TYPE_FAN; } - - return 0; -} - -/* -This function is called when new value should be measured. -The function returns the new value. -*/ -double Update2(UINT id) -{ - double value = 0.0; - - std::map::const_iterator type = g_Types.find(id); - std::map::const_iterator scale = g_Scales.find(id); - std::map::const_iterator number = g_Numbers.find(id); - - if (type == g_Types.end() || number == g_Numbers.end()) + else if (_wcsicmp(L"VOLTAGE", type) == 0) { - return 0.0; // No id in the map. How this can be ???? - } - - if ((*type).second == TYPE_TEMP) - { - if (scale != g_Scales.end() && - ReadSharedData((*type).second, (*scale).second, (*number).second, &value)) - { - return value; - } + measure->type = TYPE_VOLT; } else { - if (ReadSharedData((*type).second, SCALE_SOURCE, (*number).second, &value)) - { - return value; - } + WCHAR buffer[256]; + _snwprintf_s(buffer, _TRUNCATE, L"SpeedFanPlugin.dll: SpeedFanType=%s is not valid in [%s]", type, RmGetMeasureName(rm)); + RmLog(LOG_ERROR, buffer); } - return 0.0; + measure->number = RmReadInt(rm, L"SpeedFanNumber", 0); } -/* - If the measure needs to free resources before quitting. - The plugin can export Finalize function, which is called - when Rainmeter quits (or refreshes). -*/ -void Finalize(HMODULE instance, UINT id) +PLUGIN_EXPORT double Update(void* data) { - std::map::iterator i1 = g_Types.find(id); - if (i1 != g_Types.end()) - { - g_Types.erase(i1); - } + MeasureData* measure = (MeasureData*)data; + double value = 0.0; - std::map::iterator i2 = g_Numbers.find(id); - if (i2 != g_Numbers.end()) - { - g_Numbers.erase(i2); - } + ReadSharedData(measure->type, measure->scale, measure->number, &value); - std::map::iterator i3 = g_Scales.find(id); - if (i3 != g_Scales.end()) - { - g_Scales.erase(i3); - } + return value; +} + +PLUGIN_EXPORT void Finalize(void* data) +{ + MeasureData* measure = (MeasureData*)data; + delete measure; } /* Get the data from shared memory. */ -bool ReadSharedData(SensorType type, TempScale scale, UINT number, double* value) +void ReadSharedData(SensorType type, ScaleType scale, UINT number, double* value) { - SpeedFanData* ptr; - HANDLE hData; + HANDLE hData = OpenFileMapping(FILE_MAP_READ, FALSE, L"SFSharedMemory_ALM"); + if (hData == NULL) return; - hData = OpenFileMapping(FILE_MAP_READ, FALSE, L"SFSharedMemory_ALM"); - if (hData == NULL) return false; - - ptr = (SpeedFanData*)MapViewOfFile(hData, FILE_MAP_READ, 0, 0, 0); + SpeedFanData* ptr = (SpeedFanData*)MapViewOfFile(hData, FILE_MAP_READ, 0, 0, 0); if (ptr == 0) { CloseHandle(hData); - return false; + return; } if (ptr->version == 1) @@ -267,21 +189,9 @@ bool ReadSharedData(SensorType type, TempScale scale, UINT number, double* value } else { - LSLog(LOG_ERROR, NULL, L"SpeedFanPlugin.dll: Incorrect shared memory version"); + RmLog(LOG_ERROR, L"SpeedFanPlugin.dll: Incorrect shared memory version"); } UnmapViewOfFile(ptr); CloseHandle(hData); - - return true; } - -UINT GetPluginVersion() -{ - return 1002; -} - -LPCTSTR GetPluginAuthor() -{ - return L"Rainy (rainy@iki.fi)"; -} \ No newline at end of file diff --git a/Plugins/PluginSysInfo/PluginSysInfo.vcxproj b/Plugins/PluginSysInfo/PluginSysInfo.vcxproj index b9864646..7719c150 100644 --- a/Plugins/PluginSysInfo/PluginSysInfo.vcxproj +++ b/Plugins/PluginSysInfo/PluginSysInfo.vcxproj @@ -73,10 +73,10 @@ false $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true SysInfo SysInfo SysInfo diff --git a/Plugins/PluginVirtualDesktops/PluginVirtualDesktops.vcxproj b/Plugins/PluginVirtualDesktops/PluginVirtualDesktops.vcxproj index 98b0b9ff..c133bb89 100644 --- a/Plugins/PluginVirtualDesktops/PluginVirtualDesktops.vcxproj +++ b/Plugins/PluginVirtualDesktops/PluginVirtualDesktops.vcxproj @@ -73,10 +73,10 @@ false $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true VirtualDesktops VirtualDesktops VirtualDesktops diff --git a/Plugins/PluginWebParser/PluginWebParser.vcxproj b/Plugins/PluginWebParser/PluginWebParser.vcxproj index 8cb44a86..50d33ba4 100644 --- a/Plugins/PluginWebParser/PluginWebParser.vcxproj +++ b/Plugins/PluginWebParser/PluginWebParser.vcxproj @@ -67,10 +67,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ false diff --git a/Plugins/PluginWifiStatus/PluginWifiStatus.vcxproj b/Plugins/PluginWifiStatus/PluginWifiStatus.vcxproj index bc76f4e0..485b4501 100644 --- a/Plugins/PluginWifiStatus/PluginWifiStatus.vcxproj +++ b/Plugins/PluginWifiStatus/PluginWifiStatus.vcxproj @@ -67,10 +67,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ false diff --git a/Plugins/PluginWin7Audio/PluginWin7Audio.vcxproj b/Plugins/PluginWin7Audio/PluginWin7Audio.vcxproj index f007a479..46fd11ee 100644 --- a/Plugins/PluginWin7Audio/PluginWin7Audio.vcxproj +++ b/Plugins/PluginWin7Audio/PluginWin7Audio.vcxproj @@ -68,10 +68,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ false diff --git a/Plugins/PluginWindowMessage/PluginWindowMessage.vcxproj b/Plugins/PluginWindowMessage/PluginWindowMessage.vcxproj index 318533c2..609af6e6 100644 --- a/Plugins/PluginWindowMessage/PluginWindowMessage.vcxproj +++ b/Plugins/PluginWindowMessage/PluginWindowMessage.vcxproj @@ -67,10 +67,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ false diff --git a/Plugins/PluginWindowMessage/WindowMessagePlugin.cpp b/Plugins/PluginWindowMessage/WindowMessagePlugin.cpp index ff523cd0..8037a308 100644 --- a/Plugins/PluginWindowMessage/WindowMessagePlugin.cpp +++ b/Plugins/PluginWindowMessage/WindowMessagePlugin.cpp @@ -17,211 +17,132 @@ */ #include -#include -#include -#include -#include -#include +#include +#include "../../Library/RawString.h" #include "../../Library/Export.h" // Rainmeter's exported functions - #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point -/* The exported functions */ -extern "C" +struct MeasureData { -__declspec( dllexport ) UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id); -__declspec( dllexport ) void Finalize(HMODULE instance, UINT id); -__declspec( dllexport ) double Update2(UINT id); -__declspec( dllexport ) LPCTSTR GetString(UINT id, UINT flags); -__declspec( dllexport ) UINT GetPluginVersion(); -__declspec( dllexport ) LPCTSTR GetPluginAuthor(); -__declspec( dllexport ) void ExecuteBang(LPCTSTR args, UINT id); -} - -struct windowData -{ - std::wstring windowName; - std::wstring windowClass; + CRawString windowName; + CRawString windowClass; + CRawString value; WPARAM wParam; LPARAM lParam; DWORD uMsg; - std::wstring value; - DWORD result; + + MeasureData() : wParam(), lParam(), uMsg() {} }; -static std::map g_Values; - -/* - This function is called when the measure is initialized. - The function must return the maximum value that can be measured. - The return value can also be 0, which means that Rainmeter will - track the maximum value automatically. The parameters for this - function are: - - instance The instance of this DLL - iniFile The name of the ini-file (usually Rainmeter.ini) - section The name of the section in the ini-file for this measure - id The identifier for the measure. This is used to identify the measures that use the same plugin. -*/ -UINT Initialize(HMODULE instance, LPCTSTR iniFile, LPCTSTR section, UINT id) +PLUGIN_EXPORT void Initialize(void** data) { - windowData wData; - wData.uMsg = 0; - wData.wParam = 0; - wData.lParam = 0; - wData.result = 0; - - /* Read our own settings from the ini-file */ - LPCTSTR data = ReadConfigString(section, L"WindowName", NULL); - if (data) - { - wData.windowName = data; - } - - data = ReadConfigString(section, L"WindowClass", NULL); - if (data) - { - wData.windowClass = data; - } - - data = ReadConfigString(section, L"WindowMessage", NULL); - if (data) - { - DWORD uMsg, wParam, lParam; - if (3 == swscanf(data, L"%u %u %u", &uMsg, &wParam, &lParam)) - { - wData.uMsg = uMsg; - wData.wParam = wParam; - wData.lParam = lParam; - } - } - - g_Values[id] = wData; - - return 0; + MeasureData* measure = new MeasureData; + *data = measure; } -/* -This function is called when new value should be measured. -The function returns the new value. -*/ -double Update2(UINT id) +PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue) { - std::map::iterator i = g_Values.find(id); - if (i != g_Values.end()) + MeasureData* measure = (MeasureData*)data; + + measure->windowName = RmReadString(rm, L"WindowName", L""); + measure->windowClass = RmReadString(rm, L"WindowClass", L""); + + DWORD uMsg, wParam, lParam; + LPCWSTR message = RmReadString(rm, L"WindowMessage", L""); + if (3 == swscanf(message, L"%u %u %u", &uMsg, &wParam, &lParam)) { - const std::wstring& winName = (*i).second.windowName; - const std::wstring& winClass = (*i).second.windowClass; - HWND hwnd = FindWindow(winClass.empty() ? NULL : winClass.c_str(), winName.empty() ? NULL : winName.c_str()); - if (hwnd) - { - if ((*i).second.uMsg == 0) - { - // Get window text - WCHAR buffer[1024]; - buffer[0] = 0; - GetWindowText(hwnd, buffer, 1024); - (*i).second.value = buffer; - } - else - { - (*i).second.result = (DWORD)SendMessage(hwnd, (*i).second.uMsg, (*i).second.wParam, (*i).second.lParam); - return (int)((*i).second.result); - } - } + measure->uMsg = uMsg; + measure->wParam = wParam; + measure->lParam = lParam; } - return 0; } -LPCTSTR GetString(UINT id, UINT flags) +PLUGIN_EXPORT double Update(void* data) { - static WCHAR buffer[64]; + MeasureData* measure = (MeasureData*)data; - std::map::iterator i = g_Values.find(id); - if (i != g_Values.end()) + HWND hwnd = FindWindow( + measure->windowClass.empty() ? NULL : measure->windowClass.c_str(), + measure->windowName.empty() ? NULL : measure->windowName.c_str()); + + if (hwnd) { - if (((*i).second).value.empty()) + if (measure->uMsg == 0) { - _itow(((*i).second).result, buffer, 10); - return buffer; + // Get window text + WCHAR buffer[256]; + GetWindowText(hwnd, buffer, 256); + measure->value = buffer; } else { - return ((*i).second).value.c_str(); + return (double)SendMessage(hwnd, measure->uMsg, measure->wParam, measure->lParam); } } + else if (measure->uMsg == 0) + { + measure->value.clear(); + } + + return 0.0; +} + +PLUGIN_EXPORT LPCWSTR GetString(void* data) +{ + MeasureData* measure = (MeasureData*)data; + + if (measure->uMsg == 0) + { + return measure->value.c_str(); + } return NULL; } -/* - If the measure needs to free resources before quitting. - The plugin can export Finalize function, which is called - when Rainmeter quits (or refreshes). -*/ -void Finalize(HMODULE instance, UINT id) +PLUGIN_EXPORT void Finalize(void* data) { - std::map::iterator i1 = g_Values.find(id); - if (i1 != g_Values.end()) + MeasureData* measure = (MeasureData*)data; + delete measure; +} + +PLUGIN_EXPORT void ExecuteBang(void* data, LPCWSTR args) +{ + MeasureData* measure = (MeasureData*)data; + + const WCHAR* pos = wcschr(args, L' '); + if (pos) { - g_Values.erase(i1); - } -} - -UINT GetPluginVersion() -{ - return 1001; -} - -LPCTSTR GetPluginAuthor() -{ - return L"Rainy (rainy@iki.fi)"; -} - -void ExecuteBang(LPCTSTR args, UINT id) -{ - std::wstring wholeBang = args; - - size_t pos = wholeBang.find(L' '); - if (pos != -1) - { - std::wstring bang = wholeBang.substr(0, pos); - wholeBang.erase(0, pos + 1); - - if (_wcsicmp(bang.c_str(), L"SendMessage") == 0) + size_t len = pos - args; + if (_wcsnicmp(args, L"SendMessage", len) == 0) { + ++pos; + // Parse parameters DWORD uMsg, wParam, lParam; - if (3 == swscanf(wholeBang.c_str(), L"%u %u %u", &uMsg, &wParam, &lParam)) + if (3 == swscanf(pos, L"%u %u %u", &uMsg, &wParam, &lParam)) { - std::map::iterator i = g_Values.find(id); - if (i != g_Values.end()) + + HWND hwnd = FindWindow( + measure->windowClass.empty() ? NULL : measure->windowClass.c_str(), + measure->windowName.empty() ? NULL : measure->windowName.c_str()); + + if (hwnd) { - std::wstring& winName = (*i).second.windowName; - std::wstring& winClass = (*i).second.windowClass; - HWND hwnd = FindWindow(winClass.empty() ? NULL : winClass.c_str(), winName.empty() ? NULL : winName.c_str()); - if (hwnd) - { - PostMessage(hwnd, uMsg, wParam, lParam); - } - else - { - LSLog(LOG_ERROR, NULL, L"WindowMessagePlugin.dll: Unable to find window"); - } + PostMessage(hwnd, uMsg, wParam, lParam); } else { - LSLog(LOG_ERROR, NULL, L"WindowMessagePlugin.dll: Unable to find window data"); + RmLog(LOG_ERROR, L"WindowMessagePlugin.dll: Unable to find window"); } } else { - LSLog(LOG_WARNING, NULL, L"WindowMessagePlugin.dll: Incorrect number of arguments for bang"); + RmLog(LOG_WARNING, L"WindowMessagePlugin.dll: Incorrect number of arguments for bang"); } return; } } - LSLog(LOG_WARNING, NULL, L"WindowMessagePlugin.dll: Unknown bang"); + RmLog(LOG_WARNING, L"WindowMessagePlugin.dll: Unknown bang"); } diff --git a/Plugins/PluginiTunes/PluginiTunes.vcxproj b/Plugins/PluginiTunes/PluginiTunes.vcxproj index 48153e34..9b97b2be 100644 --- a/Plugins/PluginiTunes/PluginiTunes.vcxproj +++ b/Plugins/PluginiTunes/PluginiTunes.vcxproj @@ -68,10 +68,10 @@ <_ProjectFileVersion>10.0.30319.1 $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ - false + true $(SolutionDir)TestBench\x64\$(Configuration)\Plugins\ .\x64\$(Configuration)\ - false + true $(SolutionDir)TestBench\x32\$(Configuration)\Plugins\ .\x32\$(Configuration)\ false diff --git a/Rainmeter.props b/Rainmeter.props index a5b04092..8487eb20 100644 --- a/Rainmeter.props +++ b/Rainmeter.props @@ -3,4 +3,7 @@ Windows7.1SDK + + v100 + \ No newline at end of file diff --git a/Rainmeter.sln b/Rainmeter.sln index 0176deb7..4c10995d 100644 --- a/Rainmeter.sln +++ b/Rainmeter.sln @@ -1,5 +1,6 @@ + Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 +# Visual Studio 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Application", "Application\Application.vcxproj", "{D2A0903C-E760-4134-AE61-3D55BF8F760C}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Language", "Language\Language.vcxproj", "{6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}" @@ -11,47 +12,59 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Library", "Library\Library. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SkinInstaller", "SkinInstaller\SkinInstaller.vcxproj", "{6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DllExporter", "Plugins\API\DllExporter\DllExporter.csproj", "{49D56CA5-54AB-45C9-A245-EAE588FCBFE1}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginAdvancedCPU", "Plugins\PluginAdvancedCPU\PluginAdvancedCPU.vcxproj", "{EE8EC522-8430-4B46-86A3-D943D77F9E4B}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginCoreTemp", "Plugins\PluginCoreTemp\PluginCoreTemp.vcxproj", "{F32FA418-8DF4-4E94-B92B-EBD502F5DC07}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginExample", "Plugins\PluginExample\PluginExample.vcxproj", "{761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginExampleCS", "Plugins\PluginExampleCS\PluginExampleCS.csproj", "{D31F73ED-3978-44FA-B599-49584BA30D3A}" + ProjectSection(ProjectDependencies) = postProject + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1} = {49D56CA5-54AB-45C9-A245-EAE588FCBFE1} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginFolderInfo", "Plugins\PluginFolderInfo\PluginFolderInfo.vcxproj", "{A221819D-4263-42AA-B22A-C022924842A7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginInputText", "Plugins\PluginInputText\PluginInputText.csproj", "{2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}" + ProjectSection(ProjectDependencies) = postProject + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1} = {49D56CA5-54AB-45C9-A245-EAE588FCBFE1} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginiTunes", "Plugins\PluginiTunes\PluginiTunes.vcxproj", "{A2DD3CBE-B140-4892-A875-24107FA52518}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginMediaKey", "Plugins\PluginMediaKey\PluginMediaKey.vcxproj", "{EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginNowPlaying", "Plugins\PluginNowPlaying\PluginNowPlaying.vcxproj", "{C7FECFCD-E6C6-4F95-BB9A-E1762B043969}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginPerfMon", "Plugins\PluginPerfMon\PluginPerfMon.vcxproj", "{5344B52B-BAC3-479C-B41D-D465B8BDA1AD}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginPing", "Plugins\PluginPing\PluginPing.vcxproj", "{C862B662-5CC6-4E79-B1B3-905E0B98D627}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginPower", "Plugins\PluginPower\PluginPower.vcxproj", "{C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginProcess", "Plugins\PluginProcess\PluginProcess.vcxproj", "{05203741-CD80-4060-8218-EC5D1120FE3E}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginQuote", "Plugins\PluginQuote\PluginQuote.vcxproj", "{C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginRecycleManager", "Plugins\PluginRecycleManager\PluginRecycleManager.vcxproj", "{4F8C4C09-431C-45C4-830B-32006E783C3A}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginResMon", "Plugins\PluginResMon\PluginResMon.vcxproj", "{17D3BD92-6F5D-438C-A89B-88F4CE06DB94}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginSpeedFan", "Plugins\PluginSpeedFan\PluginSpeedFan.vcxproj", "{D10AB316-0F7A-4551-BE4F-385E04CCF1E8}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginSysInfo", "Plugins\PluginSysInfo\PluginSysInfo.vcxproj", "{6EBCA4DA-8CC7-42FE-8F45-878ABE165078}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginVirtualDesktops", "Plugins\PluginVirtualDesktops\PluginVirtualDesktops.vcxproj", "{4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginWebParser", "Plugins\PluginWebParser\PluginWebParser.vcxproj", "{8B820B9F-C154-417C-A090-42198F2AF496}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginWindowMessage", "Plugins\PluginWindowMessage\PluginWindowMessage.vcxproj", "{B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginRecycleManager", "Plugins\PluginRecycleManager\PluginRecycleManager.vcxproj", "{4F8C4C09-431C-45C4-830B-32006E783C3A}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginiTunes", "Plugins\PluginiTunes\PluginiTunes.vcxproj", "{A2DD3CBE-B140-4892-A875-24107FA52518}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginWifiStatus", "Plugins\PluginWifiStatus\PluginWifiStatus.vcxproj", "{45A34285-56DD-4521-912B-3F884D36FA35}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginWin7Audio", "Plugins\PluginWin7Audio\PluginWin7Audio.vcxproj", "{6D032D6B-7656-4743-B454-3388E2921EB0}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginVirtualDesktops", "Plugins\PluginVirtualDesktops\PluginVirtualDesktops.vcxproj", "{4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginMediaKey", "Plugins\PluginMediaKey\PluginMediaKey.vcxproj", "{EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginFolderInfo", "Plugins\PluginFolderInfo\PluginFolderInfo.vcxproj", "{A221819D-4263-42AA-B22A-C022924842A7}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginCoreTemp", "Plugins\PluginCoreTemp\PluginCoreTemp.vcxproj", "{F32FA418-8DF4-4E94-B92B-EBD502F5DC07}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginNowPlaying", "Plugins\PluginNowPlaying\PluginNowPlaying.vcxproj", "{C7FECFCD-E6C6-4F95-BB9A-E1762B043969}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginProcess", "Plugins\PluginProcess\PluginProcess.vcxproj", "{05203741-CD80-4060-8218-EC5D1120FE3E}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginWindowMessage", "Plugins\PluginWindowMessage\PluginWindowMessage.vcxproj", "{B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -71,8 +84,8 @@ Global {D2A0903C-E760-4134-AE61-3D55BF8F760C}.Release|x64.Build.0 = Release|x64 {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Debug|Win32.ActiveCfg = Debug|Win32 {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Debug|Win32.Build.0 = Debug|Win32 - {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Debug|x64.ActiveCfg = Release|x64 - {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Debug|x64.Build.0 = Release|x64 + {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Debug|x64.ActiveCfg = Debug|x64 + {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Debug|x64.Build.0 = Debug|x64 {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Release|Win32.ActiveCfg = Release|Win32 {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Release|Win32.Build.0 = Release|Win32 {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Release|x64.ActiveCfg = Release|x64 @@ -93,6 +106,14 @@ Global {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}.Release|Win32.Build.0 = Release|Win32 {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}.Release|x64.ActiveCfg = Release|x64 {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}.Release|x64.Build.0 = Release|x64 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Debug|Win32.ActiveCfg = Debug|x86 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Debug|Win32.Build.0 = Debug|x86 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Debug|x64.ActiveCfg = Debug|x64 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Debug|x64.Build.0 = Debug|x64 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Release|Win32.ActiveCfg = Release|x86 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Release|Win32.Build.0 = Release|x86 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Release|x64.ActiveCfg = Release|x64 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Release|x64.Build.0 = Release|x64 {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Debug|Win32.ActiveCfg = Debug|Win32 {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Debug|Win32.Build.0 = Debug|Win32 {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Debug|x64.ActiveCfg = Debug|x64 @@ -101,6 +122,14 @@ Global {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Release|Win32.Build.0 = Release|Win32 {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Release|x64.ActiveCfg = Release|x64 {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Release|x64.Build.0 = Release|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|Win32.ActiveCfg = Debug|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|Win32.Build.0 = Debug|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|x64.ActiveCfg = Debug|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|x64.Build.0 = Debug|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|Win32.ActiveCfg = Release|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|Win32.Build.0 = Release|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|x64.ActiveCfg = Release|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|x64.Build.0 = Release|x64 {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Debug|Win32.ActiveCfg = Debug|Win32 {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Debug|Win32.Build.0 = Debug|Win32 {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Debug|x64.ActiveCfg = Debug|x64 @@ -109,6 +138,54 @@ Global {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Release|Win32.Build.0 = Release|Win32 {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Release|x64.ActiveCfg = Release|x64 {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Release|x64.Build.0 = Release|x64 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Debug|Win32.ActiveCfg = Debug|x86 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Debug|Win32.Build.0 = Debug|x86 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Debug|x64.ActiveCfg = Debug|x64 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Debug|x64.Build.0 = Debug|x64 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Release|Win32.ActiveCfg = Release|x86 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Release|Win32.Build.0 = Release|x86 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Release|x64.ActiveCfg = Release|x64 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Release|x64.Build.0 = Release|x64 + {A221819D-4263-42AA-B22A-C022924842A7}.Debug|Win32.ActiveCfg = Debug|Win32 + {A221819D-4263-42AA-B22A-C022924842A7}.Debug|Win32.Build.0 = Debug|Win32 + {A221819D-4263-42AA-B22A-C022924842A7}.Debug|x64.ActiveCfg = Debug|x64 + {A221819D-4263-42AA-B22A-C022924842A7}.Debug|x64.Build.0 = Debug|x64 + {A221819D-4263-42AA-B22A-C022924842A7}.Release|Win32.ActiveCfg = Release|Win32 + {A221819D-4263-42AA-B22A-C022924842A7}.Release|Win32.Build.0 = Release|Win32 + {A221819D-4263-42AA-B22A-C022924842A7}.Release|x64.ActiveCfg = Release|x64 + {A221819D-4263-42AA-B22A-C022924842A7}.Release|x64.Build.0 = Release|x64 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Debug|Win32.ActiveCfg = Debug|x86 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Debug|Win32.Build.0 = Debug|x86 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Debug|x64.ActiveCfg = Debug|x64 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Debug|x64.Build.0 = Debug|x64 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Release|Win32.ActiveCfg = Release|x86 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Release|Win32.Build.0 = Release|x86 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Release|x64.ActiveCfg = Release|x64 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Release|x64.Build.0 = Release|x64 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|Win32.ActiveCfg = Debug|Win32 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|Win32.Build.0 = Debug|Win32 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|x64.ActiveCfg = Debug|x64 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|x64.Build.0 = Debug|x64 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|Win32.ActiveCfg = Release|Win32 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|Win32.Build.0 = Release|Win32 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|x64.ActiveCfg = Release|x64 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|x64.Build.0 = Release|x64 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|Win32.ActiveCfg = Debug|Win32 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|Win32.Build.0 = Debug|Win32 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|x64.ActiveCfg = Debug|x64 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|x64.Build.0 = Debug|x64 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|Win32.ActiveCfg = Release|Win32 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|Win32.Build.0 = Release|Win32 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|x64.ActiveCfg = Release|x64 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|x64.Build.0 = Release|x64 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Debug|Win32.ActiveCfg = Debug|Win32 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Debug|Win32.Build.0 = Debug|Win32 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Debug|x64.ActiveCfg = Debug|x64 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Debug|x64.Build.0 = Debug|x64 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Release|Win32.ActiveCfg = Release|Win32 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Release|Win32.Build.0 = Release|Win32 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Release|x64.ActiveCfg = Release|x64 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Release|x64.Build.0 = Release|x64 {5344B52B-BAC3-479C-B41D-D465B8BDA1AD}.Debug|Win32.ActiveCfg = Debug|Win32 {5344B52B-BAC3-479C-B41D-D465B8BDA1AD}.Debug|Win32.Build.0 = Debug|Win32 {5344B52B-BAC3-479C-B41D-D465B8BDA1AD}.Debug|x64.ActiveCfg = Debug|x64 @@ -133,6 +210,14 @@ Global {C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}.Release|Win32.Build.0 = Release|Win32 {C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}.Release|x64.ActiveCfg = Release|x64 {C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}.Release|x64.Build.0 = Release|x64 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|Win32.ActiveCfg = Debug|Win32 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|Win32.Build.0 = Debug|Win32 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|x64.ActiveCfg = Debug|x64 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|x64.Build.0 = Debug|x64 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|Win32.ActiveCfg = Release|Win32 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|Win32.Build.0 = Release|Win32 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|x64.ActiveCfg = Release|x64 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|x64.Build.0 = Release|x64 {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Debug|Win32.ActiveCfg = Debug|Win32 {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Debug|Win32.Build.0 = Debug|Win32 {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Debug|x64.ActiveCfg = Debug|x64 @@ -141,6 +226,14 @@ Global {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Release|Win32.Build.0 = Release|Win32 {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Release|x64.ActiveCfg = Release|x64 {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Release|x64.Build.0 = Release|x64 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|Win32.ActiveCfg = Debug|Win32 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|Win32.Build.0 = Debug|Win32 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|x64.ActiveCfg = Debug|x64 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|x64.Build.0 = Debug|x64 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|Win32.ActiveCfg = Release|Win32 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|Win32.Build.0 = Release|Win32 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|x64.ActiveCfg = Release|x64 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|x64.Build.0 = Release|x64 {17D3BD92-6F5D-438C-A89B-88F4CE06DB94}.Debug|Win32.ActiveCfg = Debug|Win32 {17D3BD92-6F5D-438C-A89B-88F4CE06DB94}.Debug|Win32.Build.0 = Debug|Win32 {17D3BD92-6F5D-438C-A89B-88F4CE06DB94}.Debug|x64.ActiveCfg = Debug|x64 @@ -165,6 +258,14 @@ Global {6EBCA4DA-8CC7-42FE-8F45-878ABE165078}.Release|Win32.Build.0 = Release|Win32 {6EBCA4DA-8CC7-42FE-8F45-878ABE165078}.Release|x64.ActiveCfg = Release|x64 {6EBCA4DA-8CC7-42FE-8F45-878ABE165078}.Release|x64.Build.0 = Release|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|Win32.ActiveCfg = Debug|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|Win32.Build.0 = Debug|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|x64.ActiveCfg = Debug|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|x64.Build.0 = Debug|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|Win32.ActiveCfg = Release|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|Win32.Build.0 = Release|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|x64.ActiveCfg = Release|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|x64.Build.0 = Release|x64 {8B820B9F-C154-417C-A090-42198F2AF496}.Debug|Win32.ActiveCfg = Debug|Win32 {8B820B9F-C154-417C-A090-42198F2AF496}.Debug|Win32.Build.0 = Debug|Win32 {8B820B9F-C154-417C-A090-42198F2AF496}.Debug|x64.ActiveCfg = Debug|x64 @@ -173,30 +274,6 @@ Global {8B820B9F-C154-417C-A090-42198F2AF496}.Release|Win32.Build.0 = Release|Win32 {8B820B9F-C154-417C-A090-42198F2AF496}.Release|x64.ActiveCfg = Release|x64 {8B820B9F-C154-417C-A090-42198F2AF496}.Release|x64.Build.0 = Release|x64 - {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|Win32.ActiveCfg = Debug|Win32 - {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|Win32.Build.0 = Debug|Win32 - {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|x64.ActiveCfg = Debug|x64 - {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|x64.Build.0 = Debug|x64 - {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|Win32.ActiveCfg = Release|Win32 - {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|Win32.Build.0 = Release|Win32 - {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|x64.ActiveCfg = Release|x64 - {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|x64.Build.0 = Release|x64 - {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|Win32.ActiveCfg = Debug|Win32 - {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|Win32.Build.0 = Debug|Win32 - {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|x64.ActiveCfg = Debug|x64 - {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|x64.Build.0 = Debug|x64 - {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|Win32.ActiveCfg = Release|Win32 - {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|Win32.Build.0 = Release|Win32 - {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|x64.ActiveCfg = Release|x64 - {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|x64.Build.0 = Release|x64 - {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|Win32.ActiveCfg = Debug|Win32 - {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|Win32.Build.0 = Debug|Win32 - {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|x64.ActiveCfg = Debug|x64 - {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|x64.Build.0 = Debug|x64 - {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|Win32.ActiveCfg = Release|Win32 - {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|Win32.Build.0 = Release|Win32 - {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|x64.ActiveCfg = Release|x64 - {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|x64.Build.0 = Release|x64 {45A34285-56DD-4521-912B-3F884D36FA35}.Debug|Win32.ActiveCfg = Debug|Win32 {45A34285-56DD-4521-912B-3F884D36FA35}.Debug|Win32.Build.0 = Debug|Win32 {45A34285-56DD-4521-912B-3F884D36FA35}.Debug|x64.ActiveCfg = Debug|x64 @@ -213,51 +290,14 @@ Global {6D032D6B-7656-4743-B454-3388E2921EB0}.Release|Win32.Build.0 = Release|Win32 {6D032D6B-7656-4743-B454-3388E2921EB0}.Release|x64.ActiveCfg = Release|x64 {6D032D6B-7656-4743-B454-3388E2921EB0}.Release|x64.Build.0 = Release|x64 - {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|Win32.ActiveCfg = Debug|Win32 - {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|Win32.Build.0 = Debug|Win32 - {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|x64.ActiveCfg = Debug|x64 - {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|x64.Build.0 = Debug|x64 - {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|Win32.ActiveCfg = Release|Win32 - {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|Win32.Build.0 = Release|Win32 - {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|x64.ActiveCfg = Release|x64 - {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|x64.Build.0 = Release|x64 - {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|Win32.ActiveCfg = Debug|Win32 - {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|Win32.Build.0 = Debug|Win32 - {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|x64.ActiveCfg = Debug|x64 - {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|x64.Build.0 = Debug|x64 - {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|Win32.ActiveCfg = Release|Win32 - {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|Win32.Build.0 = Release|Win32 - {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|x64.ActiveCfg = Release|x64 - {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|x64.Build.0 = Release|x64 - {A221819D-4263-42AA-B22A-C022924842A7}.Debug|Win32.ActiveCfg = Debug|Win32 - {A221819D-4263-42AA-B22A-C022924842A7}.Debug|Win32.Build.0 = Debug|Win32 - {A221819D-4263-42AA-B22A-C022924842A7}.Debug|x64.ActiveCfg = Debug|x64 - {A221819D-4263-42AA-B22A-C022924842A7}.Debug|x64.Build.0 = Debug|x64 - {A221819D-4263-42AA-B22A-C022924842A7}.Release|Win32.ActiveCfg = Release|Win32 - {A221819D-4263-42AA-B22A-C022924842A7}.Release|Win32.Build.0 = Release|Win32 - {A221819D-4263-42AA-B22A-C022924842A7}.Release|x64.ActiveCfg = Release|x64 - {A221819D-4263-42AA-B22A-C022924842A7}.Release|x64.Build.0 = Release|x64 - {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|Win32.ActiveCfg = Debug|Win32 - {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|Win32.Build.0 = Debug|Win32 - {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|x64.ActiveCfg = Debug|x64 - {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|x64.Build.0 = Debug|x64 - {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|Win32.ActiveCfg = Release|Win32 - {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|Win32.Build.0 = Release|Win32 - {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|x64.ActiveCfg = Release|x64 - {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|x64.Build.0 = Release|x64 - {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Debug|Win32.ActiveCfg = Debug|Win32 - {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Debug|Win32.Build.0 = Debug|Win32 - {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Debug|x64.ActiveCfg = Debug|x64 - {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Release|Win32.ActiveCfg = Release|Win32 - {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Release|x64.ActiveCfg = Release|x64 - {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|Win32.ActiveCfg = Debug|Win32 - {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|Win32.Build.0 = Debug|Win32 - {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|x64.ActiveCfg = Debug|x64 - {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|x64.Build.0 = Debug|x64 - {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|Win32.ActiveCfg = Release|Win32 - {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|Win32.Build.0 = Release|Win32 - {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|x64.ActiveCfg = Release|x64 - {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|x64.Build.0 = Release|x64 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|Win32.ActiveCfg = Debug|Win32 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|Win32.Build.0 = Debug|Win32 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|x64.ActiveCfg = Debug|x64 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|x64.Build.0 = Debug|x64 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|Win32.ActiveCfg = Release|Win32 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|Win32.Build.0 = Release|Win32 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|x64.ActiveCfg = Release|x64 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/RainmeterCPP.sln b/RainmeterCPP.sln new file mode 100644 index 00000000..85b09cee --- /dev/null +++ b/RainmeterCPP.sln @@ -0,0 +1,264 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Application", "Application\Application.vcxproj", "{D2A0903C-E760-4134-AE61-3D55BF8F760C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Language", "Language\Language.vcxproj", "{6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Library", "Library\Library.vcxproj", "{BE9D2400-7F1C-49D6-8498-5CE495491AD6}" + ProjectSection(ProjectDependencies) = postProject + {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A} = {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SkinInstaller", "SkinInstaller\SkinInstaller.vcxproj", "{6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginAdvancedCPU", "Plugins\PluginAdvancedCPU\PluginAdvancedCPU.vcxproj", "{EE8EC522-8430-4B46-86A3-D943D77F9E4B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginCoreTemp", "Plugins\PluginCoreTemp\PluginCoreTemp.vcxproj", "{F32FA418-8DF4-4E94-B92B-EBD502F5DC07}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginExample", "Plugins\PluginExample\PluginExample.vcxproj", "{761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginFolderInfo", "Plugins\PluginFolderInfo\PluginFolderInfo.vcxproj", "{A221819D-4263-42AA-B22A-C022924842A7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginiTunes", "Plugins\PluginiTunes\PluginiTunes.vcxproj", "{A2DD3CBE-B140-4892-A875-24107FA52518}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginMediaKey", "Plugins\PluginMediaKey\PluginMediaKey.vcxproj", "{EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginNowPlaying", "Plugins\PluginNowPlaying\PluginNowPlaying.vcxproj", "{C7FECFCD-E6C6-4F95-BB9A-E1762B043969}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginPerfMon", "Plugins\PluginPerfMon\PluginPerfMon.vcxproj", "{5344B52B-BAC3-479C-B41D-D465B8BDA1AD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginPing", "Plugins\PluginPing\PluginPing.vcxproj", "{C862B662-5CC6-4E79-B1B3-905E0B98D627}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginPower", "Plugins\PluginPower\PluginPower.vcxproj", "{C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginProcess", "Plugins\PluginProcess\PluginProcess.vcxproj", "{05203741-CD80-4060-8218-EC5D1120FE3E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginQuote", "Plugins\PluginQuote\PluginQuote.vcxproj", "{C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginRecycleManager", "Plugins\PluginRecycleManager\PluginRecycleManager.vcxproj", "{4F8C4C09-431C-45C4-830B-32006E783C3A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginResMon", "Plugins\PluginResMon\PluginResMon.vcxproj", "{17D3BD92-6F5D-438C-A89B-88F4CE06DB94}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginSpeedFan", "Plugins\PluginSpeedFan\PluginSpeedFan.vcxproj", "{D10AB316-0F7A-4551-BE4F-385E04CCF1E8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginSysInfo", "Plugins\PluginSysInfo\PluginSysInfo.vcxproj", "{6EBCA4DA-8CC7-42FE-8F45-878ABE165078}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginVirtualDesktops", "Plugins\PluginVirtualDesktops\PluginVirtualDesktops.vcxproj", "{4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginWebParser", "Plugins\PluginWebParser\PluginWebParser.vcxproj", "{8B820B9F-C154-417C-A090-42198F2AF496}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginWifiStatus", "Plugins\PluginWifiStatus\PluginWifiStatus.vcxproj", "{45A34285-56DD-4521-912B-3F884D36FA35}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginWin7Audio", "Plugins\PluginWin7Audio\PluginWin7Audio.vcxproj", "{6D032D6B-7656-4743-B454-3388E2921EB0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PluginWindowMessage", "Plugins\PluginWindowMessage\PluginWindowMessage.vcxproj", "{B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D2A0903C-E760-4134-AE61-3D55BF8F760C}.Debug|Win32.ActiveCfg = Debug|Win32 + {D2A0903C-E760-4134-AE61-3D55BF8F760C}.Debug|Win32.Build.0 = Debug|Win32 + {D2A0903C-E760-4134-AE61-3D55BF8F760C}.Debug|x64.ActiveCfg = Debug|x64 + {D2A0903C-E760-4134-AE61-3D55BF8F760C}.Debug|x64.Build.0 = Debug|x64 + {D2A0903C-E760-4134-AE61-3D55BF8F760C}.Release|Win32.ActiveCfg = Release|Win32 + {D2A0903C-E760-4134-AE61-3D55BF8F760C}.Release|Win32.Build.0 = Release|Win32 + {D2A0903C-E760-4134-AE61-3D55BF8F760C}.Release|x64.ActiveCfg = Release|x64 + {D2A0903C-E760-4134-AE61-3D55BF8F760C}.Release|x64.Build.0 = Release|x64 + {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Debug|Win32.ActiveCfg = Debug|Win32 + {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Debug|Win32.Build.0 = Debug|Win32 + {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Debug|x64.ActiveCfg = Debug|x64 + {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Debug|x64.Build.0 = Debug|x64 + {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Release|Win32.ActiveCfg = Release|Win32 + {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Release|Win32.Build.0 = Release|Win32 + {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Release|x64.ActiveCfg = Release|x64 + {6BE6F228-B741-4DA9-9FBC-E9F2A7BD483A}.Release|x64.Build.0 = Release|x64 + {BE9D2400-7F1C-49D6-8498-5CE495491AD6}.Debug|Win32.ActiveCfg = Debug|Win32 + {BE9D2400-7F1C-49D6-8498-5CE495491AD6}.Debug|Win32.Build.0 = Debug|Win32 + {BE9D2400-7F1C-49D6-8498-5CE495491AD6}.Debug|x64.ActiveCfg = Debug|x64 + {BE9D2400-7F1C-49D6-8498-5CE495491AD6}.Debug|x64.Build.0 = Debug|x64 + {BE9D2400-7F1C-49D6-8498-5CE495491AD6}.Release|Win32.ActiveCfg = Release|Win32 + {BE9D2400-7F1C-49D6-8498-5CE495491AD6}.Release|Win32.Build.0 = Release|Win32 + {BE9D2400-7F1C-49D6-8498-5CE495491AD6}.Release|x64.ActiveCfg = Release|x64 + {BE9D2400-7F1C-49D6-8498-5CE495491AD6}.Release|x64.Build.0 = Release|x64 + {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}.Debug|Win32.ActiveCfg = Debug|Win32 + {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}.Debug|Win32.Build.0 = Debug|Win32 + {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}.Debug|x64.ActiveCfg = Debug|x64 + {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}.Debug|x64.Build.0 = Debug|x64 + {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}.Release|Win32.ActiveCfg = Release|Win32 + {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}.Release|Win32.Build.0 = Release|Win32 + {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}.Release|x64.ActiveCfg = Release|x64 + {6F5D4C4A-C8C3-41DA-BF44-6D42B76464DA}.Release|x64.Build.0 = Release|x64 + {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Debug|Win32.ActiveCfg = Debug|Win32 + {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Debug|Win32.Build.0 = Debug|Win32 + {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Debug|x64.ActiveCfg = Debug|x64 + {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Debug|x64.Build.0 = Debug|x64 + {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Release|Win32.ActiveCfg = Release|Win32 + {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Release|Win32.Build.0 = Release|Win32 + {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Release|x64.ActiveCfg = Release|x64 + {EE8EC522-8430-4B46-86A3-D943D77F9E4B}.Release|x64.Build.0 = Release|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|Win32.ActiveCfg = Debug|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|Win32.Build.0 = Debug|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|x64.ActiveCfg = Debug|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Debug|x64.Build.0 = Debug|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|Win32.ActiveCfg = Release|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|Win32.Build.0 = Release|Win32 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|x64.ActiveCfg = Release|x64 + {F32FA418-8DF4-4E94-B92B-EBD502F5DC07}.Release|x64.Build.0 = Release|x64 + {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Debug|Win32.ActiveCfg = Debug|Win32 + {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Debug|Win32.Build.0 = Debug|Win32 + {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Debug|x64.ActiveCfg = Debug|x64 + {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Debug|x64.Build.0 = Debug|x64 + {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Release|Win32.ActiveCfg = Release|Win32 + {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Release|Win32.Build.0 = Release|Win32 + {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Release|x64.ActiveCfg = Release|x64 + {761BAD94-EA54-4DBD-9FF0-50FDAFECBE93}.Release|x64.Build.0 = Release|x64 + {A221819D-4263-42AA-B22A-C022924842A7}.Debug|Win32.ActiveCfg = Debug|Win32 + {A221819D-4263-42AA-B22A-C022924842A7}.Debug|Win32.Build.0 = Debug|Win32 + {A221819D-4263-42AA-B22A-C022924842A7}.Debug|x64.ActiveCfg = Debug|x64 + {A221819D-4263-42AA-B22A-C022924842A7}.Debug|x64.Build.0 = Debug|x64 + {A221819D-4263-42AA-B22A-C022924842A7}.Release|Win32.ActiveCfg = Release|Win32 + {A221819D-4263-42AA-B22A-C022924842A7}.Release|Win32.Build.0 = Release|Win32 + {A221819D-4263-42AA-B22A-C022924842A7}.Release|x64.ActiveCfg = Release|x64 + {A221819D-4263-42AA-B22A-C022924842A7}.Release|x64.Build.0 = Release|x64 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|Win32.ActiveCfg = Debug|Win32 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|Win32.Build.0 = Debug|Win32 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|x64.ActiveCfg = Debug|x64 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Debug|x64.Build.0 = Debug|x64 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|Win32.ActiveCfg = Release|Win32 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|Win32.Build.0 = Release|Win32 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|x64.ActiveCfg = Release|x64 + {A2DD3CBE-B140-4892-A875-24107FA52518}.Release|x64.Build.0 = Release|x64 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|Win32.ActiveCfg = Debug|Win32 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|Win32.Build.0 = Debug|Win32 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|x64.ActiveCfg = Debug|x64 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Debug|x64.Build.0 = Debug|x64 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|Win32.ActiveCfg = Release|Win32 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|Win32.Build.0 = Release|Win32 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|x64.ActiveCfg = Release|x64 + {EB48A04A-657E-41B8-B2F5-D47F8C30B2B4}.Release|x64.Build.0 = Release|x64 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Debug|Win32.ActiveCfg = Debug|Win32 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Debug|x64.ActiveCfg = Debug|x64 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Release|Win32.ActiveCfg = Release|Win32 + {C7FECFCD-E6C6-4F95-BB9A-E1762B043969}.Release|x64.ActiveCfg = Release|x64 + {5344B52B-BAC3-479C-B41D-D465B8BDA1AD}.Debug|Win32.ActiveCfg = Debug|Win32 + {5344B52B-BAC3-479C-B41D-D465B8BDA1AD}.Debug|Win32.Build.0 = Debug|Win32 + {5344B52B-BAC3-479C-B41D-D465B8BDA1AD}.Debug|x64.ActiveCfg = Debug|x64 + {5344B52B-BAC3-479C-B41D-D465B8BDA1AD}.Debug|x64.Build.0 = Debug|x64 + {5344B52B-BAC3-479C-B41D-D465B8BDA1AD}.Release|Win32.ActiveCfg = Release|Win32 + {5344B52B-BAC3-479C-B41D-D465B8BDA1AD}.Release|Win32.Build.0 = Release|Win32 + {5344B52B-BAC3-479C-B41D-D465B8BDA1AD}.Release|x64.ActiveCfg = Release|x64 + {5344B52B-BAC3-479C-B41D-D465B8BDA1AD}.Release|x64.Build.0 = Release|x64 + {C862B662-5CC6-4E79-B1B3-905E0B98D627}.Debug|Win32.ActiveCfg = Debug|Win32 + {C862B662-5CC6-4E79-B1B3-905E0B98D627}.Debug|Win32.Build.0 = Debug|Win32 + {C862B662-5CC6-4E79-B1B3-905E0B98D627}.Debug|x64.ActiveCfg = Debug|x64 + {C862B662-5CC6-4E79-B1B3-905E0B98D627}.Debug|x64.Build.0 = Debug|x64 + {C862B662-5CC6-4E79-B1B3-905E0B98D627}.Release|Win32.ActiveCfg = Release|Win32 + {C862B662-5CC6-4E79-B1B3-905E0B98D627}.Release|Win32.Build.0 = Release|Win32 + {C862B662-5CC6-4E79-B1B3-905E0B98D627}.Release|x64.ActiveCfg = Release|x64 + {C862B662-5CC6-4E79-B1B3-905E0B98D627}.Release|x64.Build.0 = Release|x64 + {C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}.Debug|Win32.ActiveCfg = Debug|Win32 + {C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}.Debug|Win32.Build.0 = Debug|Win32 + {C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}.Debug|x64.ActiveCfg = Debug|x64 + {C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}.Debug|x64.Build.0 = Debug|x64 + {C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}.Release|Win32.ActiveCfg = Release|Win32 + {C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}.Release|Win32.Build.0 = Release|Win32 + {C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}.Release|x64.ActiveCfg = Release|x64 + {C30E7EB6-9655-4AF4-98AE-D6E6B14631AF}.Release|x64.Build.0 = Release|x64 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|Win32.ActiveCfg = Debug|Win32 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|Win32.Build.0 = Debug|Win32 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|x64.ActiveCfg = Debug|x64 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Debug|x64.Build.0 = Debug|x64 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|Win32.ActiveCfg = Release|Win32 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|Win32.Build.0 = Release|Win32 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|x64.ActiveCfg = Release|x64 + {05203741-CD80-4060-8218-EC5D1120FE3E}.Release|x64.Build.0 = Release|x64 + {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Debug|Win32.ActiveCfg = Debug|Win32 + {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Debug|Win32.Build.0 = Debug|Win32 + {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Debug|x64.ActiveCfg = Debug|x64 + {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Debug|x64.Build.0 = Debug|x64 + {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Release|Win32.ActiveCfg = Release|Win32 + {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Release|Win32.Build.0 = Release|Win32 + {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Release|x64.ActiveCfg = Release|x64 + {C029E0CF-F203-41D0-9608-A3EA2CF0ED1F}.Release|x64.Build.0 = Release|x64 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|Win32.ActiveCfg = Debug|Win32 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|Win32.Build.0 = Debug|Win32 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|x64.ActiveCfg = Debug|x64 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Debug|x64.Build.0 = Debug|x64 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|Win32.ActiveCfg = Release|Win32 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|Win32.Build.0 = Release|Win32 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|x64.ActiveCfg = Release|x64 + {4F8C4C09-431C-45C4-830B-32006E783C3A}.Release|x64.Build.0 = Release|x64 + {17D3BD92-6F5D-438C-A89B-88F4CE06DB94}.Debug|Win32.ActiveCfg = Debug|Win32 + {17D3BD92-6F5D-438C-A89B-88F4CE06DB94}.Debug|Win32.Build.0 = Debug|Win32 + {17D3BD92-6F5D-438C-A89B-88F4CE06DB94}.Debug|x64.ActiveCfg = Debug|x64 + {17D3BD92-6F5D-438C-A89B-88F4CE06DB94}.Debug|x64.Build.0 = Debug|x64 + {17D3BD92-6F5D-438C-A89B-88F4CE06DB94}.Release|Win32.ActiveCfg = Release|Win32 + {17D3BD92-6F5D-438C-A89B-88F4CE06DB94}.Release|Win32.Build.0 = Release|Win32 + {17D3BD92-6F5D-438C-A89B-88F4CE06DB94}.Release|x64.ActiveCfg = Release|x64 + {17D3BD92-6F5D-438C-A89B-88F4CE06DB94}.Release|x64.Build.0 = Release|x64 + {D10AB316-0F7A-4551-BE4F-385E04CCF1E8}.Debug|Win32.ActiveCfg = Debug|Win32 + {D10AB316-0F7A-4551-BE4F-385E04CCF1E8}.Debug|Win32.Build.0 = Debug|Win32 + {D10AB316-0F7A-4551-BE4F-385E04CCF1E8}.Debug|x64.ActiveCfg = Debug|x64 + {D10AB316-0F7A-4551-BE4F-385E04CCF1E8}.Debug|x64.Build.0 = Debug|x64 + {D10AB316-0F7A-4551-BE4F-385E04CCF1E8}.Release|Win32.ActiveCfg = Release|Win32 + {D10AB316-0F7A-4551-BE4F-385E04CCF1E8}.Release|Win32.Build.0 = Release|Win32 + {D10AB316-0F7A-4551-BE4F-385E04CCF1E8}.Release|x64.ActiveCfg = Release|x64 + {D10AB316-0F7A-4551-BE4F-385E04CCF1E8}.Release|x64.Build.0 = Release|x64 + {6EBCA4DA-8CC7-42FE-8F45-878ABE165078}.Debug|Win32.ActiveCfg = Debug|Win32 + {6EBCA4DA-8CC7-42FE-8F45-878ABE165078}.Debug|Win32.Build.0 = Debug|Win32 + {6EBCA4DA-8CC7-42FE-8F45-878ABE165078}.Debug|x64.ActiveCfg = Debug|x64 + {6EBCA4DA-8CC7-42FE-8F45-878ABE165078}.Debug|x64.Build.0 = Debug|x64 + {6EBCA4DA-8CC7-42FE-8F45-878ABE165078}.Release|Win32.ActiveCfg = Release|Win32 + {6EBCA4DA-8CC7-42FE-8F45-878ABE165078}.Release|Win32.Build.0 = Release|Win32 + {6EBCA4DA-8CC7-42FE-8F45-878ABE165078}.Release|x64.ActiveCfg = Release|x64 + {6EBCA4DA-8CC7-42FE-8F45-878ABE165078}.Release|x64.Build.0 = Release|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|Win32.ActiveCfg = Debug|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|Win32.Build.0 = Debug|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|x64.ActiveCfg = Debug|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Debug|x64.Build.0 = Debug|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|Win32.ActiveCfg = Release|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|Win32.Build.0 = Release|Win32 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|x64.ActiveCfg = Release|x64 + {4640AB3A-5A8B-2DA0-980C-A70BCAB3A7F1}.Release|x64.Build.0 = Release|x64 + {8B820B9F-C154-417C-A090-42198F2AF496}.Debug|Win32.ActiveCfg = Debug|Win32 + {8B820B9F-C154-417C-A090-42198F2AF496}.Debug|Win32.Build.0 = Debug|Win32 + {8B820B9F-C154-417C-A090-42198F2AF496}.Debug|x64.ActiveCfg = Debug|x64 + {8B820B9F-C154-417C-A090-42198F2AF496}.Debug|x64.Build.0 = Debug|x64 + {8B820B9F-C154-417C-A090-42198F2AF496}.Release|Win32.ActiveCfg = Release|Win32 + {8B820B9F-C154-417C-A090-42198F2AF496}.Release|Win32.Build.0 = Release|Win32 + {8B820B9F-C154-417C-A090-42198F2AF496}.Release|x64.ActiveCfg = Release|x64 + {8B820B9F-C154-417C-A090-42198F2AF496}.Release|x64.Build.0 = Release|x64 + {45A34285-56DD-4521-912B-3F884D36FA35}.Debug|Win32.ActiveCfg = Debug|Win32 + {45A34285-56DD-4521-912B-3F884D36FA35}.Debug|Win32.Build.0 = Debug|Win32 + {45A34285-56DD-4521-912B-3F884D36FA35}.Debug|x64.ActiveCfg = Debug|x64 + {45A34285-56DD-4521-912B-3F884D36FA35}.Debug|x64.Build.0 = Debug|x64 + {45A34285-56DD-4521-912B-3F884D36FA35}.Release|Win32.ActiveCfg = Release|Win32 + {45A34285-56DD-4521-912B-3F884D36FA35}.Release|Win32.Build.0 = Release|Win32 + {45A34285-56DD-4521-912B-3F884D36FA35}.Release|x64.ActiveCfg = Release|x64 + {45A34285-56DD-4521-912B-3F884D36FA35}.Release|x64.Build.0 = Release|x64 + {6D032D6B-7656-4743-B454-3388E2921EB0}.Debug|Win32.ActiveCfg = Debug|Win32 + {6D032D6B-7656-4743-B454-3388E2921EB0}.Debug|Win32.Build.0 = Debug|Win32 + {6D032D6B-7656-4743-B454-3388E2921EB0}.Debug|x64.ActiveCfg = Debug|x64 + {6D032D6B-7656-4743-B454-3388E2921EB0}.Debug|x64.Build.0 = Debug|x64 + {6D032D6B-7656-4743-B454-3388E2921EB0}.Release|Win32.ActiveCfg = Release|Win32 + {6D032D6B-7656-4743-B454-3388E2921EB0}.Release|Win32.Build.0 = Release|Win32 + {6D032D6B-7656-4743-B454-3388E2921EB0}.Release|x64.ActiveCfg = Release|x64 + {6D032D6B-7656-4743-B454-3388E2921EB0}.Release|x64.Build.0 = Release|x64 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|Win32.ActiveCfg = Debug|Win32 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|Win32.Build.0 = Debug|Win32 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|x64.ActiveCfg = Debug|x64 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Debug|x64.Build.0 = Debug|x64 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|Win32.ActiveCfg = Release|Win32 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|Win32.Build.0 = Release|Win32 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|x64.ActiveCfg = Release|x64 + {B9184DBA-C6B7-44FE-8BBD-0852DB22D2E4}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/RainmeterCS.sln b/RainmeterCS.sln new file mode 100644 index 00000000..f16f3604 --- /dev/null +++ b/RainmeterCS.sln @@ -0,0 +1,55 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C# Express 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DllExporter", "Plugins\API\DllExporter\DllExporter.csproj", "{49D56CA5-54AB-45C9-A245-EAE588FCBFE1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginExampleCS", "Plugins\PluginExampleCS\PluginExampleCS.csproj", "{D31F73ED-3978-44FA-B599-49584BA30D3A}" + ProjectSection(ProjectDependencies) = postProject + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1} = {49D56CA5-54AB-45C9-A245-EAE588FCBFE1} + EndProjectSection +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginInputText", "Plugins\PluginInputText\PluginInputText.csproj", "{2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}" + ProjectSection(ProjectDependencies) = postProject + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1} = {49D56CA5-54AB-45C9-A245-EAE588FCBFE1} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Debug|x64.ActiveCfg = Debug|x64 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Debug|x64.Build.0 = Debug|x64 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Debug|x86.ActiveCfg = Debug|x86 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Debug|x86.Build.0 = Debug|x86 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Release|x64.ActiveCfg = Release|x64 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Release|x64.Build.0 = Release|x64 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Release|x86.ActiveCfg = Release|x86 + {49D56CA5-54AB-45C9-A245-EAE588FCBFE1}.Release|x86.Build.0 = Release|x86 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Debug|x64.ActiveCfg = Debug|x64 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Debug|x64.Build.0 = Debug|x64 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Debug|x86.ActiveCfg = Debug|x86 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Debug|x86.Build.0 = Debug|x86 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Release|x64.ActiveCfg = Release|x64 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Release|x64.Build.0 = Release|x64 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Release|x86.ActiveCfg = Release|x86 + {D31F73ED-3978-44FA-B599-49584BA30D3A}.Release|x86.Build.0 = Release|x86 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Debug|x64.ActiveCfg = Debug|x64 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Debug|x64.Build.0 = Debug|x64 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Debug|x86.ActiveCfg = Debug|x86 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Debug|x86.Build.0 = Debug|x86 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Release|x64.ActiveCfg = Release|x64 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Release|x64.Build.0 = Release|x64 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Release|x86.ActiveCfg = Release|x86 + {2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(SpecExplorer.ActivityCompletionStatus) = preSolution + SpecExplorer.ActivityCompletionStatus = + EndGlobalSection +EndGlobal diff --git a/Version.cs b/Version.cs new file mode 100644 index 00000000..8c00a223 --- /dev/null +++ b/Version.cs @@ -0,0 +1,11 @@ +namespace Rainmeter +{ + public class Version + { +#if X64 + public const string Informational = "2.3.0.1091 (64-bit)"; +#else + public const string Informational = "2.3.0.1091 (32-bit)"; +#endif + } +} diff --git a/Version.h b/Version.h index e0a69502..d31a6130 100644 --- a/Version.h +++ b/Version.h @@ -1,14 +1,13 @@ -#pragma once -#define MAKE_VER(major, minor1, minor2) major * 1000000 + minor1 * 1000 + minor2 - -#define FILEVER 2,2,0,960 -#define PRODUCTVER 2,2,0,960 -#define STRFILEVER "2.2.0.960" -#define STRPRODUCTVER "2.2.0.960" - -#define REVISION L"960" -#define APPVERSION L"2.2.0" -#define RAINMETER_VERSION MAKE_VER(2, 2, 0) - -const int revision_number = 960; -const bool revision_beta = true; +#pragma once +#define MAKE_VER(major, minor1, minor2) major * 1000000 + minor1 * 1000 + minor2 + +#define FILEVER 2,3,0,1091 +#define PRODUCTVER 2,3,0,1091 +#define STRFILEVER "2.3.0.1091" +#define STRPRODUCTVER "2.3.0.1091" + +#define APPVERSION L"2.3.0" +#define RAINMETER_VERSION MAKE_VER(2, 3, 0) + +const int revision_number = 1091; +const bool revision_beta = true;