Work on exporting stuff, revert some changes for better diff

This commit is contained in:
Tiberiu Chibici 2014-08-01 22:54:35 +03:00
parent 473f23378f
commit 69913fa251
31 changed files with 21016 additions and 20755 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,262 +1,262 @@
/*
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Rainmeter.h"
#include "Export.h"
#include "MeterWindow.h"
#include "Measure.h"
#include "MeasurePlugin.h"
#define NULLCHECK(str) { if ((str) == nullptr) { (str) = L""; } }
static std::wstring g_Buffer;
LPCWSTR __stdcall RmReadString(void* rm, LPCWSTR option, LPCWSTR defValue, BOOL replaceMeasures)
{
NULLCHECK(option);
NULLCHECK(defValue);
MeasurePlugin* measure = (MeasurePlugin*)rm;
ConfigParser& parser = measure->GetMeterWindow()->GetParser();
return parser.ReadString(measure->GetName(), option, defValue, replaceMeasures != FALSE).c_str();
}
double __stdcall RmReadFormula(void* rm, LPCWSTR option, double defValue)
{
NULLCHECK(option);
MeasurePlugin* measure = (MeasurePlugin*)rm;
ConfigParser& parser = measure->GetMeterWindow()->GetParser();
return parser.ReadFloat(measure->GetName(), option, defValue);
}
LPCWSTR __stdcall RmReplaceVariables(void* rm, LPCWSTR str)
{
NULLCHECK(str);
MeasurePlugin* measure = (MeasurePlugin*)rm;
ConfigParser& parser = measure->GetMeterWindow()->GetParser();
g_Buffer = str;
parser.ReplaceVariables(g_Buffer);
parser.ReplaceMeasures(g_Buffer);
return g_Buffer.c_str();
}
LPCWSTR __stdcall RmPathToAbsolute(void* rm, LPCWSTR relativePath)
{
NULLCHECK(relativePath);
MeasurePlugin* measure = (MeasurePlugin*)rm;
g_Buffer = relativePath;
measure->GetMeterWindow()->MakePathAbsolute(g_Buffer);
return g_Buffer.c_str();
}
void* __stdcall RmGet(void* rm, int type)
{
MeasurePlugin* measure = (MeasurePlugin*)rm;
switch (type)
{
case RMG_MEASURENAME:
{
return (void*)measure->GetName();
}
case RMG_SKIN:
{
return (void*)measure->GetMeterWindow();
}
case RMG_SETTINGSFILE:
{
return (void*)Rainmeter::GetInstance().GetDataFile().c_str();
}
case RMG_SKINNAME:
{
MeterWindow* window = measure->GetMeterWindow();
if (!window) break;
return (void*)window->GetFolderPath().c_str();
}
case RMG_SKINWINDOWHANDLE:
{
MeterWindow* window = measure->GetMeterWindow();
if (!window) break;
return (void*)window->GetWindow();
}
}
return nullptr;
}
void __stdcall RmExecute(void* skin, LPCWSTR command)
{
MeterWindow* mw = (MeterWindow*)skin;
if (command)
{
// WM_RAINMETER_EXECUTE used instead of ExecuteCommand for thread-safety
SendMessage(Rainmeter::GetInstance().GetWindow(), WM_RAINMETER_EXECUTE, (WPARAM)mw, (LPARAM)command);
}
}
BOOL LSLog(int level, LPCWSTR unused, LPCWSTR message)
{
NULLCHECK(message);
// Ignore Debug messages from plugins unless in debug mode.
if (level != (int)Logger::Level::Debug || Rainmeter::GetInstance().GetDebug())
{
GetLogger().Log((Logger::Level)level, L"", message);
}
return TRUE;
}
void __stdcall RmLog(void* rm, int level, LPCWSTR message)
{
NULLCHECK(message);
MeasurePlugin* measure = (MeasurePlugin*)rm;
// Ignore Debug messages from plugins unless in debug mode.
if (level != (int)Logger::Level::Debug || Rainmeter::GetInstance().GetDebug())
{
GetLogger().LogSection((Logger::Level)level, measure, message);
}
}
void RmLogF(void* rm, int level, LPCWSTR format, ...)
{
NULLCHECK(format);
MeasurePlugin* measure = (MeasurePlugin*)rm;
// Ignore Debug messages from plugins unless in debug mode.
if (level != (int)Logger::Level::Debug || Rainmeter::GetInstance().GetDebug())
{
va_list args;
va_start(args, format);
GetLogger().LogSectionVF((Logger::Level)level, measure, format, args);
va_end(args);
}
}
// Deprecated!
LPCWSTR ReadConfigString(LPCWSTR section, LPCWSTR option, LPCWSTR defValue)
{
NULLCHECK(section);
NULLCHECK(option);
NULLCHECK(defValue);
ConfigParser* parser = Rainmeter::GetInstance().GetCurrentParser();
if (parser)
{
return parser->ReadString(section, option, defValue, false).c_str();
}
return defValue;
}
// Deprecated!
LPCWSTR PluginBridge(LPCWSTR command, LPCWSTR data)
{
if (command == nullptr || *command == L'\0')
{
return L"noop";
}
NULLCHECK(data);
if (_wcsicmp(command, L"GetConfig") == 0)
{
MeterWindow* meterWindow = Rainmeter::GetInstance().GetMeterWindowByINI(data);
if (meterWindow)
{
g_Buffer = L"\"";
g_Buffer += meterWindow->GetFolderPath();
g_Buffer += L"\"";
return g_Buffer.c_str();
}
return L"";
}
else if (_wcsicmp(command, L"GetWindow") == 0)
{
std::vector<std::wstring> subStrings = CommandHandler::ParseString(data);
if (subStrings.size() >= 1)
{
const std::wstring& config = subStrings[0];
MeterWindow* meterWindow = Rainmeter::GetInstance().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";
}
else if (_wcsicmp(command, L"GetVariable") == 0)
{
std::vector<std::wstring> subStrings = CommandHandler::ParseString(data);
if (subStrings.size() >= 2)
{
const std::wstring& config = subStrings[0];
MeterWindow* meterWindow = Rainmeter::GetInstance().GetMeterWindow(config);
if (meterWindow)
{
const std::wstring& variable = subStrings[1];
const std::wstring* value = meterWindow->GetParser().GetVariable(variable);
if (value)
{
return (*value).c_str();
}
}
}
return L"";
}
else if (_wcsicmp(command, L"SetVariable") == 0)
{
std::vector<std::wstring> subStrings = CommandHandler::ParseString(data);
if (subStrings.size() == 3)
{
MeterWindow* meterWindow = Rainmeter::GetInstance().GetMeterWindow(subStrings[0]);
if (meterWindow)
{
meterWindow->SetVariable(subStrings[1], subStrings[2]);
return L"success";
}
}
return L"error";
}
return L"noop";
}
/*
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Rainmeter.h"
#include "Export.h"
#include "MeterWindow.h"
#include "Measure.h"
#include "MeasurePlugin.h"
#define NULLCHECK(str) { if ((str) == nullptr) { (str) = L""; } }
static std::wstring g_Buffer;
LPCWSTR __stdcall RmReadString(void* rm, LPCWSTR option, LPCWSTR defValue, BOOL replaceMeasures)
{
NULLCHECK(option);
NULLCHECK(defValue);
MeasurePlugin* measure = (MeasurePlugin*)rm;
ConfigParser& parser = measure->GetMeterWindow()->GetParser();
return parser.ReadString(measure->GetName(), option, defValue, replaceMeasures != FALSE).c_str();
}
double __stdcall RmReadFormula(void* rm, LPCWSTR option, double defValue)
{
NULLCHECK(option);
MeasurePlugin* measure = (MeasurePlugin*)rm;
ConfigParser& parser = measure->GetMeterWindow()->GetParser();
return parser.ReadFloat(measure->GetName(), option, defValue);
}
LPCWSTR __stdcall RmReplaceVariables(void* rm, LPCWSTR str)
{
NULLCHECK(str);
MeasurePlugin* measure = (MeasurePlugin*)rm;
ConfigParser& parser = measure->GetMeterWindow()->GetParser();
g_Buffer = str;
parser.ReplaceVariables(g_Buffer);
parser.ReplaceMeasures(g_Buffer);
return g_Buffer.c_str();
}
LPCWSTR __stdcall RmPathToAbsolute(void* rm, LPCWSTR relativePath)
{
NULLCHECK(relativePath);
MeasurePlugin* measure = (MeasurePlugin*)rm;
g_Buffer = relativePath;
measure->GetMeterWindow()->MakePathAbsolute(g_Buffer);
return g_Buffer.c_str();
}
void* __stdcall RmGet(void* rm, int type)
{
MeasurePlugin* measure = (MeasurePlugin*)rm;
switch (type)
{
case RMG_MEASURENAME:
{
return (void*)measure->GetName();
}
case RMG_SKIN:
{
return (void*)measure->GetMeterWindow();
}
case RMG_SETTINGSFILE:
{
return (void*)GetRainmeter().GetDataFile().c_str();
}
case RMG_SKINNAME:
{
MeterWindow* window = measure->GetMeterWindow();
if (!window) break;
return (void*)window->GetFolderPath().c_str();
}
case RMG_SKINWINDOWHANDLE:
{
MeterWindow* window = measure->GetMeterWindow();
if (!window) break;
return (void*)window->GetWindow();
}
}
return nullptr;
}
void __stdcall RmExecute(void* skin, LPCWSTR command)
{
MeterWindow* mw = (MeterWindow*)skin;
if (command)
{
// WM_RAINMETER_EXECUTE used instead of ExecuteCommand for thread-safety
SendMessage(GetRainmeter().GetWindow(), WM_RAINMETER_EXECUTE, (WPARAM)mw, (LPARAM)command);
}
}
BOOL LSLog(int level, LPCWSTR unused, LPCWSTR message)
{
NULLCHECK(message);
// Ignore Debug messages from plugins unless in debug mode.
if (level != (int)Logger::Level::Debug || GetRainmeter().GetDebug())
{
GetLogger().Log((Logger::Level)level, L"", message);
}
return TRUE;
}
void __stdcall RmLog(void* rm, int level, LPCWSTR message)
{
NULLCHECK(message);
MeasurePlugin* measure = (MeasurePlugin*)rm;
// Ignore Debug messages from plugins unless in debug mode.
if (level != (int)Logger::Level::Debug || GetRainmeter().GetDebug())
{
GetLogger().LogSection((Logger::Level)level, measure, message);
}
}
void RmLogF(void* rm, int level, LPCWSTR format, ...)
{
NULLCHECK(format);
MeasurePlugin* measure = (MeasurePlugin*)rm;
// Ignore Debug messages from plugins unless in debug mode.
if (level != (int)Logger::Level::Debug || GetRainmeter().GetDebug())
{
va_list args;
va_start(args, format);
GetLogger().LogSectionVF((Logger::Level)level, measure, format, args);
va_end(args);
}
}
// Deprecated!
LPCWSTR ReadConfigString(LPCWSTR section, LPCWSTR option, LPCWSTR defValue)
{
NULLCHECK(section);
NULLCHECK(option);
NULLCHECK(defValue);
ConfigParser* parser = GetRainmeter().GetCurrentParser();
if (parser)
{
return parser->ReadString(section, option, defValue, false).c_str();
}
return defValue;
}
// Deprecated!
LPCWSTR PluginBridge(LPCWSTR command, LPCWSTR data)
{
if (command == nullptr || *command == L'\0')
{
return L"noop";
}
NULLCHECK(data);
if (_wcsicmp(command, L"GetConfig") == 0)
{
MeterWindow* meterWindow = GetRainmeter().GetMeterWindowByINI(data);
if (meterWindow)
{
g_Buffer = L"\"";
g_Buffer += meterWindow->GetFolderPath();
g_Buffer += L"\"";
return g_Buffer.c_str();
}
return L"";
}
else if (_wcsicmp(command, L"GetWindow") == 0)
{
std::vector<std::wstring> subStrings = CommandHandler::ParseString(data);
if (subStrings.size() >= 1)
{
const std::wstring& config = subStrings[0];
MeterWindow* meterWindow = GetRainmeter().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";
}
else if (_wcsicmp(command, L"GetVariable") == 0)
{
std::vector<std::wstring> subStrings = CommandHandler::ParseString(data);
if (subStrings.size() >= 2)
{
const std::wstring& config = subStrings[0];
MeterWindow* meterWindow = GetRainmeter().GetMeterWindow(config);
if (meterWindow)
{
const std::wstring& variable = subStrings[1];
const std::wstring* value = meterWindow->GetParser().GetVariable(variable);
if (value)
{
return (*value).c_str();
}
}
}
return L"";
}
else if (_wcsicmp(command, L"SetVariable") == 0)
{
std::vector<std::wstring> subStrings = CommandHandler::ParseString(data);
if (subStrings.size() == 3)
{
MeterWindow* meterWindow = GetRainmeter().GetMeterWindow(subStrings[0]);
if (meterWindow)
{
meterWindow->SetVariable(subStrings[1], subStrings[2]);
return L"success";
}
}
return L"error";
}
return L"noop";
}

3
Library/Exports_Common.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
#define EXPORT extern "C" _declspec(dllexport)

32
Library/Exports_Group.cpp Normal file
View File

@ -0,0 +1,32 @@
#include "StdAfx.h"
#include <cstdint>
#include "Group.h"
#include "HandleManager.h"
#include "Exports_Common.h"
EXPORT bool Group_BelongsToGroup (bool* result, int32_t handle, LPWSTR str)
{
Group* group = (Group*)handle_get_resource (handle);
if (group != nullptr)
{
*result = group->BelongsToGroup (str);
return true;
}
return false;
}
EXPORT bool Group_Destroy (int32_t handle)
{
Group* group = (Group*)handle_get_resource (handle);
if (group != nullptr)
{
handle_free (handle);
delete group;
return true;
}
return false;
}

21
Library/Exports_Meter.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "StdAfx.h"
#include <cstdint>
#include "Meter.h"
#include "HandleManager.h"
#include "Exports_Common.h"
EXPORT bool Meter_Destroy (int handle)
{
Meter* meter = (Meter*)handle_get_resource (handle);
if (meter != nullptr)
{
handle_free (handle);
delete meter;
return true;
}
return false;
}

View File

@ -0,0 +1,35 @@
#include "StdAfx.h"
#include <cstdint>
#include "MeterString.h"
#include "HandleManager.h"
#include "Exports_Common.h"
EXPORT bool MeterString_Init (int* handle_result, int meterCanvasHandle, LPCWSTR name)
{
MeterWindow* w = (MeterWindow*) handle_get_resource (meterCanvasHandle);
if (w != nullptr)
{
MeterString* result = new MeterString (w, name);
*handle_result = handle_allocate (result);
return true;
}
return false;
}
EXPORT bool MeterString_Destroy (int handle)
{
MeterString* ms = (MeterString*) handle_get_resource (handle);
if (ms != nullptr)
{
handle_free (handle);
delete ms;
return true;
}
return false;
}

View File

@ -0,0 +1,27 @@
#include "Rainmeter.h"
#include "HandleManager.h"
/*
** Initializes Rainmeter.
**
*/
bool Rainmeter_Initialize()
{
int res = GetRainmeter().Initialize(nullptr, nullptr);
// Success?
if (res == 0)
return &GetRainmeter();
return nullptr;
}
/*
** Finalizes Rainmeter.
**
*/
void Rainmeter_Finalize(void* ptr)
{
Rainmeter* rainmeter = (Rainmeter*)ptr;
rainmeter->Finalize();
}

