Reverted trunk to r1085.

This commit is contained in:
Birunthan Mohanathas 2011-12-30 17:18:34 +00:00
parent 9856b5138a
commit 71b8d6395d
14 changed files with 454 additions and 756 deletions

View File

@ -1,241 +0,0 @@
/*
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"
extern CRainmeter* Rainmeter;
static std::wstring g_Buffer;
BOOL LSLog(int nLevel, LPCWSTR unused, LPCWSTR pszMessage)
{
// Ignore LOG_DEBUG messages from plugins unless in debug mode
if (nLevel != LOG_DEBUG || Rainmeter->GetDebug())
{
Log(nLevel, pszMessage);
}
return TRUE;
}
LPCWSTR RmReadString(void* rm, LPCWSTR option, LPCWSTR defValue, BOOL replaceMeasures)
{
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)
{
CMeasurePlugin* measure = (CMeasurePlugin*)rm;
CConfigParser& parser = measure->GetMeterWindow()->GetParser();
return parser.ReadFormula(measure->GetName(), option, defValue);
}
LPCWSTR RmPathToAbsolute(void* rm, LPCWSTR 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);
}
// Deprecated!
LPCWSTR ReadConfigString(LPCWSTR section, LPCWSTR option, LPCWSTR defValue)
{
// NULL checking
if (section == NULL) section = L"";
if (option == NULL) option = L"";
if (defValue == NULL) defValue = L"";
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 (Rainmeter)
{
if (_sCommand == NULL || *_sCommand == L'\0')
{
return L"noop";
}
if (_sData == NULL) _sData = L"";
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<std::wstring> 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<std::wstring> 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<std::wstring> 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";
}
return L"error:no rainmeter!";
}

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2011 Kimmo Pekkola, Birunthan Mohanathas Copyright (C) 2004 Kimmo Pekkola
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
@ -20,94 +20,28 @@
#define __EXPORT_H__ #define __EXPORT_H__
#ifdef LIBRARY_EXPORTS #ifdef LIBRARY_EXPORTS
#define DECLSPEC_LIBRARY __declspec(dllexport) #define EXPORT_PLUGIN __declspec(dllexport)
#else #else
#define DECLSPEC_LIBRARY __declspec(dllimport) #define EXPORT_PLUGIN __declspec(dllimport)
#endif // LIBRARY_EXPORTS
#ifdef __cplusplus
#define LIBRARY_EXPORT extern "C" DECLSPEC_LIBRARY
#define PLUGIN_EXPORT extern "C" __declspec(dllexport)
#else
#define LIBRARY_EXPORT DECLSPEC_LIBRARY
#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 BOOL LSLog(int level, LPCWSTR unused, LPCWSTR message);
LIBRARY_EXPORT void* RmGet(void* rm, int type);
enum RMGTYPE
{
RMG_MEASURENAME = 0,
RMG_SKIN = 1,
RMG_SETTINGSFILE = 2
};
/* 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);
}
__inline int RmReadInt(void* rm, LPCWSTR option, int defValue)
{
LPCWSTR value = RmReadString(rm, option, L"", TRUE);
return (*value) ? _wtoi(value) : defValue;
}
__inline LPCWSTR RmGetMeasureName(void* rm)
{
return (LPCWSTR)RmGet(rm, RMG_MEASURENAME);
}
__inline LPCWSTR RmGetSettingsFile(void* rm)
{
return (LPCWSTR)RmGet(rm, 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 #endif
// log level constants
#define LOG_ERROR 1
#define LOG_WARNING 2
#define LOG_NOTICE 3
#define LOG_DEBUG 4
#ifdef __cplusplus
extern "C"
{
#endif
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);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -657,17 +657,6 @@
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization> <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
</ClCompile> </ClCompile>
<ClCompile Include="Export.cpp">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Use</PrecompiledHeader>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Use</PrecompiledHeader>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MaxSpeed</Optimization>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Use</PrecompiledHeader>
</ClCompile>
<ClCompile Include="StdAfx.cpp"> <ClCompile Include="StdAfx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
@ -848,6 +837,7 @@
<ClInclude Include="DialogAbout.h" /> <ClInclude Include="DialogAbout.h" />
<ClInclude Include="DisableThreadLibraryCalls.h" /> <ClInclude Include="DisableThreadLibraryCalls.h" />
<ClInclude Include="Error.h" /> <ClInclude Include="Error.h" />
<ClInclude Include="Export.h" />
<ClInclude Include="Group.h" /> <ClInclude Include="Group.h" />
<ClInclude Include="Litestep.h" /> <ClInclude Include="Litestep.h" />
<ClInclude Include="DialogManage.h" /> <ClInclude Include="DialogManage.h" />
@ -883,7 +873,6 @@
<ClInclude Include="pcre-8.10\pcre_internal.h" /> <ClInclude Include="pcre-8.10\pcre_internal.h" />
<ClInclude Include="pcre-8.10\ucp.h" /> <ClInclude Include="pcre-8.10\ucp.h" />
<ClInclude Include="Rainmeter.h" /> <ClInclude Include="Rainmeter.h" />
<ClInclude Include="Export.h" />
<ClInclude Include="RainmeterQuery.h" /> <ClInclude Include="RainmeterQuery.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="StdAfx.h" /> <ClInclude Include="StdAfx.h" />

View File

@ -351,9 +351,6 @@
<ClCompile Include="DialogManage.cpp"> <ClCompile Include="DialogManage.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Export.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="ConfigParser.h"> <ClInclude Include="ConfigParser.h">
@ -365,6 +362,9 @@
<ClInclude Include="Error.h"> <ClInclude Include="Error.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Export.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Group.h"> <ClInclude Include="Group.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@ -593,9 +593,6 @@
<ClInclude Include="DialogManage.h"> <ClInclude Include="DialogManage.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Export.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="Library.rc"> <ResourceCompile Include="Library.rc">

View File

@ -23,14 +23,7 @@
#include <comdef.h> #include <comdef.h>
#include <string> #include <string>
#include "Error.h" #include "Error.h"
#include "Export.h"
enum LOGLEVEL
{
LOG_ERROR = 1,
LOG_WARNING = 2,
LOG_NOTICE = 3,
LOG_DEBUG = 4
};
void InitalizeLitestep(); void InitalizeLitestep();
void FinalizeLitestep(); void FinalizeLitestep();
@ -45,7 +38,7 @@ std::string ConvertToUTF8(LPCWSTR str);
std::wstring ConvertUTF8ToWide(LPCSTR str); std::wstring ConvertUTF8ToWide(LPCSTR str);
void Log(int nLevel, const WCHAR* message); 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 LogError(CError& error);
void RunCommand(HWND Owner, LPCTSTR szCommand, int nShowCmd, bool asAdmin = false); void RunCommand(HWND Owner, LPCTSTR szCommand, int nShowCmd, bool asAdmin = false);

View File

@ -19,7 +19,6 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "MeasurePlugin.h" #include "MeasurePlugin.h"
#include "Rainmeter.h" #include "Rainmeter.h"
#include "Export.h"
#include "System.h" #include "System.h"
#include "Error.h" #include "Error.h"
@ -33,11 +32,13 @@ extern CRainmeter* Rainmeter;
*/ */
CMeasurePlugin::CMeasurePlugin(CMeterWindow* meterWindow, const WCHAR* name) : CMeasure(meterWindow, name), CMeasurePlugin::CMeasurePlugin(CMeterWindow* meterWindow, const WCHAR* name) : CMeasure(meterWindow, name),
m_Plugin(), m_Plugin(),
m_ReloadFunc(),
m_ID(), m_ID(),
m_UpdateFunc(), InitializeFunc(),
m_GetStringFunc(), UpdateFunc(),
m_ExecuteBangFunc() UpdateFunc2(),
FinalizeFunc(),
GetStringFunc(),
ExecuteBangFunc()
{ {
m_MaxValue = 0.0; m_MaxValue = 0.0;
} }
@ -52,16 +53,7 @@ CMeasurePlugin::~CMeasurePlugin()
{ {
if (m_Plugin) if (m_Plugin)
{ {
FARPROC finalizeFunc = GetProcAddress(m_Plugin, "Finalize"); if (FinalizeFunc) FinalizeFunc(m_Plugin, m_ID);
if (IsNewApi())
{
((NEWFINALIZE)finalizeFunc)(m_PluginData);
}
else if (finalizeFunc)
{
((FINALIZE)finalizeFunc)(m_Plugin, m_ID);
}
FreeLibrary(m_Plugin); FreeLibrary(m_Plugin);
} }
} }
@ -76,20 +68,15 @@ bool CMeasurePlugin::Update()
{ {
if (!CMeasure::PreUpdate()) return false; if (!CMeasure::PreUpdate()) return false;
if (IsNewApi()) if (UpdateFunc)
{ {
m_Value = ((NEWUPDATE)m_UpdateFunc)(m_PluginData); // Update the plugin
m_Value = UpdateFunc(m_ID);
} }
else if (m_UpdateFunc) else if (UpdateFunc2)
{ {
if (m_Update2) // Update the plugin
{ m_Value = UpdateFunc2(m_ID);
m_Value = ((UPDATE2)m_UpdateFunc)(m_ID);
}
else
{
m_Value = ((UPDATE)m_UpdateFunc)(m_ID);
}
} }
// Reset to default // Reset to default
@ -106,17 +93,13 @@ bool CMeasurePlugin::Update()
*/ */
void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section) void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section)
{ {
static UINT id = 0; static UINT id = 1;
CMeasure::ReadConfig(parser, section); CMeasure::ReadConfig(parser, section);
if (m_Initialized) if (m_Initialized)
{ {
if (IsNewApi()) // DynamicVariables doesn't work with plugins, so stop here.
{
((NEWRELOAD)m_ReloadFunc)(m_PluginData, this, &m_MaxValue);
}
// DynamicVariables doesn't work with old plugins
return; return;
} }
@ -135,9 +118,16 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section)
} }
m_PluginName.insert(0, Rainmeter->GetPluginPath()); m_PluginName.insert(0, Rainmeter->GetPluginPath());
m_Plugin = CSystem::RmLoadLibrary(m_PluginName.c_str(), NULL); DWORD err = 0;
m_Plugin = CSystem::RmLoadLibrary(m_PluginName.c_str(), &err);
if (m_Plugin == 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 // Try to load from Rainmeter's folder
pos = m_PluginName.rfind(L'\\'); pos = m_PluginName.rfind(L'\\');
if (pos != std::wstring::npos) if (pos != std::wstring::npos)
@ -145,7 +135,16 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section)
std::wstring pluginName = Rainmeter->GetPath(); std::wstring pluginName = Rainmeter->GetPath();
pluginName.append(m_PluginName, pos + 1, m_PluginName.length() - (pos + 1)); pluginName.append(m_PluginName, pos + 1, m_PluginName.length() - (pos + 1));
m_Plugin = CSystem::RmLoadLibrary(pluginName.c_str(), NULL); 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);
}
}
} }
if (m_Plugin == NULL) if (m_Plugin == NULL)
@ -156,50 +155,48 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section)
} }
} }
FARPROC initializeFunc = GetProcAddress(m_Plugin, "Initialize"); InitializeFunc = (INITIALIZE)GetProcAddress(m_Plugin, "Initialize");
m_ReloadFunc = GetProcAddress(m_Plugin, "Reload"); FinalizeFunc = (FINALIZE)GetProcAddress(m_Plugin, "Finalize");
m_UpdateFunc = GetProcAddress(m_Plugin, "Update"); UpdateFunc = (UPDATE)GetProcAddress(m_Plugin, "Update");
m_GetStringFunc = GetProcAddress(m_Plugin, "GetString"); UpdateFunc2 = (UPDATE2)GetProcAddress(m_Plugin, "Update2");
m_ExecuteBangFunc = GetProcAddress(m_Plugin, "ExecuteBang"); GetStringFunc = (GETSTRING)GetProcAddress(m_Plugin, "GetString");
ExecuteBangFunc = (EXECUTEBANG)GetProcAddress(m_Plugin, "ExecuteBang");
// Remove current directory from DLL search path if (UpdateFunc == NULL && UpdateFunc2 == NULL && GetStringFunc == NULL)
SetDllDirectory(L"");
if (IsNewApi())
{ {
((NEWINITIALIZE)initializeFunc)(&m_PluginData); FreeLibrary(m_Plugin);
((NEWRELOAD)m_ReloadFunc)(m_PluginData, this, &m_MaxValue);
std::wstring error = L"Plugin: \"" + m_PluginName;
error += L"\" doesn't export Update() or GetString()";
throw CError(error);
} }
else
// Initialize the plugin
m_ID = id++;
if (InitializeFunc)
{ {
m_ID = id; // Remove current directory from DLL search path
SetDllDirectory(L"");
if (!m_UpdateFunc) double maxValue;
{ maxValue = InitializeFunc(m_Plugin, parser.GetFilename().c_str(), section, m_ID);
m_UpdateFunc = GetProcAddress(m_Plugin, "Update2");
m_Update2 = true;
}
double maxValue = ((INITIALIZE)initializeFunc)(m_Plugin, parser.GetFilename().c_str(), section, m_ID); // Reset to default
SetDllDirectory(L"");
CSystem::ResetWorkingDirectory();
const std::wstring& szMaxValue = parser.ReadString(section, L"MaxValue", L""); const std::wstring& szMaxValue = parser.ReadString(section, L"MaxValue", L"");
if (szMaxValue.empty()) if (szMaxValue.empty())
{ {
m_MaxValue = maxValue; m_MaxValue = maxValue;
} }
if (m_MaxValue == 0)
{
m_MaxValue = 1;
m_LogMaxValue = true;
}
} }
// Reset to default if (m_MaxValue == 0)
SetDllDirectory(L""); {
CSystem::ResetWorkingDirectory(); m_MaxValue = 1;
m_LogMaxValue = true;
++id; }
} }
/* /*
@ -210,18 +207,9 @@ void CMeasurePlugin::ReadConfig(CConfigParser& parser, const WCHAR* section)
*/ */
const WCHAR* CMeasurePlugin::GetStringValue(AUTOSCALE autoScale, double scale, int decimals, bool percentual) const WCHAR* CMeasurePlugin::GetStringValue(AUTOSCALE autoScale, double scale, int decimals, bool percentual)
{ {
if (m_GetStringFunc) if (GetStringFunc)
{ {
const WCHAR* ret; const WCHAR* ret = GetStringFunc(m_ID, 0);
if (IsNewApi())
{
ret = ((NEWGETSTRING)m_GetStringFunc)(m_PluginData);
}
else
{
ret = ((GETSTRING)m_GetStringFunc)(m_ID, 0);
}
if (ret) return CheckSubstitute(ret); if (ret) return CheckSubstitute(ret);
} }
@ -236,19 +224,12 @@ const WCHAR* CMeasurePlugin::GetStringValue(AUTOSCALE autoScale, double scale, i
*/ */
void CMeasurePlugin::ExecuteBang(const WCHAR* args) void CMeasurePlugin::ExecuteBang(const WCHAR* args)
{ {
if (m_ExecuteBangFunc) if (ExecuteBangFunc)
{ {
if (IsNewApi()) ExecuteBangFunc(args, m_ID);
{
((NEWEXECUTEBANG)m_ExecuteBangFunc)(m_PluginData, args);
}
else
{
((EXECUTEBANG)m_ExecuteBangFunc)(args, m_ID);
}
} }
else else
{ {
CMeasure::ExecuteBang(args); CMeasure::ExecuteBang(args);
} }
} }

View File

@ -21,20 +21,13 @@
#include "Measure.h" #include "Measure.h"
typedef UINT (*INITIALIZE)(HMODULE, LPCTSTR, LPCTSTR, UINT); typedef UINT (*INITIALIZE)(HMODULE, LPCTSTR, LPCTSTR, UINT);
typedef VOID (*FINALIZE)(HMODULE, UINT); typedef VOID (*FINALIZE)(HMODULE, UINT);
typedef UINT (*UPDATE)(UINT); typedef UINT (*UPDATE)(UINT);
typedef double (*UPDATE2)(UINT); typedef double (*UPDATE2)(UINT);
typedef LPCTSTR (*GETSTRING)(UINT, UINT); typedef LPCTSTR (*GETSTRING)(UINT, UINT);
typedef void (*EXECUTEBANG)(LPCTSTR, 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 class CMeasurePlugin : public CMeasure
{ {
public: public:
@ -49,30 +42,16 @@ protected:
virtual void ReadConfig(CConfigParser& parser, const WCHAR* section); virtual void ReadConfig(CConfigParser& parser, const WCHAR* section);
private: private:
bool IsNewApi() { return m_ReloadFunc != NULL; }
std::wstring m_PluginName; std::wstring m_PluginName;
HMODULE m_Plugin; HMODULE m_Plugin;
UINT m_ID;
void* m_ReloadFunc; INITIALIZE InitializeFunc;
FINALIZE FinalizeFunc;
union UPDATE UpdateFunc;
{ UPDATE2 UpdateFunc2;
struct GETSTRING GetStringFunc;
{ EXECUTEBANG ExecuteBangFunc;
UINT m_ID;
bool m_Update2;
};
struct
{
void* m_PluginData;
};
};
void* m_UpdateFunc;
void* m_GetStringFunc;
void* m_ExecuteBangFunc;
}; };
#endif #endif

View File

@ -2110,6 +2110,8 @@ bool CMeterWindow::ReadSkin()
MessageBox(m_Window, text.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION); 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}; static const RECT defMargins = {0};
m_BackgroundMargins = m_Parser.ReadRECT(L"Rainmeter", L"BackgroundMargins", defMargins); m_BackgroundMargins = m_Parser.ReadRECT(L"Rainmeter", L"BackgroundMargins", defMargins);
m_DragMargins = m_Parser.ReadRECT(L"Rainmeter", L"DragMargins", defMargins); m_DragMargins = m_Parser.ReadRECT(L"Rainmeter", L"DragMargins", defMargins);

View File

@ -200,6 +200,7 @@ public:
CConfigParser& GetParser() { return m_Parser; } CConfigParser& GetParser() { return m_Parser; }
const std::wstring& GetSkinAuthor() { return m_Author; }
const std::wstring& GetSkinName() { return m_SkinName; } const std::wstring& GetSkinName() { return m_SkinName; }
const std::wstring& GetSkinIniFile() { return m_SkinIniFile; } const std::wstring& GetSkinIniFile() { return m_SkinIniFile; }
std::wstring GetSkinRootPath(); std::wstring GetSkinRootPath();
@ -374,6 +375,7 @@ private:
bool m_MouseOver; bool m_MouseOver;
std::wstring m_Author; // Skin's author
std::wstring m_ConfigGroup; std::wstring m_ConfigGroup;
std::wstring m_BackgroundName; // Name of the background image std::wstring m_BackgroundName; // Name of the background image
RECT m_BackgroundMargins; RECT m_BackgroundMargins;

View File

@ -1,77 +0,0 @@
/*
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 <windows.h>
class CRawString
{
public:
CRawString() :
m_String()
{
}
CRawString(const WCHAR* str) :
m_String(_wcsdup(str))
{
}
~CRawString()
{
if (m_String) free(m_String);
}
CRawString& operator=(const WCHAR* rhs)
{
if (m_String) free(m_String);
m_String = _wcsdup(rhs);
return *this;
}
CRawString& operator=(const CRawString& rhs)
{
if (&rhs != this)
{
if (m_String) free(m_String);
m_String = _wcsdup(rhs.m_String);
}
return *this;
}
const WCHAR* c_str() const
{
return m_String;
}
bool empty() const
{
return !(*m_String);
}
private:
CRawString(const CRawString& p)
{
}
WCHAR* m_String;
};
#endif

View File

@ -120,8 +120,6 @@
<ImportLibrary>.\x32/Debug/PowerPlugin.lib</ImportLibrary> <ImportLibrary>.\x32/Debug/PowerPlugin.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
<AdditionalLibraryDirectories>..\..\Library\x32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\..\Library\x32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies)</AdditionalDependencies>
<DelayLoadDLLs>PowrProf.dll</DelayLoadDLLs>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -162,8 +160,6 @@
<ImportLibrary>.\x64/Debug/PowerPlugin.lib</ImportLibrary> <ImportLibrary>.\x64/Debug/PowerPlugin.lib</ImportLibrary>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
<AdditionalLibraryDirectories>..\..\Library\x64\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\..\Library\x64\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies)</AdditionalDependencies>
<DelayLoadDLLs>PowrProf.dll</DelayLoadDLLs>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -199,7 +195,7 @@
<Culture>0x0409</Culture> <Culture>0x0409</Culture>
</ResourceCompile> </ResourceCompile>
<Link> <Link>
<AdditionalDependencies>Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Rainmeter.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../TestBench/x32/Release/Plugins/PowerPlugin.dll</OutputFile> <OutputFile>../../TestBench/x32/Release/Plugins/PowerPlugin.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\Library\x32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\..\Library\x32\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -210,7 +206,6 @@
<MergeSections>.rdata=.text</MergeSections> <MergeSections>.rdata=.text</MergeSections>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<DelayLoadDLLs>PowrProf.dll</DelayLoadDLLs>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -246,7 +241,7 @@
</ResourceCompile> </ResourceCompile>
<Link> <Link>
<AdditionalOptions>/LTCG %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/LTCG %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>Rainmeter.lib;PowrProf.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>Rainmeter.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../TestBench/x64/Release/Plugins/PowerPlugin.dll</OutputFile> <OutputFile>../../TestBench/x64/Release/Plugins/PowerPlugin.dll</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner> <SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>..\..\Library\x64\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\..\Library\x64\$(Configuration);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -256,7 +251,6 @@
<MergeSections>.rdata=.text</MergeSections> <MergeSections>.rdata=.text</MergeSections>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<DelayLoadDLLs>PowrProf.dll</DelayLoadDLLs>
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>

View File

@ -17,12 +17,13 @@
*/ */
#include <windows.h> #include <windows.h>
#include <Powrprof.h> #include <math.h>
#include <map>
#include <string>
#include <time.h> #include <time.h>
#include <errno.h> #include <Powrprof.h>
#include <crtdbg.h>
#include "../../Library/RawString.h"
#include "../../Library/Export.h" // Rainmeter's exported functions #include "../../Library/Export.h" // Rainmeter's exported functions
#include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point #include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point
typedef struct _PROCESSOR_POWER_INFORMATION typedef struct _PROCESSOR_POWER_INFORMATION
@ -35,7 +36,20 @@ typedef struct _PROCESSOR_POWER_INFORMATION
ULONG CurrentIdleState; ULONG CurrentIdleState;
} PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION; } PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
enum MeasureType 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
{ {
POWER_UNKNOWN, POWER_UNKNOWN,
POWER_ACLINE, POWER_ACLINE,
@ -47,187 +61,272 @@ enum MeasureType
POWER_HZ POWER_HZ
}; };
struct MeasureData std::map<UINT, POWER_STATE> g_States;
{ std::map<UINT, std::wstring> g_Formats;
MeasureType type; HINSTANCE hDLL = NULL;
CRawString format; int g_Instances, g_NumOfProcessors = 0;
FPCALLNTPOWERINFORMATION fpCallNtPowerInformation = NULL;
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) void NullCRTInvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
{ {
// Do nothing. // Do nothing.
} }
PLUGIN_EXPORT void Initialize(void** data) /*
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)
{ {
MeasureData* measure = new MeasureData; g_Instances++;
*data = measure; if (hDLL == NULL)
if (!g_NumOfProcessors)
{ {
SYSTEM_INFO si; hDLL = LoadLibrary(L"powrprof.dll");
GetSystemInfo(&si); if (hDLL)
g_NumOfProcessors = (UINT)si.dwNumberOfProcessors;
}
}
PLUGIN_EXPORT void Reload(void* data, void* rm, double* maxValue)
{
MeasureData* measure = (MeasureData*)data;
LPCWSTR value = RmReadString(rm, L"PowerState", L"");
if (_wcsicmp(L"ACLINE", value) == 0)
{
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))
{ {
*maxValue = sps.BatteryFullLifeTime; fpCallNtPowerInformation = (FPCALLNTPOWERINFORMATION)GetProcAddress(hDLL, "CallNtPowerInformation");
} }
} }
else if (_wcsicmp(L"MHZ", value) == 0)
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)
{ {
measure->type = POWER_MHZ; 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;
} }
else if (_wcsicmp(L"HZ", value) == 0)
switch(powerState)
{ {
measure->type = POWER_HZ; case POWER_ACLINE:
} return 1;
else if (_wcsicmp(L"PERCENT", value) == 0)
{ case POWER_STATUS:
measure->type = POWER_PERCENT; return 4;
*maxValue = 100.0;
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;
} }
PLUGIN_EXPORT double Update(void* data) /*
This function is called when new value should be measured.
The function returns the new value.
*/
double Update2(UINT id)
{ {
MeasureData* measure = (MeasureData*)data; SYSTEM_POWER_STATUS status;
if (GetSystemPowerStatus(&status))
SYSTEM_POWER_STATUS sps;
if (GetSystemPowerStatus(&sps))
{ {
switch (measure->type) std::map<UINT, POWER_STATE>::iterator i = g_States.find(id);
if (i != g_States.end())
{ {
case POWER_ACLINE: switch ((*i).second)
return sps.ACLineStatus == 1 ? 1.0 : 0.0; {
case POWER_ACLINE:
return status.ACLineStatus == 1 ? 1 : 0;
case POWER_STATUS: case POWER_STATUS:
if (sps.BatteryFlag & 128) if (status.BatteryFlag & 128)
{ {
return 0.0; // No battery return 0; // No battery
} }
else if (sps.BatteryFlag & 8) else if (status.BatteryFlag & 8)
{ {
return 1.0; // Charging return 1; // Charging
} }
else if (sps.BatteryFlag & 4) else if (status.BatteryFlag & 4)
{ {
return 2.0; // Critical return 2; // Critical
} }
else if (sps.BatteryFlag & 2) else if (status.BatteryFlag & 2)
{ {
return 3.0; // Low return 3; // Low
} }
else if (sps.BatteryFlag & 1) else if (status.BatteryFlag & 1)
{ {
return 4.0; // High return 4; // High
} }
break; break;
case POWER_STATUS2: case POWER_STATUS2:
return sps.BatteryFlag; return status.BatteryFlag;
case POWER_LIFETIME: case POWER_LIFETIME:
return sps.BatteryLifeTime; return status.BatteryLifeTime;
case POWER_PERCENT: case POWER_PERCENT:
return sps.BatteryLifePercent == 255 ? 100.0 : sps.BatteryLifePercent; return status.BatteryLifePercent > 100 ? 100 : status.BatteryLifePercent;
case POWER_MHZ: case POWER_MHZ:
case POWER_HZ: case POWER_HZ:
if (g_NumOfProcessors > 0) if (fpCallNtPowerInformation && g_NumOfProcessors > 0)
{ {
PROCESSOR_POWER_INFORMATION* ppi = new PROCESSOR_POWER_INFORMATION[g_NumOfProcessors]; PROCESSOR_POWER_INFORMATION* ppi = new PROCESSOR_POWER_INFORMATION[g_NumOfProcessors];
memset(ppi, 0, sizeof(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); fpCallNtPowerInformation(ProcessorInformation, NULL, 0, ppi, sizeof(PROCESSOR_POWER_INFORMATION) * g_NumOfProcessors);
double value = (measure->type == POWER_MHZ) ? ppi[0].CurrentMhz : ppi[0].CurrentMhz * 1000000.0; double value = ((*i).second == POWER_MHZ) ? ppi[0].CurrentMhz : ppi[0].CurrentMhz * 1000000.0;
delete [] ppi; delete [] ppi;
return value; return value;
}
} }
} }
} }
return 0.0; return 0;
} }
PLUGIN_EXPORT LPCWSTR GetString(void* data) /*
This function is called when the value should be
returned as a string.
*/
LPCTSTR GetString(UINT id, UINT flags)
{ {
static WCHAR buffer[128]; static WCHAR buffer[128];
MeasureData* measure = (MeasureData*)data; std::map<UINT, POWER_STATE>::iterator i = g_States.find(id);
if (i != g_States.end())
if (measure->type == POWER_LIFETIME)
{ {
SYSTEM_POWER_STATUS sps; if ((*i).second == POWER_LIFETIME)
if (GetSystemPowerStatus(&sps))
{ {
// Change it to time string SYSTEM_POWER_STATUS status;
if (sps.BatteryLifeTime == -1) if (GetSystemPowerStatus(&status))
{ {
return L"Unknown"; // Change it to time string
} if (status.BatteryLifeTime == -1)
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)
{ {
buffer[0] = L'\0'; return L"Unknown";
} }
else
{
std::map<UINT, std::wstring>::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;
_set_invalid_parameter_handler(oldHandler); _invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(NullCRTInvalidParameterHandler);
_CrtSetReportMode(_CRT_ASSERT, 0);
return buffer; 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 NULL; return NULL;
} }
PLUGIN_EXPORT void Finalize(void* data) /*
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)
{ {
MeasureData* measure = (MeasureData*)data; std::map<UINT, POWER_STATE>::iterator i = g_States.find(id);
delete measure; if (i != g_States.end())
{
g_States.erase(i);
}
std::map<UINT, std::wstring>::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;
}
} }
UINT GetPluginVersion()
{
return 1004;
}
LPCTSTR GetPluginAuthor()
{
return L"Rainy (rainy@iki.fi)";
}

View File

@ -18,72 +18,117 @@
#include <windows.h> #include <windows.h>
#include <Psapi.h> #include <Psapi.h>
#include <algorithm> #include <string>
#include <vector> #include <map>
#include "../../Library/RawString.h"
#include "../../Library/Export.h" // Rainmeter's exported functions #include "../../Library/Export.h" // Rainmeter's exported functions
#include "../../Library/DisableThreadLibraryCalls.h" // contains DllMain entry point #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) UINT Update(UINT id);
__declspec(dllexport) UINT GetPluginVersion();
__declspec(dllexport) LPCTSTR GetPluginAuthor();
}
struct MeasureData struct MeasureData
{ {
CRawString processName; std::wstring processName;
bool isRunning; bool isRunning;
MeasureData() : isRunning(false) {} MeasureData() : isRunning(false) {}
}; };
static std::map<UINT, MeasureData> g_Values;
static UINT g_UpdateCount = 0; static UINT g_UpdateCount = 0;
static std::vector<MeasureData*> g_Measures;
void CheckProcesses(); void CheckProcesses();
PLUGIN_EXPORT void Initialize(void** data) /*
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)
{ {
MeasureData* measure = new MeasureData; MeasureData data;
g_Measures.push_back(measure);
*data = measure; const WCHAR* value = ReadConfigString(section, L"ProcessName", L"");
} if (*value)
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())
{ {
CheckProcesses(); data.processName = value;
g_UpdateCount = 0; g_Values[id] = std::move(data);
} }
return (double)measure->isRunning; return 1;
} }
PLUGIN_EXPORT void Finalize(void* data) /*
This function is called when new value should be measured.
The function returns the new value.
*/
UINT Update(UINT id)
{ {
MeasureData* measure = (MeasureData*)data; UINT result = 0;
std::vector<MeasureData*>::iterator iter = std::find(g_Measures.begin(), g_Measures.end(), measure);
g_Measures.erase(iter);
delete measure; std::map<UINT, MeasureData>::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 = (UINT)(*iter).second.isRunning;
}
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<UINT, MeasureData>::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)";
} }
void CheckProcesses() void CheckProcesses()
{ {
// Set everything to false // Set everything to false
std::vector<MeasureData*>::iterator iter = g_Measures.begin(); std::map<UINT, MeasureData>::iterator iter = g_Values.begin();
for ( ; iter != g_Measures.end(); ++iter) for ( ; iter != g_Values.end(); ++iter)
{ {
(*iter)->isRunning = false; (*iter).second.isRunning = false;
} }
int bufSize = 256; int bufSize = 256;
@ -106,12 +151,12 @@ void CheckProcesses()
WCHAR buffer[MAX_PATH]; WCHAR buffer[MAX_PATH];
if (GetModuleBaseName(hProcess, NULL, buffer, _countof(buffer))) if (GetModuleBaseName(hProcess, NULL, buffer, _countof(buffer)))
{ {
iter = g_Measures.begin(); iter = g_Values.begin();
for ( ; iter != g_Measures.end(); ++iter) for ( ; iter != g_Values.end(); ++iter)
{ {
if (_wcsicmp(buffer, (*iter)->processName.c_str()) == 0) if (_wcsicmp(buffer, (*iter).second.processName.c_str()) == 0)
{ {
(*iter)->isRunning = true; (*iter).second.isRunning = true;
} }
} }
} }

View File

@ -1,13 +1,14 @@
#pragma once #pragma once
#define MAKE_VER(major, minor1, minor2) major * 1000000 + minor1 * 1000 + minor2 #define MAKE_VER(major, minor1, minor2) major * 1000000 + minor1 * 1000 + minor2
#define FILEVER 2,3,0,1088 #define FILEVER 2,2,0,960
#define PRODUCTVER 2,3,0,1088 #define PRODUCTVER 2,2,0,960
#define STRFILEVER "2.3.0.1088" #define STRFILEVER "2.2.0.960"
#define STRPRODUCTVER "2.3.0.1088" #define STRPRODUCTVER "2.2.0.960"
#define APPVERSION L"2.3.0" #define REVISION L"960"
#define RAINMETER_VERSION MAKE_VER(2, 3, 0) #define APPVERSION L"2.2.0"
#define RAINMETER_VERSION MAKE_VER(2, 2, 0)
const int revision_number = 1088;
const bool revision_beta = true; const int revision_number = 960;
const bool revision_beta = true;