131
Library/Exports_Section.cpp Normal file
View File

@ -0,0 +1,131 @@
#include "HandleManager.h"
#include "Exports_Common.h"
#include "Section.h"
EXPORT bool Section_GetName (LPCWCHAR* result, int32_t handle)
{
Section* section = (Section*) handle_get_resource (handle);
if (section != nullptr)
{
*result = section->GetName();
return true;
}
return false;
}
EXPORT bool Section_GetOriginalName (LPCWCHAR* result, int32_t handle)
{
Section* section = (Section*) handle_get_resource (handle);
if (section != nullptr)
{
*result = section->GetOriginalName().c_str();
return true;
}
return false;
}
EXPORT bool Section_HasDynamicVariables (bool* result, int32_t handle)
{
Section* section = (Section*) handle_get_resource (handle);
if (section != nullptr)
{
*result = section->HasDynamicVariables();
return true;
}
return false;
}
EXPORT bool Section_SetDynamicVariables (int32_t handle, bool value)
{
Section* section = (Section*) handle_get_resource (handle);
if (section != nullptr)
{
section->SetDynamicVariables(value);
return true;
}
return false;
}
EXPORT bool Section_ResetUpdateCounter (int32_t handle)
{
Section* section = (Section*) handle_get_resource (handle);
if (section != nullptr)
{
section->ResetUpdateCounter();
return true;
}
return false;
}
EXPORT bool Section_GetUpdateCounter (int* result, int32_t handle)
{
Section* section = (Section*) handle_get_resource (handle);
if (section != nullptr)
{
*result = section->GetUpdateCounter();
return true;
}
return false;
}
EXPORT bool Section_GetUpdateDivider (int* result, int32_t handle)
{
Section* section = (Section*) handle_get_resource (handle);
if (section != nullptr)
{
*result = section->GetUpdateDivider();
return true;
}
return false;
}
EXPORT bool Section_GetOnUpdateAction (LPCWCHAR* result, int32_t handle)
{
Section* section = (Section*) handle_get_resource (handle);
if (section != nullptr)
{
*result = section->GetOnUpdateAction().c_str();
return true;
}
return false;
}
EXPORT bool Section_DoUpdateAction (int32_t handle)
{
Section* section = (Section*) handle_get_resource (handle);
if (section != nullptr)
{
section->DoUpdateAction ();
return true;
}
return false;
}
EXPORT bool Section_Destroy (int32_t handle)
{
Section* section = (Section*) handle_get_resource (handle);
if (section != nullptr)
{
handle_free (handle);
delete section;
return true;
}
return false;
}

28
Library/HandleManager.cpp Normal file
View File

@ -0,0 +1,28 @@
#include <map>
#include <cstdint>
#include "HandleManager.h"
std::map<int32_t, void*> handles;
int32_t handle_allocate (void* resource)
{
static int32_t handle = 1;
handles.insert (std::make_pair(handle, resource));
return handle++;
}
void* handle_get_resource (int32_t handle)
{
if (handles.count (handle) != 0)
return handles.at (handle);
return nullptr;
}
void handle_free (int32_t handle)
{
handles.erase (handle);
}
void

7
Library/HandleManager.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
#include <cstdint>
int32_t handle_allocate (void* resource);
void* handle_get_resource (int32_t handle);
void handle_free (int32_t handle);

View File

@ -1,367 +1,367 @@
/*
Copyright (C) 2013 Brian Ferguson
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Measure.h"
#include "IfActions.h"
#include "Rainmeter.h"
#include "../Common/MathParser.h"
#include "pcre-8.10/config.h"
#include "pcre-8.10/pcre.h"
IfActions::IfActions() :
m_AboveValue(0.0f),
m_BelowValue(0.0f),
m_EqualValue(0),
m_AboveAction(),
m_BelowAction(),
m_EqualAction(),
m_AboveCommitted(false),
m_BelowCommitted(false),
m_EqualCommitted(false),
m_Conditions(),
m_ConditionMode(false),
m_Matches(),
m_MatchMode(false)
{
}
IfActions::~IfActions()
{
}
void IfActions::ReadOptions(ConfigParser& parser, const WCHAR* section)
{
m_AboveAction = parser.ReadString(section, L"IfAboveAction", L"", false);
m_AboveValue = parser.ReadFloat(section, L"IfAboveValue", 0.0f);
m_BelowAction = parser.ReadString(section, L"IfBelowAction", L"", false);
m_BelowValue = parser.ReadFloat(section, L"IfBelowValue", 0.0f);
m_EqualAction = parser.ReadString(section, L"IfEqualAction", L"", false);
m_EqualValue = (int64_t)parser.ReadFloat(section, L"IfEqualValue", 0.0f);
}
void IfActions::ReadConditionOptions(ConfigParser& parser, const WCHAR* section)
{
// IfCondition options
m_ConditionMode = parser.ReadBool(section, L"IfConditionMode", false);
std::wstring condition = parser.ReadString(section, L"IfCondition", L"");
if (!condition.empty())
{
std::wstring tAction = parser.ReadString(section, L"IfTrueAction", L"", false);
std::wstring fAction = parser.ReadString(section, L"IfFalseAction", L"", false);
if (!tAction.empty() || !fAction.empty())
{
size_t i = 1;
do
{
if (m_Conditions.size() > (i - 1))
{
m_Conditions[i - 1].Set(condition, tAction, fAction);
}
else
{
m_Conditions.emplace_back(condition, tAction, fAction);
}
// Check for IfCondition2/IfTrueAction2/IfFalseAction2 ... etc.
const std::wstring num = std::to_wstring(++i);
std::wstring key = L"IfCondition" + num;
condition = parser.ReadString(section, key.c_str(), L"");
if (condition.empty()) break;
key = L"IfTrueAction" + num;
tAction = parser.ReadString(section, key.c_str(), L"", false);
key = L"IfFalseAction" + num;
fAction = parser.ReadString(section, key.c_str(), L"", false);
}
while (!tAction.empty() || !fAction.empty());
}
else
{
m_Conditions.clear();
}
}
else
{
m_Conditions.clear();
}
// IfMatch options
m_MatchMode = parser.ReadBool(section, L"IfMatchMode", false);
std::wstring match = parser.ReadString(section, L"IfMatch", L"");
if (!match.empty())
{
std::wstring tAction = parser.ReadString(section, L"IfMatchAction", L"", false);
std::wstring fAction = parser.ReadString(section, L"IfNotMatchAction", L"", false);
if (!tAction.empty() || !fAction.empty())
{
size_t i = 1;
do
{
if (m_Matches.size() > (i - 1))
{
m_Matches[i - 1].Set(match, tAction, fAction);
}
else
{
m_Matches.emplace_back(match, tAction, fAction);
}
// Check for IfMatch2/IfMatchAction2/IfNotMatchAction2 ... etc.
const std::wstring num = std::to_wstring(++i);
std::wstring key = L"IfMatch" + num;
match = parser.ReadString(section, key.c_str(), L"");
if (match.empty()) break;
key = L"IfMatchAction" + num;
tAction = parser.ReadString(section, key.c_str(), L"", false);
key = L"IfNotMatchAction" + num;
fAction = parser.ReadString(section, key.c_str(), L"", false);
} while (!tAction.empty() || !fAction.empty());
}
else
{
m_Matches.clear();
}
}
else
{
m_Matches.clear();
}
}
void IfActions::DoIfActions(Measure& measure, double value)
{
// IfEqual
if (!m_EqualAction.empty())
{
if ((int64_t)value == m_EqualValue)
{
if (!m_EqualCommitted)
{
m_EqualCommitted = true; // To avoid infinite loop from !Update
Rainmeter::GetInstance().ExecuteCommand(m_EqualAction.c_str(), measure.GetMeterWindow());
}
}
else
{
m_EqualCommitted = false;
}
}
// IfAbove
if (!m_AboveAction.empty())
{
if (value > m_AboveValue)
{
if (!m_AboveCommitted)
{
m_AboveCommitted = true; // To avoid infinite loop from !Update
Rainmeter::GetInstance().ExecuteCommand(m_AboveAction.c_str(), measure.GetMeterWindow());
}
}
else
{
m_AboveCommitted = false;
}
}
// IfBelow
if (!m_BelowAction.empty())
{
if (value < m_BelowValue)
{
if (!m_BelowCommitted)
{
m_BelowCommitted = true; // To avoid infinite loop from !Update
Rainmeter::GetInstance().ExecuteCommand(m_BelowAction.c_str(), measure.GetMeterWindow());
}
}
else
{
m_BelowCommitted = false;
}
}
// IfCondition
int i = 0;
for (auto& item : m_Conditions)
{
++i;
if (!item.value.empty() && (!item.tAction.empty() || !item.fAction.empty()))
{
double result = 0.0f;
const WCHAR* errMsg = MathParser::Parse(
item.value.c_str(), &result, measure.GetCurrentMeasureValue, &measure);
if (errMsg != nullptr)
{
if (!item.parseError)
{
if (i == 1)
{
LogErrorF(&measure, L"%s: IfCondition=%s", errMsg, item.value.c_str());
}
else
{
LogErrorF(&measure, L"%s: IfCondition%i=%s", errMsg, i, item.value.c_str());
}
item.parseError = true;
}
}
else
{
item.parseError = false;
if (result == 1.0f) // "True"
{
item.fCommitted = false;
if (m_ConditionMode || !item.tCommitted)
{
item.tCommitted = true;
Rainmeter::GetInstance().ExecuteCommand(item.tAction.c_str(), measure.GetMeterWindow());
}
}
else if (result == 0.0f) // "False"
{
item.tCommitted = false;
if (m_ConditionMode || !item.fCommitted)
{
item.fCommitted = true;
Rainmeter::GetInstance().ExecuteCommand(item.fAction.c_str(), measure.GetMeterWindow());
}
}
}
}
}
// IfMatch
i = 0;
for (auto& item : m_Matches)
{
++i;
if (!item.value.empty() && (!item.tAction.empty() || !item.fAction.empty()))
{
const char* error;
int errorOffset;
pcre* re = pcre_compile(
StringUtil::NarrowUTF8(item.value).c_str(),
PCRE_UTF8,
&error,
&errorOffset,
nullptr);
if (!re)
{
if (!item.parseError)
{
if (i == 1)
{
LogErrorF(&measure, L"Error: \"%S\" in IfMatch=%s", error, item.value.c_str());
}
else
{
LogErrorF(&measure, L"Error: \"%S\" in IfMatch%i=%s", error, i, item.value.c_str());
}
item.parseError = true;
}
}
else
{
item.parseError = false;
std::string utf8str = StringUtil::NarrowUTF8(measure.GetStringValue());
int ovector[300];
int rc = pcre_exec(
re,
nullptr,
utf8str.c_str(),
(int)utf8str.length(),
0,
0,
ovector,
(int)_countof(ovector));
if (rc > 0) // Match
{
item.fCommitted = false;
if (m_MatchMode || !item.tCommitted)
{
item.tCommitted = true;
Rainmeter::GetInstance().ExecuteCommand(item.tAction.c_str(), measure.GetMeterWindow());
}
}
else // Not Match
{
item.tCommitted = false;
if (m_MatchMode || !item.fCommitted)
{
item.fCommitted = true;
Rainmeter::GetInstance().ExecuteCommand(item.fAction.c_str(), measure.GetMeterWindow());
}
}
}
// Release memory used for the compiled pattern
pcre_free(re);
}
}
}
void IfActions::SetState(double& value)
{
// Set IfAction committed state to false if condition is not met with value = 0
if (m_EqualValue != (int64_t)value)
{
m_EqualCommitted = false;
}
if (m_AboveValue <= value)
{
m_AboveCommitted = false;
}
if (m_BelowValue >= value)
{
m_BelowCommitted = false;
}
for (auto& item : m_Conditions)
{
item.tCommitted = false;
item.fCommitted = false;
}
for (auto& item : m_Matches)
{
item.tCommitted = false;
item.fCommitted = false;
}
}
/*
Copyright (C) 2013 Brian Ferguson
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Measure.h"
#include "IfActions.h"
#include "Rainmeter.h"
#include "../Common/MathParser.h"
#include "pcre-8.10/config.h"
#include "pcre-8.10/pcre.h"
IfActions::IfActions() :
m_AboveValue(0.0f),
m_BelowValue(0.0f),
m_EqualValue(0),
m_AboveAction(),
m_BelowAction(),
m_EqualAction(),
m_AboveCommitted(false),
m_BelowCommitted(false),
m_EqualCommitted(false),
m_Conditions(),
m_ConditionMode(false),
m_Matches(),
m_MatchMode(false)
{
}
IfActions::~IfActions()
{
}
void IfActions::ReadOptions(ConfigParser& parser, const WCHAR* section)
{
m_AboveAction = parser.ReadString(section, L"IfAboveAction", L"", false);
m_AboveValue = parser.ReadFloat(section, L"IfAboveValue", 0.0f);
m_BelowAction = parser.ReadString(section, L"IfBelowAction", L"", false);
m_BelowValue = parser.ReadFloat(section, L"IfBelowValue", 0.0f);
m_EqualAction = parser.ReadString(section, L"IfEqualAction", L"", false);
m_EqualValue = (int64_t)parser.ReadFloat(section, L"IfEqualValue", 0.0f);
}
void IfActions::ReadConditionOptions(ConfigParser& parser, const WCHAR* section)
{
// IfCondition options
m_ConditionMode = parser.ReadBool(section, L"IfConditionMode", false);
std::wstring condition = parser.ReadString(section, L"IfCondition", L"");
if (!condition.empty())
{
std::wstring tAction = parser.ReadString(section, L"IfTrueAction", L"", false);
std::wstring fAction = parser.ReadString(section, L"IfFalseAction", L"", false);
if (!tAction.empty() || !fAction.empty())
{
size_t i = 1;
do
{
if (m_Conditions.size() > (i - 1))
{
m_Conditions[i - 1].Set(condition, tAction, fAction);
}
else
{
m_Conditions.emplace_back(condition, tAction, fAction);
}
// Check for IfCondition2/IfTrueAction2/IfFalseAction2 ... etc.
const std::wstring num = std::to_wstring(++i);
std::wstring key = L"IfCondition" + num;
condition = parser.ReadString(section, key.c_str(), L"");
if (condition.empty()) break;
key = L"IfTrueAction" + num;
tAction = parser.ReadString(section, key.c_str(), L"", false);
key = L"IfFalseAction" + num;
fAction = parser.ReadString(section, key.c_str(), L"", false);
}
while (!tAction.empty() || !fAction.empty());
}
else
{
m_Conditions.clear();
}
}
else
{
m_Conditions.clear();
}
// IfMatch options
m_MatchMode = parser.ReadBool(section, L"IfMatchMode", false);
std::wstring match = parser.ReadString(section, L"IfMatch", L"");
if (!match.empty())
{
std::wstring tAction = parser.ReadString(section, L"IfMatchAction", L"", false);
std::wstring fAction = parser.ReadString(section, L"IfNotMatchAction", L"", false);
if (!tAction.empty() || !fAction.empty())
{
size_t i = 1;
do
{
if (m_Matches.size() > (i - 1))
{
m_Matches[i - 1].Set(match, tAction, fAction);
}
else
{
m_Matches.emplace_back(match, tAction, fAction);
}
// Check for IfMatch2/IfMatchAction2/IfNotMatchAction2 ... etc.
const std::wstring num = std::to_wstring(++i);
std::wstring key = L"IfMatch" + num;
match = parser.ReadString(section, key.c_str(), L"");
if (match.empty()) break;
key = L"IfMatchAction" + num;
tAction = parser.ReadString(section, key.c_str(), L"", false);
key = L"IfNotMatchAction" + num;
fAction = parser.ReadString(section, key.c_str(), L"", false);
} while (!tAction.empty() || !fAction.empty());
}
else
{
m_Matches.clear();
}
}
else
{
m_Matches.clear();
}
}
void IfActions::DoIfActions(Measure& measure, double value)
{
// IfEqual
if (!m_EqualAction.empty())
{
if ((int64_t)value == m_EqualValue)
{
if (!m_EqualCommitted)
{
m_EqualCommitted = true; // To avoid infinite loop from !Update
GetRainmeter().ExecuteCommand(m_EqualAction.c_str(), measure.GetMeterWindow());
}
}
else
{
m_EqualCommitted = false;
}
}
// IfAbove
if (!m_AboveAction.empty())
{
if (value > m_AboveValue)
{
if (!m_AboveCommitted)
{
m_AboveCommitted = true; // To avoid infinite loop from !Update
GetRainmeter().ExecuteCommand(m_AboveAction.c_str(), measure.GetMeterWindow());
}
}
else
{
m_AboveCommitted = false;
}
}
// IfBelow
if (!m_BelowAction.empty())
{
if (value < m_BelowValue)
{
if (!m_BelowCommitted)
{
m_BelowCommitted = true; // To avoid infinite loop from !Update
GetRainmeter().ExecuteCommand(m_BelowAction.c_str(), measure.GetMeterWindow());
}
}
else
{
m_BelowCommitted = false;
}
}
// IfCondition
int i = 0;
for (auto& item : m_Conditions)
{
++i;
if (!item.value.empty() && (!item.tAction.empty() || !item.fAction.empty()))
{
double result = 0.0f;
const WCHAR* errMsg = MathParser::Parse(
item.value.c_str(), &result, measure.GetCurrentMeasureValue, &measure);
if (errMsg != nullptr)
{
if (!item.parseError)
{
if (i == 1)
{
LogErrorF(&measure, L"%s: IfCondition=%s", errMsg, item.value.c_str());
}
else
{
LogErrorF(&measure, L"%s: IfCondition%i=%s", errMsg, i, item.value.c_str());
}
item.parseError = true;
}
}
else
{
item.parseError = false;
if (result == 1.0f) // "True"
{
item.fCommitted = false;
if (m_ConditionMode || !item.tCommitted)
{
item.tCommitted = true;
GetRainmeter().ExecuteCommand(item.tAction.c_str(), measure.GetMeterWindow());
}
}
else if (result == 0.0f) // "False"
{
item.tCommitted = false;
if (m_ConditionMode || !item.fCommitted)
{
item.fCommitted = true;
GetRainmeter().ExecuteCommand(item.fAction.c_str(), measure.GetMeterWindow());
}
}
}
}
}
// IfMatch
i = 0;
for (auto& item : m_Matches)
{
++i;
if (!item.value.empty() && (!item.tAction.empty() || !item.fAction.empty()))
{
const char* error;
int errorOffset;
pcre* re = pcre_compile(
StringUtil::NarrowUTF8(item.value).c_str(),
PCRE_UTF8,
&error,
&errorOffset,
nullptr);
if (!re)
{
if (!item.parseError)
{
if (i == 1)
{
LogErrorF(&measure, L"Error: \"%S\" in IfMatch=%s", error, item.value.c_str());
}
else
{
LogErrorF(&measure, L"Error: \"%S\" in IfMatch%i=%s", error, i, item.value.c_str());
}
item.parseError = true;
}
}
else
{
item.parseError = false;
std::string utf8str = StringUtil::NarrowUTF8(measure.GetStringValue());
int ovector[300];
int rc = pcre_exec(
re,
nullptr,
utf8str.c_str(),
(int)utf8str.length(),
0,
0,
ovector,
(int)_countof(ovector));
if (rc > 0) // Match
{
item.fCommitted = false;
if (m_MatchMode || !item.tCommitted)
{
item.tCommitted = true;
GetRainmeter().ExecuteCommand(item.tAction.c_str(), measure.GetMeterWindow());
}
}
else // Not Match
{
item.tCommitted = false;
if (m_MatchMode || !item.fCommitted)
{
item.fCommitted = true;
GetRainmeter().ExecuteCommand(item.fAction.c_str(), measure.GetMeterWindow());
}
}
}
// Release memory used for the compiled pattern
pcre_free(re);
}
}
}
void IfActions::SetState(double& value)
{
// Set IfAction committed state to false if condition is not met with value = 0
if (m_EqualValue != (int64_t)value)
{
m_EqualCommitted = false;
}
if (m_AboveValue <= value)
{
m_AboveCommitted = false;
}
if (m_BelowValue >= value)
{
m_BelowCommitted = false;
}
for (auto& item : m_Conditions)
{
item.tCommitted = false;
item.fCommitted = false;
}
for (auto& item : m_Matches)
{
item.tCommitted = false;
item.fCommitted = false;
}
}

View File

@ -1,90 +1,90 @@
/*
Copyright (C) 2002 Kimmo Pekkola + few lsapi developers
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Litestep.h"
#include "Rainmeter.h"
#include "DialogAbout.h"
#include "System.h"
UINT GetUniqueID()
{
static UINT id = 0;
return id++;
}
WCHAR* GetString(UINT id)
{
LPWSTR pData;
int len = LoadString(Rainmeter::GetInstance().GetResourceInstance(), id, (LPWSTR)&pData, 0);
return len ? pData : L"";
}
std::wstring GetFormattedString(UINT id, ...)
{
LPWSTR pBuffer = nullptr;
va_list args = nullptr;
va_start(args, id);
DWORD len = FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
GetString(id),
0,
0,
(LPWSTR)&pBuffer,
0,
&args);
va_end(args);
std::wstring tmpSz(len ? pBuffer : L"", len);
if (pBuffer) LocalFree(pBuffer);
return tmpSz;
}
HICON GetIcon(UINT id, bool large)
{
HINSTANCE hExe = GetModuleHandle(nullptr);
HINSTANCE hComctl = GetModuleHandle(L"Comctl32");
if (hComctl)
{
// Try LoadIconMetric for better quality with high DPI
auto loadIconMetric = (decltype(LoadIconMetric)*)GetProcAddress(hComctl, "LoadIconMetric");
if (loadIconMetric)
{
HICON icon;
HRESULT hr = loadIconMetric(hExe, MAKEINTRESOURCE(id), large ? LIM_LARGE : LIM_SMALL, &icon);
if (SUCCEEDED(hr))
{
return icon;
}
}
}
return (HICON)LoadImage(
hExe,
MAKEINTRESOURCE(id),
IMAGE_ICON,
GetSystemMetrics(large ? SM_CXICON : SM_CXSMICON),
GetSystemMetrics(large ? SM_CYICON : SM_CYSMICON),
LR_SHARED);
}
void RmNullCRTInvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
{
// Do nothing.
}
/*
Copyright (C) 2002 Kimmo Pekkola + few lsapi developers
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Litestep.h"
#include "Rainmeter.h"
#include "DialogAbout.h"
#include "System.h"
UINT GetUniqueID()
{
static UINT id = 0;
return id++;
}
WCHAR* GetString(UINT id)
{
LPWSTR pData;
int len = LoadString(GetRainmeter().GetResourceInstance(), id, (LPWSTR)&pData, 0);
return len ? pData : L"";
}
std::wstring GetFormattedString(UINT id, ...)
{
LPWSTR pBuffer = nullptr;
va_list args = nullptr;
va_start(args, id);
DWORD len = FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
GetString(id),
0,
0,
(LPWSTR)&pBuffer,
0,
&args);
va_end(args);
std::wstring tmpSz(len ? pBuffer : L"", len);
if (pBuffer) LocalFree(pBuffer);
return tmpSz;
}
HICON GetIcon(UINT id, bool large)
{
HINSTANCE hExe = GetModuleHandle(nullptr);
HINSTANCE hComctl = GetModuleHandle(L"Comctl32");
if (hComctl)
{
// Try LoadIconMetric for better quality with high DPI
auto loadIconMetric = (decltype(LoadIconMetric)*)GetProcAddress(hComctl, "LoadIconMetric");
if (loadIconMetric)
{
HICON icon;
HRESULT hr = loadIconMetric(hExe, MAKEINTRESOURCE(id), large ? LIM_LARGE : LIM_SMALL, &icon);
if (SUCCEEDED(hr))
{
return icon;
}
}
}
return (HICON)LoadImage(
hExe,
MAKEINTRESOURCE(id),
IMAGE_ICON,
GetSystemMetrics(large ? SM_CXICON : SM_CXSMICON),
GetSystemMetrics(large ? SM_CYICON : SM_CYSMICON),
LR_SHARED);
}
void RmNullCRTInvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
{
// Do nothing.
}

View File

@ -1,276 +1,276 @@
/*
Copyright (C) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Logger.h"
#include "DialogAbout.h"
#include "Litestep.h"
#include "Rainmeter.h"
#include "Section.h"
#include "MeterWindow.h"
#include "System.h"
#include "resource.h"
namespace {
const size_t MAX_LOG_ENTIRES = 20;
} // namespace
Logger::Logger() :
m_LogToFile(false)
{
System::InitializeCriticalSection(&m_CsLog);
System::InitializeCriticalSection(&m_CsLogDelay);
}
Logger::~Logger()
{
DeleteCriticalSection(&m_CsLog);
DeleteCriticalSection(&m_CsLogDelay);
}
Logger& Logger::GetInstance()
{
static Logger s_Logger;
return s_Logger;
}
void Logger::StartLogFile()
{
const WCHAR* filePath = m_LogFilePath.c_str();
if (_waccess(filePath, 0) == -1)
{
// Create empty log file.
HANDLE file = CreateFile(filePath, GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr);
if (file != INVALID_HANDLE_VALUE)
{
CloseHandle(file);
}
else
{
const std::wstring text = GetFormattedString(ID_STR_LOGFILECREATEFAIL, filePath);
Rainmeter::GetInstance().ShowMessage(nullptr, text.c_str(), MB_OK | MB_ICONERROR);
SetLogToFile(false);
return;
}
}
SetLogToFile(true);
}
void Logger::StopLogFile()
{
SetLogToFile(false);
}
void Logger::DeleteLogFile()
{
const WCHAR* filePath = m_LogFilePath.c_str();
if (_waccess(filePath, 0) != -1)
{
const std::wstring text = GetFormattedString(ID_STR_LOGFILEDELETE, filePath);
const int res = Rainmeter::GetInstance().ShowMessage(nullptr, text.c_str(), MB_YESNO | MB_ICONQUESTION);
if (res == IDYES)
{
SetLogToFile(false);
System::RemoveFile(m_LogFilePath);
}
}
}
void Logger::SetLogToFile(bool logToFile)
{
m_LogToFile = logToFile;
WritePrivateProfileString(
L"Rainmeter", L"Logging", logToFile ? L"1" : L"0", Rainmeter::GetInstance().GetIniFile().c_str());
}
void Logger::LogInternal(Level level, ULONGLONG timestamp, const WCHAR* source, const WCHAR* msg)
{
WCHAR timestampSz[128];
size_t len = _snwprintf_s(
timestampSz,
_TRUNCATE,
L"%02llu:%02llu:%02llu.%03llu",
timestamp / (1000 * 60 * 60),
(timestamp / (1000 * 60)) % 60,
(timestamp / 1000) % 60,
timestamp % 1000);
// Store up to MAX_LOG_ENTIRES entries.
Entry entry = {level, std::wstring(timestampSz, len), source, msg};
m_Entries.push_back(entry);
if (m_Entries.size() > MAX_LOG_ENTIRES)
{
m_Entries.pop_front();
}
DialogAbout::AddLogItem(level, timestampSz, source, msg);
WriteToLogFile(entry);
}
void Logger::WriteToLogFile(Entry& entry)
{
#ifndef _DEBUG
if (!m_LogToFile) return;
#endif
const WCHAR* levelSz =
(entry.level == Level::Error) ? L"ERRO" :
(entry.level == Level::Warning) ? L"WARN" :
(entry.level == Level::Notice) ? L"NOTE" :
L"DBUG";
std::wstring message = levelSz;
message += L" (";
message.append(entry.timestamp);
message += L") ";
message += entry.source;
message += L": ";
message += entry.message;
message += L'\n';
#ifdef _DEBUG
_RPTW0(_CRT_WARN, message.c_str());
if (!m_LogToFile) return;
#endif
const WCHAR* filePath = m_LogFilePath.c_str();
if (_waccess(filePath, 0) == -1)
{
// The file has been deleted manually.
StopLogFile();
}
else
{
FILE* file = _wfopen(filePath, L"a+, ccs=UTF-8");
if (file)
{
fputws(message.c_str(), file);
fclose(file);
}
}
}
void Logger::Log(Level level, const WCHAR* source, const WCHAR* msg)
{
struct DelayedEntry
{
Level level;
ULONGLONG elapsed;
std::wstring message;
};
static std::list<DelayedEntry> s_DelayedEntries;
static ULONGLONG s_StartTime = System::GetTickCount64();
ULONGLONG elapsed = System::GetTickCount64() - s_StartTime;
if (TryEnterCriticalSection(&m_CsLog))
{
// Log queued messages first.
EnterCriticalSection(&m_CsLogDelay);
while (!s_DelayedEntries.empty())
{
DelayedEntry& entry = s_DelayedEntries.front();
LogInternal(entry.level, entry.elapsed, source, entry.message.c_str());
s_DelayedEntries.erase(s_DelayedEntries.begin());
}
LeaveCriticalSection(&m_CsLogDelay);
// Log the actual message.
LogInternal(level, elapsed, source, msg);
LeaveCriticalSection(&m_CsLog);
}
else
{
// Queue message.
EnterCriticalSection(&m_CsLogDelay);
DelayedEntry entry = {level, elapsed, msg};
s_DelayedEntries.push_back(entry);
LeaveCriticalSection(&m_CsLogDelay);
}
}
void Logger::LogVF(Level level, const WCHAR* source, const WCHAR* format, va_list args)
{
WCHAR* buffer = new WCHAR[1024];
_invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(RmNullCRTInvalidParameterHandler);
_CrtSetReportMode(_CRT_ASSERT, 0);
errno = 0;
_vsnwprintf_s(buffer, 1024, _TRUNCATE, format, args);
if (errno != 0)
{
level = Level::Error;
_snwprintf_s(buffer, 1024, _TRUNCATE, L"Internal error: %s", format);
}
_set_invalid_parameter_handler(oldHandler);
Log(level, source, buffer);
delete [] buffer;
}
std::wstring GetSectionSourceString(Section* section)
{
std::wstring source;
if (section)
{
MeterWindow* meterWindow = section->GetMeterWindow();
if (meterWindow)
{
source = meterWindow->GetSkinPath();
source += L" - ";
}
source += L'[';
source += section->GetOriginalName();
source += L']';
}
return source;
}
void Logger::LogSection(Logger::Level level, Section* section, const WCHAR* message)
{
const std::wstring source = GetSectionSourceString(section);
GetLogger().Log(level, source.c_str(), message);
}
void Logger::LogSectionVF(Logger::Level level, Section* section, const WCHAR* format, va_list args)
{
const std::wstring source = GetSectionSourceString(section);
GetLogger().LogVF(level, source.c_str(), format, args);
}
void Logger::LogMeterWindowVF(Logger::Level level, MeterWindow* meterWindow, const WCHAR* format, va_list args)
{
std::wstring source;
if (meterWindow)
{
source = meterWindow->GetSkinPath();
}
GetLogger().LogVF(level, source.c_str(), format, args);
}
/*
Copyright (C) 2013 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Logger.h"
#include "DialogAbout.h"
#include "Litestep.h"
#include "Rainmeter.h"
#include "Section.h"
#include "MeterWindow.h"
#include "System.h"
#include "resource.h"
namespace {
const size_t MAX_LOG_ENTIRES = 20;
} // namespace
Logger::Logger() :
m_LogToFile(false)
{
System::InitializeCriticalSection(&m_CsLog);
System::InitializeCriticalSection(&m_CsLogDelay);
}
Logger::~Logger()
{
DeleteCriticalSection(&m_CsLog);
DeleteCriticalSection(&m_CsLogDelay);
}
Logger& Logger::GetInstance()
{
static Logger s_Logger;
return s_Logger;
}
void Logger::StartLogFile()
{
const WCHAR* filePath = m_LogFilePath.c_str();
if (_waccess(filePath, 0) == -1)
{
// Create empty log file.
HANDLE file = CreateFile(filePath, GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr);
if (file != INVALID_HANDLE_VALUE)
{
CloseHandle(file);
}
else
{
const std::wstring text = GetFormattedString(ID_STR_LOGFILECREATEFAIL, filePath);
GetRainmeter().ShowMessage(nullptr, text.c_str(), MB_OK | MB_ICONERROR);
SetLogToFile(false);
return;
}
}
SetLogToFile(true);
}
void Logger::StopLogFile()
{
SetLogToFile(false);
}
void Logger::DeleteLogFile()
{
const WCHAR* filePath = m_LogFilePath.c_str();
if (_waccess(filePath, 0) != -1)
{
const std::wstring text = GetFormattedString(ID_STR_LOGFILEDELETE, filePath);
const int res = GetRainmeter().ShowMessage(nullptr, text.c_str(), MB_YESNO | MB_ICONQUESTION);
if (res == IDYES)
{
SetLogToFile(false);
System::RemoveFile(m_LogFilePath);
}
}
}
void Logger::SetLogToFile(bool logToFile)
{
m_LogToFile = logToFile;
WritePrivateProfileString(
L"Rainmeter", L"Logging", logToFile ? L"1" : L"0", GetRainmeter().GetIniFile().c_str());
}
void Logger::LogInternal(Level level, ULONGLONG timestamp, const WCHAR* source, const WCHAR* msg)
{
WCHAR timestampSz[128];
size_t len = _snwprintf_s(
timestampSz,
_TRUNCATE,
L"%02llu:%02llu:%02llu.%03llu",
timestamp / (1000 * 60 * 60),
(timestamp / (1000 * 60)) % 60,
(timestamp / 1000) % 60,
timestamp % 1000);
// Store up to MAX_LOG_ENTIRES entries.
Entry entry = {level, std::wstring(timestampSz, len), source, msg};
m_Entries.push_back(entry);
if (m_Entries.size() > MAX_LOG_ENTIRES)
{
m_Entries.pop_front();
}
DialogAbout::AddLogItem(level, timestampSz, source, msg);
WriteToLogFile(entry);
}
void Logger::WriteToLogFile(Entry& entry)
{
#ifndef _DEBUG
if (!m_LogToFile) return;
#endif
const WCHAR* levelSz =
(entry.level == Level::Error) ? L"ERRO" :
(entry.level == Level::Warning) ? L"WARN" :
(entry.level == Level::Notice) ? L"NOTE" :
L"DBUG";
std::wstring message = levelSz;
message += L" (";
message.append(entry.timestamp);
message += L") ";
message += entry.source;
message += L": ";
message += entry.message;
message += L'\n';
#ifdef _DEBUG
_RPTW0(_CRT_WARN, message.c_str());
if (!m_LogToFile) return;
#endif
const WCHAR* filePath = m_LogFilePath.c_str();
if (_waccess(filePath, 0) == -1)
{
// The file has been deleted manually.
StopLogFile();
}
else
{
FILE* file = _wfopen(filePath, L"a+, ccs=UTF-8");
if (file)
{
fputws(message.c_str(), file);
fclose(file);
}
}
}
void Logger::Log(Level level, const WCHAR* source, const WCHAR* msg)
{
struct DelayedEntry
{
Level level;
ULONGLONG elapsed;
std::wstring message;
};
static std::list<DelayedEntry> s_DelayedEntries;
static ULONGLONG s_StartTime = System::GetTickCount64();
ULONGLONG elapsed = System::GetTickCount64() - s_StartTime;
if (TryEnterCriticalSection(&m_CsLog))
{
// Log queued messages first.
EnterCriticalSection(&m_CsLogDelay);
while (!s_DelayedEntries.empty())
{
DelayedEntry& entry = s_DelayedEntries.front();
LogInternal(entry.level, entry.elapsed, source, entry.message.c_str());
s_DelayedEntries.erase(s_DelayedEntries.begin());
}
LeaveCriticalSection(&m_CsLogDelay);
// Log the actual message.
LogInternal(level, elapsed, source, msg);
LeaveCriticalSection(&m_CsLog);
}
else
{
// Queue message.
EnterCriticalSection(&m_CsLogDelay);
DelayedEntry entry = {level, elapsed, msg};
s_DelayedEntries.push_back(entry);
LeaveCriticalSection(&m_CsLogDelay);
}
}
void Logger::LogVF(Level level, const WCHAR* source, const WCHAR* format, va_list args)
{
WCHAR* buffer = new WCHAR[1024];
_invalid_parameter_handler oldHandler = _set_invalid_parameter_handler(RmNullCRTInvalidParameterHandler);
_CrtSetReportMode(_CRT_ASSERT, 0);
errno = 0;
_vsnwprintf_s(buffer, 1024, _TRUNCATE, format, args);
if (errno != 0)
{
level = Level::Error;
_snwprintf_s(buffer, 1024, _TRUNCATE, L"Internal error: %s", format);
}
_set_invalid_parameter_handler(oldHandler);
Log(level, source, buffer);
delete [] buffer;
}
std::wstring GetSectionSourceString(Section* section)
{
std::wstring source;
if (section)
{
MeterWindow* meterWindow = section->GetMeterWindow();
if (meterWindow)
{
source = meterWindow->GetSkinPath();
source += L" - ";
}
source += L'[';
source += section->GetOriginalName();
source += L']';
}
return source;
}
void Logger::LogSection(Logger::Level level, Section* section, const WCHAR* message)
{
const std::wstring source = GetSectionSourceString(section);
GetLogger().Log(level, source.c_str(), message);
}
void Logger::LogSectionVF(Logger::Level level, Section* section, const WCHAR* format, va_list args)
{
const std::wstring source = GetSectionSourceString(section);
GetLogger().LogVF(level, source.c_str(), format, args);
}
void Logger::LogMeterWindowVF(Logger::Level level, MeterWindow* meterWindow, const WCHAR* format, va_list args)
{
std::wstring source;
if (meterWindow)
{
source = meterWindow->GetSkinPath();
}
GetLogger().LogVF(level, source.c_str(), format, args);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,258 +1,258 @@
/*
Copyright (C) 2001 Kimmo Pekkola
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "MeasurePlugin.h"
#include "Rainmeter.h"
#include "Export.h"
#include "System.h"
#include "Error.h"
/*
** The constructor
**
*/
MeasurePlugin::MeasurePlugin(MeterWindow* meterWindow, const WCHAR* name) : Measure(meterWindow, name),
m_Plugin(),
m_ReloadFunc(),
m_ID(),
m_Update2(false),
m_PluginData(),
m_UpdateFunc(),
m_GetStringFunc(),
m_ExecuteBangFunc()
{
}
/*
** The destructor
**
*/
MeasurePlugin::~MeasurePlugin()
{
if (m_Plugin)
{
FARPROC finalizeFunc = GetProcAddress(m_Plugin, "Finalize");
if (finalizeFunc)
{
if (IsNewApi())
{
((NEWFINALIZE)finalizeFunc)(m_PluginData);
}
else
{
((FINALIZE)finalizeFunc)(m_Plugin, m_ID);
}
}
FreeLibrary(m_Plugin);
}
}
/*
** Gets the current value from the plugin
**
*/
void MeasurePlugin::UpdateValue()
{
if (m_UpdateFunc)
{
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
System::ResetWorkingDirectory();
}
}
/*
** Reads the options and loads the plugin
**
*/
void MeasurePlugin::ReadOptions(ConfigParser& parser, const WCHAR* section)
{
static UINT id = 0;
Measure::ReadOptions(parser, section);
if (m_Initialized)
{
if (IsNewApi())
{
((NEWRELOAD)m_ReloadFunc)(m_PluginData, this, &m_MaxValue);
}
// DynamicVariables doesn't work with old plugins
return;
}
const std::wstring& plugin = parser.ReadString(section, L"Plugin", L"");
size_t pos = plugin.find_last_of(L"\\/");
std::wstring pluginName;
if (pos != std::wstring::npos)
{
pluginName.assign(plugin, pos, plugin.length() - pos);
}
else
{
pluginName = plugin;
}
// First try from program path
std::wstring pluginFile = Rainmeter::GetInstance().GetPluginPath();
pluginFile += pluginName;
m_Plugin = System::RmLoadLibrary(pluginFile.c_str());
if (!m_Plugin)
{
if (Rainmeter::GetInstance().HasUserPluginPath())
{
// Try from settings path
pluginFile = Rainmeter::GetInstance().GetUserPluginPath();
pluginFile += pluginName;
m_Plugin = System::RmLoadLibrary(pluginFile.c_str());
}
if (!m_Plugin)
{
LogErrorF(
this, L"Plugin: Unable to load \"%s\" (error %ld)",
pluginName.c_str(), GetLastError());
return;
}
}
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");
// Remove current directory from DLL search path
SetDllDirectory(L"");
double maxValue = 0.0;
if (IsNewApi())
{
m_PluginData = (void*)id;
if (initializeFunc)
{
((NEWINITIALIZE)initializeFunc)(&m_PluginData, this);
}
((NEWRELOAD)m_ReloadFunc)(m_PluginData, this, &maxValue);
}
else
{
m_ID = id;
if (!m_UpdateFunc)
{
m_UpdateFunc = GetProcAddress(m_Plugin, "Update2");
m_Update2 = true;
}
if (initializeFunc)
{
maxValue = ((INITIALIZE)initializeFunc)(m_Plugin, m_MeterWindow->GetFilePath().c_str(), section, m_ID);
}
}
const std::wstring& szMaxValue = parser.ReadString(section, L"MaxValue", L"");
if (szMaxValue.empty())
{
if (maxValue == 0.0)
{
m_MaxValue = 1.0;
m_LogMaxValue = true;
m_MedianValues.clear();
}
else
{
m_MaxValue = maxValue;
m_LogMaxValue = false;
}
}
// Reset to default
SetDllDirectory(L"");
System::ResetWorkingDirectory();
++id;
}
/*
** Gets the string value from the plugin.
**
*/
const WCHAR* MeasurePlugin::GetStringValue()
{
if (m_GetStringFunc)
{
const WCHAR* ret;
if (IsNewApi())
{
ret = ((NEWGETSTRING)m_GetStringFunc)(m_PluginData);
}
else
{
ret = ((GETSTRING)m_GetStringFunc)(m_ID, 0);
}
if (ret) return CheckSubstitute(ret);
}
return nullptr;
}
/*
** Sends a bang to the plugin
**
*/
void MeasurePlugin::Command(const std::wstring& command)
{
if (m_ExecuteBangFunc)
{
const WCHAR* str = command.c_str();
if (IsNewApi())
{
((NEWEXECUTEBANG)m_ExecuteBangFunc)(m_PluginData, str);
}
else
{
((EXECUTEBANG)m_ExecuteBangFunc)(str, m_ID);
}
}
else
{
Measure::Command(command);
}
}
/*
Copyright (C) 2001 Kimmo Pekkola
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "MeasurePlugin.h"
#include "Rainmeter.h"
#include "Export.h"
#include "System.h"
#include "Error.h"
/*
** The constructor
**
*/
MeasurePlugin::MeasurePlugin(MeterWindow* meterWindow, const WCHAR* name) : Measure(meterWindow, name),
m_Plugin(),
m_ReloadFunc(),
m_ID(),
m_Update2(false),
m_PluginData(),
m_UpdateFunc(),
m_GetStringFunc(),
m_ExecuteBangFunc()
{
}
/*
** The destructor
**
*/
MeasurePlugin::~MeasurePlugin()
{
if (m_Plugin)
{
FARPROC finalizeFunc = GetProcAddress(m_Plugin, "Finalize");
if (finalizeFunc)
{
if (IsNewApi())
{
((NEWFINALIZE)finalizeFunc)(m_PluginData);
}
else
{
((FINALIZE)finalizeFunc)(m_Plugin, m_ID);
}
}
FreeLibrary(m_Plugin);
}
}
/*
** Gets the current value from the plugin
**
*/
void MeasurePlugin::UpdateValue()
{
if (m_UpdateFunc)
{
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
System::ResetWorkingDirectory();
}
}
/*
** Reads the options and loads the plugin
**
*/
void MeasurePlugin::ReadOptions(ConfigParser& parser, const WCHAR* section)
{
static UINT id = 0;
Measure::ReadOptions(parser, section);
if (m_Initialized)
{
if (IsNewApi())
{
((NEWRELOAD)m_ReloadFunc)(m_PluginData, this, &m_MaxValue);
}
// DynamicVariables doesn't work with old plugins
return;
}
const std::wstring& plugin = parser.ReadString(section, L"Plugin", L"");
size_t pos = plugin.find_last_of(L"\\/");
std::wstring pluginName;
if (pos != std::wstring::npos)
{
pluginName.assign(plugin, pos, plugin.length() - pos);
}
else
{
pluginName = plugin;
}
// First try from program path
std::wstring pluginFile = GetRainmeter().GetPluginPath();
pluginFile += pluginName;
m_Plugin = System::RmLoadLibrary(pluginFile.c_str());
if (!m_Plugin)
{
if (GetRainmeter().HasUserPluginPath())
{
// Try from settings path
pluginFile = GetRainmeter().GetUserPluginPath();
pluginFile += pluginName;
m_Plugin = System::RmLoadLibrary(pluginFile.c_str());
}
if (!m_Plugin)
{
LogErrorF(
this, L"Plugin: Unable to load \"%s\" (error %ld)",
pluginName.c_str(), GetLastError());
return;
}
}
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");
// Remove current directory from DLL search path
SetDllDirectory(L"");
double maxValue = 0.0;
if (IsNewApi())
{
m_PluginData = (void*)id;
if (initializeFunc)
{
((NEWINITIALIZE)initializeFunc)(&m_PluginData, this);
}
((NEWRELOAD)m_ReloadFunc)(m_PluginData, this, &maxValue);
}
else
{
m_ID = id;
if (!m_UpdateFunc)
{
m_UpdateFunc = GetProcAddress(m_Plugin, "Update2");
m_Update2 = true;
}
if (initializeFunc)
{
maxValue = ((INITIALIZE)initializeFunc)(m_Plugin, m_MeterWindow->GetFilePath().c_str(), section, m_ID);
}
}
const std::wstring& szMaxValue = parser.ReadString(section, L"MaxValue", L"");
if (szMaxValue.empty())
{
if (maxValue == 0.0)
{
m_MaxValue = 1.0;
m_LogMaxValue = true;
m_MedianValues.clear();
}
else
{
m_MaxValue = maxValue;
m_LogMaxValue = false;
}
}
// Reset to default
SetDllDirectory(L"");
System::ResetWorkingDirectory();
++id;
}
/*
** Gets the string value from the plugin.
**
*/
const WCHAR* MeasurePlugin::GetStringValue()
{
if (m_GetStringFunc)
{
const WCHAR* ret;
if (IsNewApi())
{
ret = ((NEWGETSTRING)m_GetStringFunc)(m_PluginData);
}
else
{
ret = ((GETSTRING)m_GetStringFunc)(m_ID, 0);
}
if (ret) return CheckSubstitute(ret);
}
return nullptr;
}
/*
** Sends a bang to the plugin
**
*/
void MeasurePlugin::Command(const std::wstring& command)
{
if (m_ExecuteBangFunc)
{
const WCHAR* str = command.c_str();
if (IsNewApi())
{
((NEWEXECUTEBANG)m_ExecuteBangFunc)(m_PluginData, str);
}
else
{
((EXECUTEBANG)m_ExecuteBangFunc)(str, m_ID);
}
}
else
{
Measure::Command(command);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,330 +1,330 @@
/*
Copyright (C) 2005 Kimmo Pekkola
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "MeterButton.h"
#include "Measure.h"
#include "Rainmeter.h"
#include "Error.h"
#include "../Common/Gfx/Canvas.h"
using namespace Gdiplus;
enum BUTTON_STATE
{
BUTTON_STATE_NORMAL,
BUTTON_STATE_DOWN,
BUTTON_STATE_HOVER
};
/*
** The constructor
**
*/
MeterButton::MeterButton(MeterWindow* meterWindow, const WCHAR* name) : Meter(meterWindow, name),
m_Image(L"ButtonImage", nullptr, true, meterWindow),
m_NeedsReload(false),
m_Bitmaps(),
m_State(BUTTON_STATE_NORMAL),
m_Clicked(false),
m_Focus(false)
{
}
/*
** The destructor
**
*/
MeterButton::~MeterButton()
{
for (int i = 0; i < BUTTON_FRAMES; ++i)
{
delete m_Bitmaps[i];
}
}
/*
** Load the image and get the dimensions of the meter from it.
**
*/
void MeterButton::Initialize()
{
Meter::Initialize();
for (int i = 0; i < BUTTON_FRAMES; ++i)
{
delete m_Bitmaps[i];
m_Bitmaps[i] = nullptr;
}
// Load the bitmaps if defined
if (!m_ImageName.empty())
{
m_Image.LoadImage(m_ImageName, m_NeedsReload);
if (m_Image.IsLoaded())
{
Bitmap* bitmap = m_Image.GetImage();
int bitmapW = bitmap->GetWidth();
int bitmapH = bitmap->GetHeight();
m_W = bitmapW;
m_H = bitmapH;
if (m_H > m_W)
{
m_H /= BUTTON_FRAMES;
}
else
{
m_W /= BUTTON_FRAMES;
}
// Separate the frames
for (int i = 0; i < BUTTON_FRAMES; ++i)
{
Bitmap bitmapPart(m_W, m_H, PixelFormat32bppPARGB);
Graphics graphics(&bitmapPart);
Rect r(0, 0, m_W, m_H);
if (bitmapH > bitmapW)
{
graphics.DrawImage(bitmap, r, 0, m_H * i, m_W, m_H, UnitPixel);
}
else
{
graphics.DrawImage(bitmap, r, m_W * i, 0, m_W, m_H, UnitPixel);
}
m_Bitmaps[i] = new CachedBitmap(&bitmapPart, &graphics);
}
m_W += GetWidthPadding();
m_H += GetHeightPadding();
}
}
else if (m_Image.IsLoaded())
{
m_Image.DisposeImage();
}
}
/*
** Read the options specified in the ini file.
**
*/
void MeterButton::ReadOptions(ConfigParser& parser, const WCHAR* section)
{
// Store the current values so we know if the image needs to be updated
std::wstring oldImageName = m_ImageName;
int oldW = m_W;
int oldH = m_H;
Meter::ReadOptions(parser, section);
m_ImageName = parser.ReadString(section, L"ButtonImage", L"");
if (!m_ImageName.empty())
{
// Read tinting options
m_Image.ReadOptions(parser, section);
}
else
{
m_Image.ClearOptionFlags();
}
m_Command = parser.ReadString(section, L"ButtonCommand", L"", false);
if (m_Initialized)
{
m_NeedsReload = (wcscmp(oldImageName.c_str(), m_ImageName.c_str()) != 0);
if (m_NeedsReload ||
m_Image.IsOptionsChanged())
{
Initialize(); // Reload the image
}
else
{
// Reset to old dimensions
m_W = oldW;
m_H = oldH;
}
}
}
/*
** Updates the value(s) from the measures.
**
*/
bool MeterButton::Update()
{
return Meter::Update();
}
/*
** Draws the meter on the double buffer
**
*/
bool MeterButton::Draw(Gfx::Canvas& canvas)
{
if (!Meter::Draw(canvas)) return false;
if (m_Bitmaps[m_State] == nullptr) return false; // Unable to continue
Gdiplus::Graphics& graphics = canvas.BeginGdiplusContext();
Gdiplus::Rect meterRect = GetMeterRectPadding();
// Blit the image
graphics.DrawCachedBitmap(m_Bitmaps[m_State], meterRect.X, meterRect.Y);
canvas.EndGdiplusContext();
return true;
}
/*
** Overridden method. The meters need not to be bound on anything
**
*/
void MeterButton::BindMeasures(ConfigParser& parser, const WCHAR* section)
{
BindPrimaryMeasure(parser, section, true);
}
/*
** Checks if the given point is inside the button.
**
*/
bool MeterButton::HitTest2(int px, int py)
{
int x = GetX();
int y = GetY();
if (m_MouseOver &&
px >= x && px < x + m_W &&
py >= y && py < y + m_H)
{
if (m_SolidColor.GetA() != 0 || m_SolidColor2.GetA() != 0)
{
return true;
}
// Check transparent pixels
if (m_Image.IsLoaded())
{
Rect meterRect = GetMeterRectPadding();
int ix = meterRect.Width * m_State;
px = px - meterRect.X + ix;
py = py - meterRect.Y;
if (px >= ix && px < ix + meterRect.Width &&
py >= 0 && py < meterRect.Height)
{
Color color;
Status status = m_Image.GetImage()->GetPixel(px, py, &color);
if (status != Ok || color.GetA() != 0)
{
return true;
}
}
}
else
{
return true;
}
}
return false;
}
bool MeterButton::MouseUp(POINT pos, bool execute)
{
if (m_State == BUTTON_STATE_DOWN)
{
if (execute && m_Clicked && m_Focus && HitTest2(pos.x, pos.y))
{
Rainmeter::GetInstance().ExecuteCommand(m_Command.c_str(), m_MeterWindow);
}
m_State = BUTTON_STATE_NORMAL;
m_Clicked = false;
return true;
}
m_Clicked = false;
return false;
}
bool MeterButton::MouseDown(POINT pos)
{
if (m_Focus && HitTest2(pos.x, pos.y))
{
m_State = BUTTON_STATE_DOWN;
m_Clicked = true;
return true;
}
return false;
}
bool MeterButton::MouseMove(POINT pos)
{
if (m_Clicked)
{
if (HitTest2(pos.x, pos.y))
{
if (m_State == BUTTON_STATE_NORMAL)
{
m_State = BUTTON_STATE_DOWN;
return true;
}
}
else
{
// If the left button is not down anymore the clicked state needs to be set false
if (!IsLButtonDown())
{
m_Clicked = false;
}
if (m_State == BUTTON_STATE_DOWN)
{
m_State = BUTTON_STATE_NORMAL;
return true;
}
}
}
else
{
if (HitTest2(pos.x, pos.y))
{
if (m_State == BUTTON_STATE_NORMAL)
{
m_State = BUTTON_STATE_HOVER;
return true;
}
}
else
{
if (m_State == BUTTON_STATE_HOVER)
{
m_State = BUTTON_STATE_NORMAL;
return true;
}
}
}
return false;
}
/*
Copyright (C) 2005 Kimmo Pekkola
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "MeterButton.h"
#include "Measure.h"
#include "Rainmeter.h"
#include "Error.h"
#include "../Common/Gfx/Canvas.h"
using namespace Gdiplus;
enum BUTTON_STATE
{
BUTTON_STATE_NORMAL,
BUTTON_STATE_DOWN,
BUTTON_STATE_HOVER
};
/*
** The constructor
**
*/
MeterButton::MeterButton(MeterWindow* meterWindow, const WCHAR* name) : Meter(meterWindow, name),
m_Image(L"ButtonImage", nullptr, true, meterWindow),
m_NeedsReload(false),
m_Bitmaps(),
m_State(BUTTON_STATE_NORMAL),
m_Clicked(false),
m_Focus(false)
{
}
/*
** The destructor
**
*/
MeterButton::~MeterButton()
{
for (int i = 0; i < BUTTON_FRAMES; ++i)
{
delete m_Bitmaps[i];
}
}
/*
** Load the image and get the dimensions of the meter from it.
**
*/
void MeterButton::Initialize()
{
Meter::Initialize();
for (int i = 0; i < BUTTON_FRAMES; ++i)
{
delete m_Bitmaps[i];
m_Bitmaps[i] = nullptr;
}
// Load the bitmaps if defined
if (!m_ImageName.empty())
{
m_Image.LoadImage(m_ImageName, m_NeedsReload);
if (m_Image.IsLoaded())
{
Bitmap* bitmap = m_Image.GetImage();
int bitmapW = bitmap->GetWidth();
int bitmapH = bitmap->GetHeight();
m_W = bitmapW;
m_H = bitmapH;
if (m_H > m_W)
{
m_H /= BUTTON_FRAMES;
}
else
{
m_W /= BUTTON_FRAMES;
}
// Separate the frames
for (int i = 0; i < BUTTON_FRAMES; ++i)
{
Bitmap bitmapPart(m_W, m_H, PixelFormat32bppPARGB);
Graphics graphics(&bitmapPart);
Rect r(0, 0, m_W, m_H);
if (bitmapH > bitmapW)
{
graphics.DrawImage(bitmap, r, 0, m_H * i, m_W, m_H, UnitPixel);
}
else
{
graphics.DrawImage(bitmap, r, m_W * i, 0, m_W, m_H, UnitPixel);
}
m_Bitmaps[i] = new CachedBitmap(&bitmapPart, &graphics);
}
m_W += GetWidthPadding();
m_H += GetHeightPadding();
}
}
else if (m_Image.IsLoaded())
{
m_Image.DisposeImage();
}
}
/*
** Read the options specified in the ini file.
**
*/
void MeterButton::ReadOptions(ConfigParser& parser, const WCHAR* section)
{
// Store the current values so we know if the image needs to be updated
std::wstring oldImageName = m_ImageName;
int oldW = m_W;
int oldH = m_H;
Meter::ReadOptions(parser, section);
m_ImageName = parser.ReadString(section, L"ButtonImage", L"");
if (!m_ImageName.empty())
{
// Read tinting options
m_Image.ReadOptions(parser, section);
}
else
{
m_Image.ClearOptionFlags();
}
m_Command = parser.ReadString(section, L"ButtonCommand", L"", false);
if (m_Initialized)
{
m_NeedsReload = (wcscmp(oldImageName.c_str(), m_ImageName.c_str()) != 0);
if (m_NeedsReload ||
m_Image.IsOptionsChanged())
{
Initialize(); // Reload the image
}
else
{
// Reset to old dimensions
m_W = oldW;
m_H = oldH;
}
}
}
/*
** Updates the value(s) from the measures.
**
*/
bool MeterButton::Update()
{
return Meter::Update();
}
/*
** Draws the meter on the double buffer
**
*/
bool MeterButton::Draw(Gfx::Canvas& canvas)
{
if (!Meter::Draw(canvas)) return false;
if (m_Bitmaps[m_State] == nullptr) return false; // Unable to continue
Gdiplus::Graphics& graphics = canvas.BeginGdiplusContext();
Gdiplus::Rect meterRect = GetMeterRectPadding();
// Blit the image
graphics.DrawCachedBitmap(m_Bitmaps[m_State], meterRect.X, meterRect.Y);
canvas.EndGdiplusContext();
return true;
}
/*
** Overridden method. The meters need not to be bound on anything
**
*/
void MeterButton::BindMeasures(ConfigParser& parser, const WCHAR* section)
{
BindPrimaryMeasure(parser, section, true);
}
/*
** Checks if the given point is inside the button.
**
*/
bool MeterButton::HitTest2(int px, int py)
{
int x = GetX();
int y = GetY();
if (m_MouseOver &&
px >= x && px < x + m_W &&
py >= y && py < y + m_H)
{
if (m_SolidColor.GetA() != 0 || m_SolidColor2.GetA() != 0)
{
return true;
}
// Check transparent pixels
if (m_Image.IsLoaded())
{
Rect meterRect = GetMeterRectPadding();
int ix = meterRect.Width * m_State;
px = px - meterRect.X + ix;
py = py - meterRect.Y;
if (px >= ix && px < ix + meterRect.Width &&
py >= 0 && py < meterRect.Height)
{
Color color;
Status status = m_Image.GetImage()->GetPixel(px, py, &color);
if (status != Ok || color.GetA() != 0)
{
return true;
}
}
}
else
{
return true;
}
}
return false;
}
bool MeterButton::MouseUp(POINT pos, bool execute)
{
if (m_State == BUTTON_STATE_DOWN)
{
if (execute && m_Clicked && m_Focus && HitTest2(pos.x, pos.y))
{
GetRainmeter().ExecuteCommand(m_Command.c_str(), m_MeterWindow);
}
m_State = BUTTON_STATE_NORMAL;
m_Clicked = false;
return true;
}
m_Clicked = false;
return false;
}
bool MeterButton::MouseDown(POINT pos)
{
if (m_Focus && HitTest2(pos.x, pos.y))
{
m_State = BUTTON_STATE_DOWN;
m_Clicked = true;
return true;
}
return false;
}
bool MeterButton::MouseMove(POINT pos)
{
if (m_Clicked)
{
if (HitTest2(pos.x, pos.y))
{
if (m_State == BUTTON_STATE_NORMAL)
{
m_State = BUTTON_STATE_DOWN;
return true;
}
}
else
{
// If the left button is not down anymore the clicked state needs to be set false
if (!IsLButtonDown())
{
m_Clicked = false;
}
if (m_State == BUTTON_STATE_DOWN)
{
m_State = BUTTON_STATE_NORMAL;
return true;
}
}
}
else
{
if (HitTest2(pos.x, pos.y))
{
if (m_State == BUTTON_STATE_NORMAL)
{
m_State = BUTTON_STATE_HOVER;
return true;
}
}
else
{
if (m_State == BUTTON_STATE_HOVER)
{
m_State = BUTTON_STATE_NORMAL;
return true;
}
}
}
return false;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,285 +1,286 @@
/*
Copyright (C) 2001 Kimmo Pekkola
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __RAINMETER_H__
#define __RAINMETER_H__
#include <windows.h>
#include <map>
#include <vector>
#include <list>
#include <string>
#include "CommandHandler.h"
#include "ContextMenu.h"
#include "Logger.h"
#include "MeterWindow.h"
#include "SkinRegistry.h"
#define MAX_LINE_LENGTH 4096
#define APPNAME L"Rainmeter"
#ifdef _WIN64
#define APPBITS L"64-bit"
#else
#define APPBITS L"32-bit"
#endif
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define APPDATE WIDEN(__DATE__)
#define RAINMETER_CLASS_NAME L"DummyRainWClass"
#define RAINMETER_WINDOW_NAME L"Rainmeter control window"
#define WM_RAINMETER_DELAYED_REFRESH_ALL WM_APP + 0
#define WM_RAINMETER_DELAYED_EXECUTE WM_APP + 1
#define WM_RAINMETER_EXECUTE WM_APP + 2
struct GlobalOptions
{
double netInSpeed;
double netOutSpeed;
};
class ConfigParser;
class TrayWindow;
class Rainmeter
{
public:
static Rainmeter& GetInstance();
int Initialize(LPCWSTR iniPath, LPCWSTR layout);
void Finalize();
int MessagePump();
void SetNetworkStatisticsTimer();
ConfigParser* GetCurrentParser() { return m_CurrentParser; }
void SetCurrentParser(ConfigParser* parser) { m_CurrentParser = parser; }
TrayWindow* GetTrayWindow() { return m_TrayWindow; }
bool HasMeterWindow(const MeterWindow* meterWindow) const;
MeterWindow* GetMeterWindow(const std::wstring& folderPath);
MeterWindow* GetMeterWindowByINI(const std::wstring& ini_searching);
MeterWindow* GetMeterWindow(HWND hwnd);
void GetMeterWindowsByLoadOrder(std::multimap<int, MeterWindow*>& windows, const std::wstring& group = std::wstring());
std::map<std::wstring, MeterWindow*>& GetAllMeterWindows() { return m_MeterWindows; }
const std::vector<std::wstring>& GetAllLayouts() { return m_Layouts; }
void RemoveMeterWindow(MeterWindow* meterWindow);
void AddUnmanagedMeterWindow(MeterWindow* meterWindow);
void RemoveUnmanagedMeterWindow(MeterWindow* meterWindow);
bool ActivateSkin(const std::wstring& folderPath);
bool ActivateSkin(const std::wstring& folderPath, const std::wstring& file);
void ActivateSkin(int folderIndex, int fileIndex);
void DeactivateSkin(MeterWindow* meterWindow, int folderIndex, bool save = true);
void ToggleSkin(int folderIndex, int fileIndex);
void ToggleSkinWithID(UINT id);
const std::wstring& GetPath() { return m_Path; }
const std::wstring& GetIniFile() { return m_IniFile; }
const std::wstring& GetDataFile() { return m_DataFile; }
const std::wstring& GetSettingsPath() { return m_SettingsPath; }
const std::wstring& GetSkinPath() { return m_SkinPath; }
void SetSkinPath(const std::wstring& skinPath);
std::wstring GetLayoutPath() { return m_SettingsPath + L"Layouts\\"; }
std::wstring GetPluginPath() { return m_Path + L"Plugins\\"; }
std::wstring GetUserPluginPath() { return m_SettingsPath + L"Plugins\\"; }
std::wstring GetAddonPath() { return m_SettingsPath + L"Addons\\"; }
bool HasUserPluginPath() { return (_wcsicmp(m_Path.c_str(), m_SettingsPath.c_str()) != 0); }
std::wstring GetDefaultSkinPath() { return m_Path + L"Defaults\\Skins\\"; }
std::wstring GetDefaultLayoutPath() { return m_Path + L"Defaults\\Layouts\\"; }
std::wstring GetDefaultPluginPath() { return m_Path + L"Defaults\\Plugins\\"; }
std::wstring GetDefaultAddonPath() { return m_Path + L"Defaults\\Addons\\"; }
const std::wstring& GetDrive() { return m_Drive; }
const std::wstring& GetSkinEditor() { return m_SkinEditor; }
void SetSkinEditor(const std::wstring& path);
const std::wstring& GetStatsDate() { return m_StatsDate; }
HWND GetWindow() { return m_Window; }
HINSTANCE GetModuleInstance() { return m_Instance; }
HINSTANCE GetResourceInstance() { return m_ResourceInstance; }
LCID GetResourceLCID() { return m_ResourceLCID; }
bool GetUseD2D() const { return m_UseD2D; }
void SetUseD2D(bool enabled);
bool GetDebug() { return m_Debug; }
GlobalOptions& GetGlobalOptions() { return m_GlobalOptions; }
void ReloadSettings();
void EditSettings();
void EditSkinFile(const std::wstring& name, const std::wstring& iniFile);
void OpenSkinFolder(const std::wstring& name = std::wstring());
void UpdateStats();
void ReadStats();
void WriteStats(bool bForce);
void ResetStats();
bool GetDisableVersionCheck() { return m_DisableVersionCheck; }
void SetDisableVersionCheck(bool check);
bool GetNewVersion() { return m_NewVersion; }
void SetNewVersion() { m_NewVersion = true; }
void ShowLogFile();
bool GetDisableRDP() { return m_DisableRDP; }
bool IsRedrawable() { return (!GetDisableRDP() || !GetSystemMetrics(SM_REMOTESESSION)); }
bool GetDisableDragging() { return m_DisableDragging; }
void SetDisableDragging(bool dragging);
bool IsNormalStayDesktop() { return m_NormalStayDesktop; }
void SetDebug(bool debug);
int ShowMessage(HWND parent, const WCHAR* text, UINT type);
bool IsMenuActive() { return m_ContextMenu.IsMenuActive(); }
void ShowContextMenu(POINT pos, MeterWindow* mw) { return m_ContextMenu.ShowMenu(pos, mw); }
void ShowSkinCustomContextMenu(POINT pos, MeterWindow* mw) { return m_ContextMenu.ShowSkinCustomMenu(pos, mw); }
const std::wstring& GetTrayExecuteR() { return m_TrayExecuteR; }
const std::wstring& GetTrayExecuteM() { return m_TrayExecuteM; }
const std::wstring& GetTrayExecuteDR() { return m_TrayExecuteDR; }
const std::wstring& GetTrayExecuteDM() { return m_TrayExecuteDM; }
void ExecuteBang(const WCHAR* bang, std::vector<std::wstring>& args, MeterWindow* meterWindow);
void ExecuteCommand(const WCHAR* command, MeterWindow* meterWindow, bool multi = true);
void DelayedExecuteCommand(const WCHAR* command);
void RefreshAll();
bool LoadLayout(const std::wstring& name);
void PreserveSetting(const std::wstring& from, LPCTSTR key, bool replace = true);
friend class CommandHandler;
friend class ContextMenu;
friend class DialogManage;
private:
Rainmeter();
~Rainmeter();
Rainmeter(const Rainmeter& other) = delete;
Rainmeter& operator=(Rainmeter other) = delete;
static LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void ActivateActiveSkins();
void CreateMeterWindow(const std::wstring& folderPath, const std::wstring& file);
void DeleteAllMeterWindows();
void DeleteAllUnmanagedMeterWindows();
void WriteActive(const std::wstring& folderPath, int fileIndex);
void ScanForSkins();
void ScanForLayouts();
void ReadGeneralSettings(const std::wstring& iniFile);
void SetLoadOrder(int folderIndex, int order);
int GetLoadOrder(const std::wstring& folderPath);
void UpdateDesktopWorkArea(bool reset);
void CreateOptionsFile();
void CreateDataFile();
void CreateComponentFolders(bool defaultIniLocation);
void TestSettingsFile(bool bDefaultIniLocation);
TrayWindow* m_TrayWindow;
std::multimap<int, int> m_SkinOrders;
std::map<std::wstring, MeterWindow*> m_MeterWindows;
std::list<MeterWindow*> m_UnmanagedMeterWindows;
std::vector<std::wstring> m_Layouts;
std::wstring m_Path;
std::wstring m_IniFile;
std::wstring m_DataFile;
std::wstring m_StatsFile;
std::wstring m_SettingsPath;
std::wstring m_SkinPath;
std::wstring m_Drive;
std::wstring m_StatsDate;
std::wstring m_TrayExecuteR;
std::wstring m_TrayExecuteM;
std::wstring m_TrayExecuteDR;
std::wstring m_TrayExecuteDM;
bool m_UseD2D;
bool m_Debug;
bool m_DisableVersionCheck;
bool m_NewVersion;
bool m_DesktopWorkAreaChanged;
bool m_DesktopWorkAreaType;
std::map<UINT, RECT> m_DesktopWorkAreas;
std::vector<RECT> m_OldDesktopWorkAreas;
bool m_NormalStayDesktop;
bool m_DisableRDP;
bool m_DisableDragging;
std::wstring m_SkinEditor;
CommandHandler m_CommandHandler;
ContextMenu m_ContextMenu;
SkinRegistry m_SkinRegistry;
ConfigParser* m_CurrentParser;
HWND m_Window;
HANDLE m_Mutex;
HINSTANCE m_Instance;
HMODULE m_ResourceInstance;
LCID m_ResourceLCID;
ULONG_PTR m_GDIplusToken;
GlobalOptions m_GlobalOptions;
};
#ifdef LIBRARY_EXPORTS
#define EXPORT_PLUGIN EXTERN_C __declspec(dllexport)
#else
#define EXPORT_PLUGIN EXTERN_C __declspec(dllimport)
#endif
EXPORT_PLUGIN int RainmeterMain(LPWSTR cmdLine);
EXPORT_PLUGIN void* Rainmeter_Initialize();
EXPORT_PLUGIN void Rainmeter_Finalize(void* ptr);
#endif
/*
Copyright (C) 2001 Kimmo Pekkola
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __RAINMETER_H__
#define __RAINMETER_H__
#include <windows.h>
#include <map>
#include <vector>
#include <list>
#include <string>
#include "CommandHandler.h"
#include "ContextMenu.h"
#include "Logger.h"
#include "MeterWindow.h"
#include "SkinRegistry.h"
#define MAX_LINE_LENGTH 4096
#define APPNAME L"Rainmeter"
#ifdef _WIN64
#define APPBITS L"64-bit"
#else
#define APPBITS L"32-bit"
#endif
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
#define APPDATE WIDEN(__DATE__)
#define RAINMETER_CLASS_NAME L"DummyRainWClass"
#define RAINMETER_WINDOW_NAME L"Rainmeter control window"
#define WM_RAINMETER_DELAYED_REFRESH_ALL WM_APP + 0
#define WM_RAINMETER_DELAYED_EXECUTE WM_APP + 1
#define WM_RAINMETER_EXECUTE WM_APP + 2
struct GlobalOptions
{
double netInSpeed;
double netOutSpeed;
};
class ConfigParser;
class TrayWindow;
class Rainmeter
{
public:
static Rainmeter& GetInstance();
int Initialize(LPCWSTR iniPath, LPCWSTR layout);
void Finalize();
int MessagePump();
void SetNetworkStatisticsTimer();
ConfigParser* GetCurrentParser() { return m_CurrentParser; }
void SetCurrentParser(ConfigParser* parser) { m_CurrentParser = parser; }
TrayWindow* GetTrayWindow() { return m_TrayWindow; }
bool HasMeterWindow(const MeterWindow* meterWindow) const;
MeterWindow* GetMeterWindow(const std::wstring& folderPath);
MeterWindow* GetMeterWindowByINI(const std::wstring& ini_searching);
MeterWindow* GetMeterWindow(HWND hwnd);
void GetMeterWindowsByLoadOrder(std::multimap<int, MeterWindow*>& windows, const std::wstring& group = std::wstring());
std::map<std::wstring, MeterWindow*>& GetAllMeterWindows() { return m_MeterWindows; }
const std::vector<std::wstring>& GetAllLayouts() { return m_Layouts; }
void RemoveMeterWindow(MeterWindow* meterWindow);
void AddUnmanagedMeterWindow(MeterWindow* meterWindow);
void RemoveUnmanagedMeterWindow(MeterWindow* meterWindow);
bool ActivateSkin(const std::wstring& folderPath);
bool ActivateSkin(const std::wstring& folderPath, const std::wstring& file);
void ActivateSkin(int folderIndex, int fileIndex);
void DeactivateSkin(MeterWindow* meterWindow, int folderIndex, bool save = true);
void ToggleSkin(int folderIndex, int fileIndex);
void ToggleSkinWithID(UINT id);
const std::wstring& GetPath() { return m_Path; }
const std::wstring& GetIniFile() { return m_IniFile; }
const std::wstring& GetDataFile() { return m_DataFile; }
const std::wstring& GetSettingsPath() { return m_SettingsPath; }
const std::wstring& GetSkinPath() { return m_SkinPath; }
void SetSkinPath(const std::wstring& skinPath);
std::wstring GetLayoutPath() { return m_SettingsPath + L"Layouts\\"; }
std::wstring GetPluginPath() { return m_Path + L"Plugins\\"; }
std::wstring GetUserPluginPath() { return m_SettingsPath + L"Plugins\\"; }
std::wstring GetAddonPath() { return m_SettingsPath + L"Addons\\"; }
bool HasUserPluginPath() { return (_wcsicmp(m_Path.c_str(), m_SettingsPath.c_str()) != 0); }
std::wstring GetDefaultSkinPath() { return m_Path + L"Defaults\\Skins\\"; }
std::wstring GetDefaultLayoutPath() { return m_Path + L"Defaults\\Layouts\\"; }
std::wstring GetDefaultPluginPath() { return m_Path + L"Defaults\\Plugins\\"; }
std::wstring GetDefaultAddonPath() { return m_Path + L"Defaults\\Addons\\"; }
const std::wstring& GetDrive() { return m_Drive; }
const std::wstring& GetSkinEditor() { return m_SkinEditor; }
void SetSkinEditor(const std::wstring& path);
const std::wstring& GetStatsDate() { return m_StatsDate; }
HWND GetWindow() { return m_Window; }
HINSTANCE GetModuleInstance() { return m_Instance; }
HINSTANCE GetResourceInstance() { return m_ResourceInstance; }
LCID GetResourceLCID() { return m_ResourceLCID; }
bool GetUseD2D() const { return m_UseD2D; }
void SetUseD2D(bool enabled);
bool GetDebug() { return m_Debug; }
GlobalOptions& GetGlobalOptions() { return m_GlobalOptions; }
void ReloadSettings();
void EditSettings();
void EditSkinFile(const std::wstring& name, const std::wstring& iniFile);
void OpenSkinFolder(const std::wstring& name = std::wstring());
void UpdateStats();
void ReadStats();
void WriteStats(bool bForce);
void ResetStats();
bool GetDisableVersionCheck() { return m_DisableVersionCheck; }
void SetDisableVersionCheck(bool check);
bool GetNewVersion() { return m_NewVersion; }
void SetNewVersion() { m_NewVersion = true; }
void ShowLogFile();
bool GetDisableRDP() { return m_DisableRDP; }
bool IsRedrawable() { return (!GetDisableRDP() || !GetSystemMetrics(SM_REMOTESESSION)); }
bool GetDisableDragging() { return m_DisableDragging; }
void SetDisableDragging(bool dragging);
bool IsNormalStayDesktop() { return m_NormalStayDesktop; }
void SetDebug(bool debug);
int ShowMessage(HWND parent, const WCHAR* text, UINT type);
bool IsMenuActive() { return m_ContextMenu.IsMenuActive(); }
void ShowContextMenu(POINT pos, MeterWindow* mw) { return m_ContextMenu.ShowMenu(pos, mw); }
void ShowSkinCustomContextMenu(POINT pos, MeterWindow* mw) { return m_ContextMenu.ShowSkinCustomMenu(pos, mw); }
const std::wstring& GetTrayExecuteR() { return m_TrayExecuteR; }
const std::wstring& GetTrayExecuteM() { return m_TrayExecuteM; }
const std::wstring& GetTrayExecuteDR() { return m_TrayExecuteDR; }
const std::wstring& GetTrayExecuteDM() { return m_TrayExecuteDM; }
void ExecuteBang(const WCHAR* bang, std::vector<std::wstring>& args, MeterWindow* meterWindow);
void ExecuteCommand(const WCHAR* command, MeterWindow* meterWindow, bool multi = true);
void DelayedExecuteCommand(const WCHAR* command);
void RefreshAll();
bool LoadLayout(const std::wstring& name);
void PreserveSetting(const std::wstring& from, LPCTSTR key, bool replace = true);
friend class CommandHandler;
friend class ContextMenu;
friend class DialogManage;
private:
Rainmeter();
~Rainmeter();
Rainmeter(const Rainmeter& other) = delete;
Rainmeter& operator=(Rainmeter other) = delete;
static LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void ActivateActiveSkins();
void CreateMeterWindow(const std::wstring& folderPath, const std::wstring& file);
void DeleteAllMeterWindows();
void DeleteAllUnmanagedMeterWindows();
void WriteActive(const std::wstring& folderPath, int fileIndex);
void ScanForSkins();
void ScanForLayouts();
void ReadGeneralSettings(const std::wstring& iniFile);
void SetLoadOrder(int folderIndex, int order);
int GetLoadOrder(const std::wstring& folderPath);
void UpdateDesktopWorkArea(bool reset);
void CreateOptionsFile();
void CreateDataFile();
void CreateComponentFolders(bool defaultIniLocation);
void TestSettingsFile(bool bDefaultIniLocation);
TrayWindow* m_TrayWindow;
std::multimap<int, int> m_SkinOrders;
std::map<std::wstring, MeterWindow*> m_MeterWindows;
std::list<MeterWindow*> m_UnmanagedMeterWindows;
std::vector<std::wstring> m_Layouts;
std::wstring m_Path;
std::wstring m_IniFile;
std::wstring m_DataFile;
std::wstring m_StatsFile;
std::wstring m_SettingsPath;
std::wstring m_SkinPath;
std::wstring m_Drive;
std::wstring m_StatsDate;
std::wstring m_TrayExecuteR;
std::wstring m_TrayExecuteM;
std::wstring m_TrayExecuteDR;
std::wstring m_TrayExecuteDM;
bool m_UseD2D;
bool m_Debug;
bool m_DisableVersionCheck;
bool m_NewVersion;
bool m_DesktopWorkAreaChanged;
bool m_DesktopWorkAreaType;
std::map<UINT, RECT> m_DesktopWorkAreas;
std::vector<RECT> m_OldDesktopWorkAreas;
bool m_NormalStayDesktop;
bool m_DisableRDP;
bool m_DisableDragging;
std::wstring m_SkinEditor;
CommandHandler m_CommandHandler;
ContextMenu m_ContextMenu;
SkinRegistry m_SkinRegistry;
ConfigParser* m_CurrentParser;
HWND m_Window;
HANDLE m_Mutex;
HINSTANCE m_Instance;
HMODULE m_ResourceInstance;
LCID m_ResourceLCID;
ULONG_PTR m_GDIplusToken;
GlobalOptions m_GlobalOptions;
};
// Convenience function.
inline Rainmeter& GetRainmeter() { return Rainmeter::GetInstance(); }
#ifdef LIBRARY_EXPORTS
#define EXPORT_PLUGIN EXTERN_C
#else
#define EXPORT_PLUGIN EXTERN_C __declspec(dllimport)
#endif
EXPORT_PLUGIN int RainmeterMain(LPWSTR cmdLine);
#endif

View File

@ -1,87 +1,87 @@
/*
Copyright (C) 2013 spx
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Section.h"
#include "ConfigParser.h"
#include "Rainmeter.h"
/*
** The constructor
**
*/
Section::Section(MeterWindow* meterWindow, const WCHAR* name) : m_MeterWindow(meterWindow), m_Name(name),
m_DynamicVariables(false),
m_UpdateDivider(1),
m_UpdateCounter(1)
{
}
/*
** The destructor
**
*/
Section::~Section()
{
}
/*
** Read the common options specified in the ini file. The inherited classes must
** call this base implementation if they overwrite this method.
**
*/
void Section::ReadOptions(ConfigParser& parser, const WCHAR* section)
{
int updateDivider = parser.ReadInt(section, L"UpdateDivider", 1);
if (updateDivider != m_UpdateDivider)
{
m_UpdateCounter = m_UpdateDivider = updateDivider;
}
m_DynamicVariables = parser.ReadBool(section, L"DynamicVariables", false);
m_OnUpdateAction = parser.ReadString(section, L"OnUpdateAction", L"", false);
const std::wstring& group = parser.ReadString(section, L"Group", L"");
InitializeGroup(group);
}
/*
** Updates the counter value
**
*/
bool Section::UpdateCounter()
{
++m_UpdateCounter;
if (m_UpdateCounter < m_UpdateDivider) return false;
m_UpdateCounter = 0;
return true;
}
/*
** Execute OnUpdateAction if action is set
**
*/
void Section::DoUpdateAction()
{
if (!m_OnUpdateAction.empty())
{
Rainmeter::GetInstance().ExecuteCommand(m_OnUpdateAction.c_str(), m_MeterWindow);
}
}
/*
Copyright (C) 2013 spx
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Section.h"
#include "ConfigParser.h"
#include "Rainmeter.h"
/*
** The constructor
**
*/
Section::Section(MeterWindow* meterWindow, const WCHAR* name) : m_MeterWindow(meterWindow), m_Name(name),
m_DynamicVariables(false),
m_UpdateDivider(1),
m_UpdateCounter(1)
{
}
/*
** The destructor
**
*/
Section::~Section()
{
}
/*
** Read the common options specified in the ini file. The inherited classes must
** call this base implementation if they overwrite this method.
**
*/
void Section::ReadOptions(ConfigParser& parser, const WCHAR* section)
{
int updateDivider = parser.ReadInt(section, L"UpdateDivider", 1);
if (updateDivider != m_UpdateDivider)
{
m_UpdateCounter = m_UpdateDivider = updateDivider;
}
m_DynamicVariables = parser.ReadBool(section, L"DynamicVariables", false);
m_OnUpdateAction = parser.ReadString(section, L"OnUpdateAction", L"", false);
const std::wstring& group = parser.ReadString(section, L"Group", L"");
InitializeGroup(group);
}
/*
** Updates the counter value
**
*/
bool Section::UpdateCounter()
{
++m_UpdateCounter;
if (m_UpdateCounter < m_UpdateDivider) return false;
m_UpdateCounter = 0;
return true;
}
/*
** Execute OnUpdateAction if action is set
**
*/
void Section::DoUpdateAction()
{
if (!m_OnUpdateAction.empty())
{
GetRainmeter().ExecuteCommand(m_OnUpdateAction.c_str(), m_MeterWindow);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,97 +1,97 @@
/*
Copyright (C) 2004 Kimmo Pekkola
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Litestep.h"
#include "Rainmeter.h"
#include "TrayWindow.h"
#include "../Version.h"
void CheckVersion(void* dummy)
{
HINTERNET hRootHandle = InternetOpen(
L"Rainmeter",
INTERNET_OPEN_TYPE_PRECONFIG,
nullptr,
nullptr,
0);
if (hRootHandle == nullptr)
{
return;
}
HINTERNET hUrlDump = InternetOpenUrl(
hRootHandle, L"http://rainmeter.github.io/rainmeter/release", nullptr, 0, INTERNET_FLAG_RESYNCHRONIZE, 0);
if (hUrlDump)
{
DWORD dwSize;
char urlData[16] = {0};
if (InternetReadFile(hUrlDump, (LPVOID)urlData, sizeof(urlData) - 1, &dwSize))
{
auto parseVersion = [](const WCHAR* str)->int
{
int version = _wtoi(str) * 1000000;
const WCHAR* pos = wcschr(str, L'.');
if (pos)
{
++pos; // Skip .
version += _wtoi(pos) * 1000;
pos = wcschr(pos, '.');
if (pos)
{
++pos; // Skip .
version += _wtoi(pos);
}
}
return version;
};
std::wstring tmpSz = StringUtil::Widen(urlData);
const WCHAR* version = tmpSz.c_str();
int availableVersion = parseVersion(version);
if (availableVersion > RAINMETER_VERSION ||
(revision_beta && availableVersion == RAINMETER_VERSION))
{
Rainmeter::GetInstance().SetNewVersion();
WCHAR buffer[32];
const WCHAR* dataFile = Rainmeter::GetInstance().GetDataFile().c_str();
GetPrivateProfileString(L"Rainmeter", L"LastCheck", L"0", buffer, _countof(buffer), dataFile);
// Show tray notification only once per new version
int lastVersion = parseVersion(buffer);
if (availableVersion > lastVersion)
{
Rainmeter::GetInstance().GetTrayWindow()->ShowUpdateNotification(version);
WritePrivateProfileString(L"Rainmeter", L"LastCheck", version, dataFile);
}
}
}
InternetCloseHandle(hUrlDump);
}
InternetCloseHandle(hRootHandle);
}
void CheckUpdate()
{
_beginthread(CheckVersion, 0, nullptr);
}
/*
Copyright (C) 2004 Kimmo Pekkola
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Litestep.h"
#include "Rainmeter.h"
#include "TrayWindow.h"
#include "../Version.h"
void CheckVersion(void* dummy)
{
HINTERNET hRootHandle = InternetOpen(
L"Rainmeter",
INTERNET_OPEN_TYPE_PRECONFIG,
nullptr,
nullptr,
0);
if (hRootHandle == nullptr)
{
return;
}
HINTERNET hUrlDump = InternetOpenUrl(
hRootHandle, L"http://rainmeter.github.io/rainmeter/release", nullptr, 0, INTERNET_FLAG_RESYNCHRONIZE, 0);
if (hUrlDump)
{
DWORD dwSize;
char urlData[16] = {0};
if (InternetReadFile(hUrlDump, (LPVOID)urlData, sizeof(urlData) - 1, &dwSize))
{
auto parseVersion = [](const WCHAR* str)->int
{
int version = _wtoi(str) * 1000000;
const WCHAR* pos = wcschr(str, L'.');
if (pos)
{
++pos; // Skip .
version += _wtoi(pos) * 1000;
pos = wcschr(pos, '.');
if (pos)
{
++pos; // Skip .
version += _wtoi(pos);
}
}
return version;
};
std::wstring tmpSz = StringUtil::Widen(urlData);
const WCHAR* version = tmpSz.c_str();
int availableVersion = parseVersion(version);
if (availableVersion > RAINMETER_VERSION ||
(revision_beta && availableVersion == RAINMETER_VERSION))
{
GetRainmeter().SetNewVersion();
WCHAR buffer[32];
const WCHAR* dataFile = GetRainmeter().GetDataFile().c_str();
GetPrivateProfileString(L"Rainmeter", L"LastCheck", L"0", buffer, _countof(buffer), dataFile);
// Show tray notification only once per new version
int lastVersion = parseVersion(buffer);
if (availableVersion > lastVersion)
{
GetRainmeter().GetTrayWindow()->ShowUpdateNotification(version);
WritePrivateProfileString(L"Rainmeter", L"LastCheck", version, dataFile);
}
}
}
InternetCloseHandle(hUrlDump);
}
InternetCloseHandle(hRootHandle);
}
void CheckUpdate()
{
_beginthread(CheckVersion, 0, nullptr);
}

View File

@ -1,240 +1,240 @@
/*
Copyright (C) 2010 Matt King, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "../LuaManager.h"
#include "../../Rainmeter.h"
#include "../../MeterWindow.h"
#include "../../MeterString.h"
#define DECLARE_SELF(L) \
void* selfData = lua_touserdata(L, 1); \
if (!selfData) return 0; \
MeterWindow* self = *(MeterWindow**)selfData;
static int Bang(lua_State* L)
{
DECLARE_SELF(L)
ConfigParser& parser = self->GetParser();
std::wstring bang = LuaManager::ToWide(2);
int top = lua_gettop(L);
if (top == 2) // 1 argument
{
parser.ReplaceVariables(bang);
Rainmeter::GetInstance().ExecuteCommand(bang.c_str(), self);
}
else
{
const WCHAR* bangSz = bang.c_str();
if (*bangSz == L'!')
{
++bangSz; // Skip "!"
std::vector<std::wstring> args;
for (int i = 3; i <= top; ++i)
{
std::wstring tmpSz = LuaManager::ToWide(i);
parser.ReplaceVariables(tmpSz);
args.push_back(tmpSz);
}
Rainmeter::GetInstance().ExecuteBang(bangSz, args, self);
}
}
return 0;
}
static int GetMeter(lua_State* L)
{
DECLARE_SELF(L)
const std::wstring meterName = LuaManager::ToWide(2);
Meter* meter = self->GetMeter(meterName);
if (meter)
{
*(Meter**)lua_newuserdata(L, sizeof(Meter*)) = meter;
lua_getglobal(L, "Meter");
lua_setmetatable(L, -2);
}
else
{
lua_pushnil(L);
}
return 1;
}
static int GetMeasure(lua_State* L)
{
DECLARE_SELF(L)
const std::wstring measureName = LuaManager::ToWide(2);
Measure* measure = self->GetMeasure(measureName);
if (measure)
{
*(Measure**)lua_newuserdata(L, sizeof(Measure*)) = measure;
lua_getglobal(L, "Measure");
lua_setmetatable(L, -2);
}
else
{
lua_pushnil(L);
}
return 1;
}
static int GetVariable(lua_State* L)
{
DECLARE_SELF(L)
const std::wstring name = LuaManager::ToWide(2);
const std::wstring* value = self->GetParser().GetVariable(name);
if (value)
{
LuaManager::PushWide(*value);
}
else if (lua_gettop(L) >= 3)
{
lua_pushvalue(L, 3);
}
else
{
lua_pushnil(L);
}
return 1;
}
static int ReplaceVariables(lua_State* L)
{
DECLARE_SELF(L)
std::wstring strTmp = LuaManager::ToWide(2);
self->GetParser().ReplaceVariables(strTmp);
self->GetParser().ReplaceMeasures(strTmp);
LuaManager::PushWide(strTmp);
return 1;
}
static int ParseFormula(lua_State* L)
{
DECLARE_SELF(L)
std::wstring strTmp = LuaManager::ToWide(2);
double result;
if (!self->GetParser().ParseFormula(strTmp, &result))
{
result = lua_tonumber(L, 2);
}
lua_pushnumber(L, result);
return 1;
}
static int MoveWindow(lua_State* L)
{
DECLARE_SELF(L)
int x = (int)lua_tonumber(L, 2);
int y = (int)lua_tonumber(L, 3);
self->MoveWindow(x, y);
return 0;
}
static int FadeWindow(lua_State* L)
{
DECLARE_SELF(L)
int from = (int)lua_tonumber(L, 2);
int to = (int)lua_tonumber(L, 3);
self->FadeWindow(from, to);
return 0;
}
static int GetW(lua_State* L)
{
DECLARE_SELF(L)
lua_pushnumber(L, self->GetW());
return 1;
}
static int GetH(lua_State* L)
{
DECLARE_SELF(L)
lua_pushnumber(L, self->GetH());
return 1;
}
static int GetX(lua_State* L)
{
DECLARE_SELF(L)
lua_pushnumber(L, self->GetX());
return 1;
}
static int GetY(lua_State* L)
{
DECLARE_SELF(L)
lua_pushnumber(L, self->GetY());
return 1;
}
static int MakePathAbsolute(lua_State* L)
{
DECLARE_SELF(L)
std::wstring path = LuaManager::ToWide(2);
self->MakePathAbsolute(path);
LuaManager::PushWide(path);
return 1;
}
void LuaManager::RegisterMeterWindow(lua_State* L)
{
const luaL_Reg functions[] =
{
{ "Bang", Bang },
{ "GetMeter", GetMeter },
{ "GetMeasure", GetMeasure },
{ "GetVariable", GetVariable },
{ "ReplaceVariables", ReplaceVariables },
{ "ParseFormula", ParseFormula },
{ "MoveWindow", MoveWindow },
{ "FadeWindow", FadeWindow },
{ "GetW", GetW },
{ "GetH", GetH },
{ "GetX", GetX },
{ "GetY", GetY },
{ "MakePathAbsolute", MakePathAbsolute },
{ nullptr, nullptr }
};
luaL_register(L, "MeterWindow", functions);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
lua_pop(L, 1);
}
/*
Copyright (C) 2010 Matt King, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "../LuaManager.h"
#include "../../Rainmeter.h"
#include "../../MeterWindow.h"
#include "../../MeterString.h"
#define DECLARE_SELF(L) \
void* selfData = lua_touserdata(L, 1); \
if (!selfData) return 0; \
MeterWindow* self = *(MeterWindow**)selfData;
static int Bang(lua_State* L)
{
DECLARE_SELF(L)
ConfigParser& parser = self->GetParser();
std::wstring bang = LuaManager::ToWide(2);
int top = lua_gettop(L);
if (top == 2) // 1 argument
{
parser.ReplaceVariables(bang);
GetRainmeter().ExecuteCommand(bang.c_str(), self);
}
else
{
const WCHAR* bangSz = bang.c_str();
if (*bangSz == L'!')
{
++bangSz; // Skip "!"
std::vector<std::wstring> args;
for (int i = 3; i <= top; ++i)
{
std::wstring tmpSz = LuaManager::ToWide(i);
parser.ReplaceVariables(tmpSz);
args.push_back(tmpSz);
}
GetRainmeter().ExecuteBang(bangSz, args, self);
}
}
return 0;
}
static int GetMeter(lua_State* L)
{
DECLARE_SELF(L)
const std::wstring meterName = LuaManager::ToWide(2);
Meter* meter = self->GetMeter(meterName);
if (meter)
{
*(Meter**)lua_newuserdata(L, sizeof(Meter*)) = meter;
lua_getglobal(L, "Meter");
lua_setmetatable(L, -2);
}
else
{
lua_pushnil(L);
}
return 1;
}
static int GetMeasure(lua_State* L)
{
DECLARE_SELF(L)
const std::wstring measureName = LuaManager::ToWide(2);
Measure* measure = self->GetMeasure(measureName);
if (measure)
{
*(Measure**)lua_newuserdata(L, sizeof(Measure*)) = measure;
lua_getglobal(L, "Measure");
lua_setmetatable(L, -2);
}
else
{
lua_pushnil(L);
}
return 1;
}
static int GetVariable(lua_State* L)
{
DECLARE_SELF(L)
const std::wstring name = LuaManager::ToWide(2);
const std::wstring* value = self->GetParser().GetVariable(name);
if (value)
{
LuaManager::PushWide(*value);
}
else if (lua_gettop(L) >= 3)
{
lua_pushvalue(L, 3);
}
else
{
lua_pushnil(L);
}
return 1;
}
static int ReplaceVariables(lua_State* L)
{
DECLARE_SELF(L)
std::wstring strTmp = LuaManager::ToWide(2);
self->GetParser().ReplaceVariables(strTmp);
self->GetParser().ReplaceMeasures(strTmp);
LuaManager::PushWide(strTmp);
return 1;
}
static int ParseFormula(lua_State* L)
{
DECLARE_SELF(L)
std::wstring strTmp = LuaManager::ToWide(2);
double result;
if (!self->GetParser().ParseFormula(strTmp, &result))
{
result = lua_tonumber(L, 2);
}
lua_pushnumber(L, result);
return 1;
}
static int MoveWindow(lua_State* L)
{
DECLARE_SELF(L)
int x = (int)lua_tonumber(L, 2);
int y = (int)lua_tonumber(L, 3);
self->MoveWindow(x, y);
return 0;
}
static int FadeWindow(lua_State* L)
{
DECLARE_SELF(L)
int from = (int)lua_tonumber(L, 2);
int to = (int)lua_tonumber(L, 3);
self->FadeWindow(from, to);
return 0;
}
static int GetW(lua_State* L)
{
DECLARE_SELF(L)
lua_pushnumber(L, self->GetW());
return 1;
}
static int GetH(lua_State* L)
{
DECLARE_SELF(L)
lua_pushnumber(L, self->GetH());
return 1;
}
static int GetX(lua_State* L)
{
DECLARE_SELF(L)
lua_pushnumber(L, self->GetX());
return 1;
}
static int GetY(lua_State* L)
{
DECLARE_SELF(L)
lua_pushnumber(L, self->GetY());
return 1;
}
static int MakePathAbsolute(lua_State* L)
{
DECLARE_SELF(L)
std::wstring path = LuaManager::ToWide(2);
self->MakePathAbsolute(path);
LuaManager::PushWide(path);
return 1;
}
void LuaManager::RegisterMeterWindow(lua_State* L)
{
const luaL_Reg functions[] =
{
{ "Bang", Bang },
{ "GetMeter", GetMeter },
{ "GetMeasure", GetMeasure },
{ "GetVariable", GetVariable },
{ "ReplaceVariables", ReplaceVariables },
{ "ParseFormula", ParseFormula },
{ "MoveWindow", MoveWindow },
{ "FadeWindow", FadeWindow },
{ "GetW", GetW },
{ "GetH", GetH },
{ "GetX", GetX },
{ "GetY", GetY },
{ "MakePathAbsolute", MakePathAbsolute },
{ nullptr, nullptr }
};
luaL_register(L, "MeterWindow", functions);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
lua_pop(L, 1);
}