- Partially refactored bang handling code

- Renamed CMeasure::ExecuteBang to CMeasure::Command
- Minor cosmetic changes and tweaks
This commit is contained in:
Birunthan Mohanathas 2012-02-01 15:55:29 +00:00
parent 7531ddde27
commit b21658b1cd
11 changed files with 503 additions and 635 deletions

View File

@ -88,13 +88,7 @@ void* __stdcall RmGet(void* rm, int type)
void __stdcall RmExecute(void* skin, LPCWSTR command)
{
CMeterWindow* mw = (CMeterWindow*)skin;
// Fake WM_COPYDATA message to deliver bang
COPYDATASTRUCT cds;
cds.cbData = 1;
cds.dwData = 1;
cds.lpData = (void*)command;
mw->OnCopyData(WM_COPYDATA, NULL, (LPARAM)&cds);
Rainmeter->ExecuteCommand(command, mw);
}
BOOL LSLog(int nLevel, LPCWSTR unused, LPCWSTR pszMessage)
@ -127,25 +121,18 @@ LPCWSTR ReadConfigString(LPCWSTR section, LPCWSTR option, LPCWSTR defValue)
}
// Deprecated!
LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData)
LPCWSTR PluginBridge(LPCWSTR command, LPCWSTR data)
{
if (_sCommand == NULL || *_sCommand == L'\0')
if (command == NULL || *command == L'\0')
{
return L"noop";
}
NULLCHECK(_sData);
NULLCHECK(data);
// Command GetConfig
// Data unquoted full path and filename given to the plugin on initialize
// (note: this is CaSe-SeNsItIvE!)
// Execution none
// Result the config name if found or a blank string if not
if (_wcsicmp(_sCommand, L"GetConfig") == 0)
if (_wcsicmp(command, L"GetConfig") == 0)
{
// returns the config name, lookup by INI file
CMeterWindow *meterWindow = Rainmeter->GetMeterWindowByINI(_sData);
CMeterWindow *meterWindow = Rainmeter->GetMeterWindowByINI(data);
if (meterWindow)
{
g_Buffer = L"\"";
@ -156,14 +143,9 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData)
return L"";
}
// Command GetWindow
// Data [the config name]
// Execution none
// Result the HWND to the specified config window if found, 'error' otherwise
if (_wcsicmp(_sCommand, L"GetWindow") == 0)
else if (_wcsicmp(command, L"GetWindow") == 0)
{
std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData);
std::vector<std::wstring> subStrings = CRainmeter::ParseString(data);
if (subStrings.size() >= 1)
{
@ -181,14 +163,9 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData)
return L"error";
}
// Command GetVariable
// Data [the config name]
// Execution none
// Result the value of the variable
if (_wcsicmp(_sCommand, L"GetVariable") == 0)
else if (_wcsicmp(command, L"GetVariable") == 0)
{
std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData);
std::vector<std::wstring> subStrings = CRainmeter::ParseString(data);
if (subStrings.size() >= 2)
{
@ -208,31 +185,22 @@ LPCWSTR PluginBridge(LPCWSTR _sCommand, LPCWSTR _sData)
return L"";
}
// Command SetVariable
// Data [the config name] [variable data]
// Execution the indicated variable is updated
// Result 'success' if the config was found, 'error' otherwise
if (_wcsicmp(_sCommand, L"SetVariable") == 0)
else if (_wcsicmp(command, L"SetVariable") == 0)
{
std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData);
if (subStrings.size() >= 2)
const WCHAR* pos = wcschr(data, L' ');
if (pos)
{
const std::wstring& config = subStrings[0];
std::wstring arguments;
std::wstring config(data + 1, pos - 1);
std::vector<std::wstring> subStrings = CRainmeter::ParseString(pos);
for (size_t i = 1, isize = subStrings.size(); i < isize; ++i)
if (subStrings.size() == 2)
{
if (i != 1) arguments += L" ";
arguments += subStrings[i];
}
CMeterWindow *meterWindow = Rainmeter->GetMeterWindow(config);
if (meterWindow)
{
meterWindow->RunBang(BANG_SETVARIABLE, arguments.c_str());
return L"success";
CMeterWindow *meterWindow = Rainmeter->GetMeterWindow(config);
if (meterWindow)
{
meterWindow->RunBang(BANG_SETVARIABLE, subStrings);
return L"success";
}
}
}

View File

@ -838,11 +838,12 @@ CMeasure* CMeasure::Create(const WCHAR* measure, CMeterWindow* meterWindow, cons
}
/*
** ExecuteBang
** Command
**
** Executes a custom bang.
**
** Executes a custom bang
*/
void CMeasure::ExecuteBang(const WCHAR* args)
void CMeasure::Command(const std::wstring& command)
{
LogWithArgs(LOG_WARNING, L"!CommandMeasure: Not supported by [%s]", m_Name.c_str());
}

View File

@ -62,7 +62,7 @@ public:
bool HasDynamicVariables() { return m_DynamicVariables; }
void SetDynamicVariables(bool b) { m_DynamicVariables = b; }
virtual void ExecuteBang(const WCHAR* args);
virtual void Command(const std::wstring& command);
double GetValue();
double GetRelativeValue();

View File

@ -248,26 +248,27 @@ const WCHAR* CMeasurePlugin::GetStringValue(AUTOSCALE autoScale, double scale, i
}
/*
** ExecuteBang
** Command
**
** Sends a bang to the plugin
**
*/
void CMeasurePlugin::ExecuteBang(const WCHAR* args)
void CMeasurePlugin::Command(const std::wstring& command)
{
if (m_ExecuteBangFunc)
{
const WCHAR* str = command.c_str();
if (IsNewApi())
{
((NEWEXECUTEBANG)m_ExecuteBangFunc)(m_PluginData, args);
((NEWEXECUTEBANG)m_ExecuteBangFunc)(m_PluginData, str);
}
else
{
((EXECUTEBANG)m_ExecuteBangFunc)(args, m_ID);
((EXECUTEBANG)m_ExecuteBangFunc)(str, m_ID);
}
}
else
{
CMeasure::ExecuteBang(args);
CMeasure::Command(command);
}
}

View File

@ -27,14 +27,14 @@ typedef VOID (*FINALIZE)(HMODULE, UINT);
typedef UINT (*UPDATE)(UINT);
typedef double (*UPDATE2)(UINT);
typedef LPCTSTR (*GETSTRING)(UINT, UINT);
typedef void (*EXECUTEBANG)(LPCTSTR, UINT);
typedef void (*EXECUTEBANG)(LPCWSTR, UINT);
typedef void (*NEWINITIALIZE)(void*);
typedef void (*NEWRELOAD)(void*, void*, double*);
typedef void (*NEWFINALIZE)(void*);
typedef double (*NEWUPDATE)(void*);
typedef LPCWSTR (*NEWGETSTRING)(void*);
typedef void (*NEWEXECUTEBANG)(void*, const WCHAR*);
typedef void (*NEWEXECUTEBANG)(void*, const LPCWSTR);
class CMeasurePlugin : public CMeasure
{
@ -44,7 +44,7 @@ public:
virtual bool Update();
virtual const WCHAR* GetStringValue(AUTOSCALE autoScale, double scale, int decimals, bool percentual);
virtual void ExecuteBang(const WCHAR* args);
virtual void Command(const std::wstring& command);
protected:
virtual void ReadConfig(CConfigParser& parser, const WCHAR* section);

View File

@ -219,14 +219,14 @@ void CMeasureScript::ReadConfig(CConfigParser& parser, const WCHAR* section)
}
/*
** ExecuteBang
** Command
**
** Sends a bang to the measure.
** Executes a custom bang.
**
*/
void CMeasureScript::ExecuteBang(const WCHAR* args)
void CMeasureScript::Command(const std::wstring& command)
{
std::string str = ConvertToAscii(args);
std::string str = ConvertToAscii(command.c_str());
m_LuaScript->RunString(str.c_str());
}

View File

@ -30,7 +30,7 @@ public:
virtual void Initialize();
virtual bool Update();
virtual const WCHAR* GetStringValue(AUTOSCALE autoScale, double scale, int decimals, bool percentual);
virtual void ExecuteBang(const WCHAR* args);
virtual void Command(const std::wstring& command);
void DeleteLuaScript();

View File

@ -74,7 +74,7 @@ extern CRainmeter* Rainmeter;
** Constructor
**
*/
CMeterWindow::CMeterWindow(const std::wstring& path, const std::wstring& config, const std::wstring& iniFile) : m_SkinPath(path), m_SkinName(config), m_SkinIniFile(iniFile),
CMeterWindow::CMeterWindow(const std::wstring& config, const std::wstring& iniFile) : m_SkinName(config), m_SkinIniFile(iniFile),
m_DoubleBuffer(),
m_DIBSectionBuffer(),
m_DIBSectionBufferPixels(),
@ -699,14 +699,11 @@ void CMeterWindow::ChangeSingleZPos(ZPOSITION zPos, bool all)
/*
** RunBang
**
** Runs the bang command
**
** Runs the bang command with the given arguments.
** Correct number of arguments must be passed (or use CRainmeter::ExecuteBang).
*/
void CMeterWindow::RunBang(BANGCOMMAND bang, const WCHAR* arg)
void CMeterWindow::RunBang(BANGCOMMAND bang, const std::vector<std::wstring>& args)
{
const WCHAR* pos = NULL;
const WCHAR* pos2 = NULL;
if (!m_Window) return;
switch (bang)
@ -739,82 +736,82 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const WCHAR* arg)
break;
case BANG_TOGGLEBLUR:
RunBang(IsBlur() ? BANG_HIDEBLUR : BANG_SHOWBLUR, arg);
RunBang(IsBlur() ? BANG_HIDEBLUR : BANG_SHOWBLUR, args);
break;
case BANG_ADDBLUR:
ResizeBlur(arg, RGN_OR);
ResizeBlur(args[0], RGN_OR);
if (IsBlur()) ShowBlur();
break;
case BANG_REMOVEBLUR:
ResizeBlur(arg, RGN_DIFF);
ResizeBlur(args[0], RGN_DIFF);
if (IsBlur()) ShowBlur();
break;
case BANG_TOGGLEMETER:
ToggleMeter(arg);
ToggleMeter(args[0]);
break;
case BANG_SHOWMETER:
ShowMeter(arg);
ShowMeter(args[0]);
break;
case BANG_HIDEMETER:
HideMeter(arg);
HideMeter(args[0]);
break;
case BANG_UPDATEMETER:
UpdateMeter(arg);
UpdateMeter(args[0]);
break;
case BANG_TOGGLEMETERGROUP:
ToggleMeter(arg, true);
ToggleMeter(args[0], true);
break;
case BANG_SHOWMETERGROUP:
ShowMeter(arg, true);
ShowMeter(args[0], true);
break;
case BANG_HIDEMETERGROUP:
HideMeter(arg, true);
HideMeter(args[0], true);
break;
case BANG_UPDATEMETERGROUP:
UpdateMeter(arg, true);
UpdateMeter(args[0], true);
break;
case BANG_TOGGLEMEASURE:
ToggleMeasure(arg);
ToggleMeasure(args[0]);
break;
case BANG_ENABLEMEASURE:
EnableMeasure(arg);
EnableMeasure(args[0]);
break;
case BANG_DISABLEMEASURE:
DisableMeasure(arg);
DisableMeasure(args[0]);
break;
case BANG_UPDATEMEASURE:
UpdateMeasure(arg);
UpdateMeasure(args[0]);
CDialogAbout::UpdateMeasures(this);
break;
case BANG_DISABLEMEASUREGROUP:
DisableMeasure(arg, true);
DisableMeasure(args[0], true);
break;
case BANG_TOGGLEMEASUREGROUP:
ToggleMeasure(arg, true);
ToggleMeasure(args[0], true);
break;
case BANG_ENABLEMEASUREGROUP:
EnableMeasure(arg, true);
EnableMeasure(args[0], true);
break;
case BANG_UPDATEMEASUREGROUP:
UpdateMeasure(arg, true);
UpdateMeasure(args[0], true);
CDialogAbout::UpdateMeasures(this);
break;
@ -830,77 +827,63 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const WCHAR* arg)
break;
case BANG_TOGGLE:
RunBang(m_Hidden ? BANG_SHOW : BANG_HIDE, arg);
RunBang(m_Hidden ? BANG_SHOW : BANG_HIDE, args);
break;
case BANG_SHOWFADE:
m_Hidden = false;
if (!IsWindowVisible(m_Window))
{
FadeWindow(0, (m_WindowHide == HIDEMODE_FADEOUT) ? 255 : m_AlphaValue);
}
ShowFade();
break;
case BANG_HIDEFADE:
m_Hidden = true;
if (IsWindowVisible(m_Window))
{
FadeWindow(m_AlphaValue, 0);
}
HideFade();
break;
case BANG_TOGGLEFADE:
RunBang(m_Hidden ? BANG_SHOWFADE : BANG_HIDEFADE, arg);
RunBang(m_Hidden ? BANG_SHOWFADE : BANG_HIDEFADE, args);
break;
case BANG_MOVE:
pos = wcschr(arg, L' ');
if (pos != NULL)
{
MoveWindow(_wtoi(arg), _wtoi(pos));
}
else
{
Log(LOG_ERROR, L"!Move: Invalid parameters");
MoveWindow(_wtoi(args[0].c_str()), _wtoi(args[1].c_str()));
}
break;
case BANG_ZPOS:
SetWindowZPosition((ZPOSITION)_wtoi(arg));
SetWindowZPosition((ZPOSITION)_wtoi(args[0].c_str()));
break;
case BANG_CLICKTHROUGH:
{
int f = _wtoi(arg);
int f = _wtoi(args[0].c_str());
SetClickThrough((f == -1) ? !m_ClickThrough : f);
}
break;
case BANG_DRAGGABLE:
{
int f = _wtoi(arg);
int f = _wtoi(args[0].c_str());
SetWindowDraggable((f == -1) ? !m_WindowDraggable : f);
}
break;
case BANG_SNAPEDGES:
{
int f = _wtoi(arg);
int f = _wtoi(args[0].c_str());
SetSnapEdges((f == -1) ? !m_SnapEdges : f);
}
break;
case BANG_KEEPONSCREEN:
{
int f = _wtoi(arg);
int f = _wtoi(args[0].c_str());
SetKeepOnScreen((f == -1) ? !m_KeepOnScreen : f);
}
break;
case BANG_SETTRANSPARENCY:
if (arg != NULL)
{
m_AlphaValue = CConfigParser::ParseInt(arg, 255);
const std::wstring& arg = args[0];
m_AlphaValue = CConfigParser::ParseInt(arg.c_str(), 255);
m_AlphaValue = max(m_AlphaValue, 0);
m_AlphaValue = min(m_AlphaValue, 255);
UpdateTransparency(m_AlphaValue, false);
@ -908,80 +891,52 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const WCHAR* arg)
break;
case BANG_MOVEMETER:
pos = wcschr(arg, L' ');
if (pos != NULL)
{
pos2 = wcschr(pos + 1, L' ');
if (pos2 != NULL)
{
MoveMeter(_wtoi(arg), _wtoi(pos), pos2 + 1);
break;
}
}
Log(LOG_ERROR, L"!MoveMeter: Invalid parameters");
MoveMeter(args[2], _wtoi(args[0].c_str()), _wtoi(args[1].c_str()));
break;
case BANG_COMMANDMEASURE:
{
std::wstring args = arg;
std::wstring measure;
std::wstring::size_type pos3;
pos3 = args.find(L' ');
if (pos3 != std::wstring::npos)
const std::wstring& measure = args[0];
CMeasure* m = GetMeasure(measure);
if (m)
{
measure.assign(args, 0, pos3);
args.erase(0, ++pos3);
CMeasure* m = GetMeasure(measure);
if (m)
{
m->ExecuteBang(args.c_str());
return;
}
LogWithArgs(LOG_WARNING, L"!CommandMeasure: [%s] not found", measure.c_str());
m->Command(args[1]);
}
else
{
Log(LOG_ERROR, L"!CommandMeasure: Invalid parameters");
LogWithArgs(LOG_WARNING, L"!CommandMeasure: [%s] not found", measure.c_str());
}
}
break;
case BANG_PLUGIN:
{
std::wstring args = arg;
std::wstring measure;
std::wstring::size_type pos3;
do
std::wstring arg = args[0];
std::wstring::size_type pos;
while ((pos = arg.find(L'"')) != std::wstring::npos)
{
pos3 = args.find(L'"');
if (pos3 != std::wstring::npos)
{
args.erase(pos3, 1);
}
arg.erase(pos, 1);
}
while(pos3 != std::wstring::npos);
pos3 = args.find(L' ');
if (pos3 != std::wstring::npos)
std::wstring measure;
pos = arg.find(L' ');
if (pos != std::wstring::npos)
{
measure.assign(args, 0, pos3);
++pos3;
measure.assign(arg, 0, pos);
++pos;
}
else
{
measure = args;
measure = arg;
}
args.erase(0, pos3);
arg.erase(0, pos);
if (!measure.empty())
{
CMeasure* m = GetMeasure(measure);
if (m)
{
m->ExecuteBang(args.c_str());
m->Command(arg);
return;
}
@ -995,41 +950,35 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const WCHAR* arg)
break;
case BANG_SETVARIABLE:
pos = wcschr(arg, L' ');
if (pos != NULL)
{
std::wstring strVariable(arg, pos - arg);
std::wstring strValue(pos + 1);
double value;
const std::wstring& variable = args[0];
const std::wstring& value = args[1];
// Formula read fine
if (m_Parser.ParseFormula(strValue, &value))
double result;
if (m_Parser.ParseFormula(value, &result))
{
WCHAR buffer[256];
int len = _snwprintf_s(buffer, _TRUNCATE, L"%.5f", value);
int len = _snwprintf_s(buffer, _TRUNCATE, L"%.5f", result);
CMeasure::RemoveTrailingZero(buffer, len);
const std::wstring& resultString = buffer;
m_Parser.SetVariable(strVariable, resultString);
m_Parser.SetVariable(variable, resultString);
}
else
{
m_Parser.SetVariable(strVariable, strValue);
m_Parser.SetVariable(variable, value);
}
}
else
{
Log(LOG_ERROR, L"!SetVariable: Invalid parameters");
}
break;
case BANG_SETOPTION:
SetOption(arg, false);
SetOption(args[0], args[1], args[2], false);
break;
case BANG_SETOPTIONGROUP:
SetOption(arg, true);
SetOption(args[0], args[1], args[2], true);
break;
}
}
@ -1103,11 +1052,11 @@ void CMeterWindow::HideBlur()
** Adds to or removes from blur region
**
*/
void CMeterWindow::ResizeBlur(const WCHAR* arg, int mode)
void CMeterWindow::ResizeBlur(const std::wstring& arg, int mode)
{
if (CSystem::GetOSPlatform() >= OSPLATFORM_VISTA)
{
WCHAR* parseSz = _wcsdup(arg);
WCHAR* parseSz = _wcsdup(arg.c_str());
double val;
int type, x, y, w = 0, h = 0;
@ -1188,14 +1137,14 @@ void CMeterWindow::ResizeBlur(const WCHAR* arg, int mode)
** Shows the given meter
**
*/
void CMeterWindow::ShowMeter(const WCHAR* name, bool group)
void CMeterWindow::ShowMeter(const std::wstring& name, bool group)
{
if (name == NULL || *name == 0) return;
const WCHAR* meter = name.c_str();
std::list<CMeter*>::const_iterator j = m_Meters.begin();
for ( ; j != m_Meters.end(); ++j)
{
if (CompareName((*j), name, group))
if (CompareName((*j), meter, group))
{
(*j)->Show();
m_ResetRegion = true; // Need to recalculate the window region
@ -1203,7 +1152,7 @@ void CMeterWindow::ShowMeter(const WCHAR* name, bool group)
}
}
if (!group) LogWithArgs(LOG_NOTICE, L"!ShowMeter: [%s] not found in \"%s\"", name, m_SkinName.c_str());
if (!group) LogWithArgs(LOG_NOTICE, L"!ShowMeter: [%s] not found in \"%s\"", meter, m_SkinName.c_str());
}
/*
@ -1212,14 +1161,14 @@ void CMeterWindow::ShowMeter(const WCHAR* name, bool group)
** Hides the given meter
**
*/
void CMeterWindow::HideMeter(const WCHAR* name, bool group)
void CMeterWindow::HideMeter(const std::wstring& name, bool group)
{
if (name == NULL || *name == 0) return;
const WCHAR* meter = name.c_str();
std::list<CMeter*>::const_iterator j = m_Meters.begin();
for ( ; j != m_Meters.end(); ++j)
{
if (CompareName((*j), name, group))
if (CompareName((*j), meter, group))
{
(*j)->Hide();
m_ResetRegion = true; // Need to recalculate the windowregion
@ -1227,7 +1176,7 @@ void CMeterWindow::HideMeter(const WCHAR* name, bool group)
}
}
if (!group) LogWithArgs(LOG_ERROR, L"!HideMeter: [%s] not found in \"%s\"", name, m_SkinName.c_str());
if (!group) LogWithArgs(LOG_ERROR, L"!HideMeter: [%s] not found in \"%s\"", meter, m_SkinName.c_str());
}
/*
@ -1236,14 +1185,14 @@ void CMeterWindow::HideMeter(const WCHAR* name, bool group)
** Toggles the given meter
**
*/
void CMeterWindow::ToggleMeter(const WCHAR* name, bool group)
void CMeterWindow::ToggleMeter(const std::wstring& name, bool group)
{
if (name == NULL || *name == 0) return;
const WCHAR* meter = name.c_str();
std::list<CMeter*>::const_iterator j = m_Meters.begin();
for ( ; j != m_Meters.end(); ++j)
{
if (CompareName((*j), name, group))
if (CompareName((*j), meter, group))
{
if ((*j)->IsHidden())
{
@ -1258,7 +1207,7 @@ void CMeterWindow::ToggleMeter(const WCHAR* name, bool group)
}
}
if (!group) LogWithArgs(LOG_ERROR, L"!ToggleMeter: [%s] not found in \"%s\"", name, m_SkinName.c_str());
if (!group) LogWithArgs(LOG_ERROR, L"!ToggleMeter: [%s] not found in \"%s\"", meter, m_SkinName.c_str());
}
/*
@ -1267,14 +1216,14 @@ void CMeterWindow::ToggleMeter(const WCHAR* name, bool group)
** Moves the given meter
**
*/
void CMeterWindow::MoveMeter(int x, int y, const WCHAR* name)
void CMeterWindow::MoveMeter(const std::wstring& name, int x, int y)
{
if (name == NULL || *name == 0) return;
const WCHAR* meter = name.c_str();
std::list<CMeter*>::const_iterator j = m_Meters.begin();
for ( ; j != m_Meters.end(); ++j)
{
if (CompareName((*j), name, false))
if (CompareName((*j), meter, false))
{
(*j)->SetX(x);
(*j)->SetY(y);
@ -1283,7 +1232,7 @@ void CMeterWindow::MoveMeter(int x, int y, const WCHAR* name)
}
}
LogWithArgs(LOG_ERROR, L"!MoveMeter: [%s] not found in \"%s\"", name, m_SkinName.c_str());
LogWithArgs(LOG_ERROR, L"!MoveMeter: [%s] not found in \"%s\"", meter, m_SkinName.c_str());
}
/*
@ -1292,16 +1241,16 @@ void CMeterWindow::MoveMeter(int x, int y, const WCHAR* name)
** Updates the given meter
**
*/
void CMeterWindow::UpdateMeter(const WCHAR* name, bool group)
void CMeterWindow::UpdateMeter(const std::wstring& name, bool group)
{
if (name == NULL || *name == 0) return;
const WCHAR* meter = name.c_str();
bool bActiveTransition = false;
bool bContinue = true;
std::list<CMeter*>::const_iterator j = m_Meters.begin();
for ( ; j != m_Meters.end(); ++j)
{
if (bContinue && CompareName((*j), name, group))
if (bContinue && CompareName((*j), meter, group))
{
UpdateMeter((*j), bActiveTransition, true);
m_ResetRegion = true; // Need to recalculate the windowregion
@ -1325,7 +1274,7 @@ void CMeterWindow::UpdateMeter(const WCHAR* name, bool group)
// Post-updates
PostUpdate(bActiveTransition);
if (!group && bContinue) LogWithArgs(LOG_ERROR, L"!UpdateMeter: [%s] not found in \"%s\"", name, m_SkinName.c_str());
if (!group && bContinue) LogWithArgs(LOG_ERROR, L"!UpdateMeter: [%s] not found in \"%s\"", meter, m_SkinName.c_str());
}
/*
@ -1334,14 +1283,14 @@ void CMeterWindow::UpdateMeter(const WCHAR* name, bool group)
** Enables the given measure
**
*/
void CMeterWindow::EnableMeasure(const WCHAR* name, bool group)
void CMeterWindow::EnableMeasure(const std::wstring& name, bool group)
{
if (name == NULL || *name == 0) return;
const WCHAR* measure = name.c_str();
std::list<CMeasure*>::const_iterator i = m_Measures.begin();
for ( ; i != m_Measures.end(); ++i)
{
if (CompareName((*i), name, group))
if (CompareName((*i), measure, group))
{
(*i)->Enable();
if (!group) return;
@ -1357,21 +1306,21 @@ void CMeterWindow::EnableMeasure(const WCHAR* name, bool group)
** Disables the given measure
**
*/
void CMeterWindow::DisableMeasure(const WCHAR* name, bool group)
void CMeterWindow::DisableMeasure(const std::wstring& name, bool group)
{
if (name == NULL || *name == 0) return;
const WCHAR* measure = name.c_str();
std::list<CMeasure*>::const_iterator i = m_Measures.begin();
for ( ; i != m_Measures.end(); ++i)
{
if (CompareName((*i), name, group))
if (CompareName((*i), measure, group))
{
(*i)->Disable();
if (!group) return;
}
}
if (!group) LogWithArgs(LOG_ERROR, L"!DisableMeasure: [%s] not found in \"%s\"", name, m_SkinName.c_str());
if (!group) LogWithArgs(LOG_ERROR, L"!DisableMeasure: [%s] not found in \"%s\"", measure, m_SkinName.c_str());
}
/*
@ -1380,14 +1329,14 @@ void CMeterWindow::DisableMeasure(const WCHAR* name, bool group)
** Toggless the given measure
**
*/
void CMeterWindow::ToggleMeasure(const WCHAR* name, bool group)
void CMeterWindow::ToggleMeasure(const std::wstring& name, bool group)
{
if (name == NULL || *name == 0) return;
const WCHAR* measure = name.c_str();
std::list<CMeasure*>::const_iterator i = m_Measures.begin();
for ( ; i != m_Measures.end(); ++i)
{
if (CompareName((*i), name, group))
if (CompareName((*i), measure, group))
{
if ((*i)->IsDisabled())
{
@ -1401,7 +1350,7 @@ void CMeterWindow::ToggleMeasure(const WCHAR* name, bool group)
}
}
if (!group) LogWithArgs(LOG_ERROR, L"!ToggleMeasure: [%s] not found in \"%s\"", name, m_SkinName.c_str());
if (!group) LogWithArgs(LOG_ERROR, L"!ToggleMeasure: [%s] not found in \"%s\"", measure, m_SkinName.c_str());
}
/*
@ -1410,15 +1359,15 @@ void CMeterWindow::ToggleMeasure(const WCHAR* name, bool group)
** Updates the given measure
**
*/
void CMeterWindow::UpdateMeasure(const WCHAR* name, bool group)
void CMeterWindow::UpdateMeasure(const std::wstring& name, bool group)
{
if (name == NULL || *name == 0) return;
const WCHAR* measure = name.c_str();
bool bNetStats = m_HasNetMeasures;
std::list<CMeasure*>::const_iterator i = m_Measures.begin();
for ( ; i != m_Measures.end(); ++i)
{
if (CompareName((*i), name, group))
if (CompareName((*i), measure, group))
{
if (bNetStats && dynamic_cast<CMeasureNet*>(*i) != NULL)
{
@ -1432,7 +1381,7 @@ void CMeterWindow::UpdateMeasure(const WCHAR* name, bool group)
}
}
if (!group) LogWithArgs(LOG_ERROR, L"!UpdateMeasure: [%s] not found in \"%s\"", name, m_SkinName.c_str());
if (!group) LogWithArgs(LOG_ERROR, L"!UpdateMeasure: [%s] not found in \"%s\"", measure, m_SkinName.c_str());
}
/*
@ -1441,61 +1390,34 @@ void CMeterWindow::UpdateMeasure(const WCHAR* name, bool group)
** Changes the property of a meter or measure.
**
*/
void CMeterWindow::SetOption(const WCHAR* arg, bool group)
void CMeterWindow::SetOption(const std::wstring& section, const std::wstring& option, const std::wstring& value, bool group)
{
const WCHAR* pos = wcschr(arg, L' ');
if (pos != NULL)
if (group)
{
const WCHAR* pos2 = wcschr(pos + 1, L' ');
std::wstring section(arg, pos - arg);
std::wstring option(pos + 1, pos2);
std::wstring value(pos2 + 1);
if (group)
for (std::list<CMeter*>::const_iterator j = m_Meters.begin(); j != m_Meters.end(); ++j)
{
for (std::list<CMeter*>::const_iterator j = m_Meters.begin(); j != m_Meters.end(); ++j)
if ((*j)->BelongsToGroup(section))
{
if ((*j)->BelongsToGroup(section))
{
// Force DynamicVariables temporarily (it will reset back to original setting in ReadConfig())
(*j)->SetDynamicVariables(true);
// Force DynamicVariables temporarily (it will reset back to original setting in ReadConfig())
(*j)->SetDynamicVariables(true);
if (value.empty())
{
GetParser().DeleteValue((*j)->GetOriginalName(), option);
}
else
{
GetParser().SetValue((*j)->GetOriginalName(), option, value);
}
if (value.empty())
{
GetParser().DeleteValue((*j)->GetOriginalName(), option);
}
}
for (std::list<CMeasure*>::const_iterator i = m_Measures.begin(); i != m_Measures.end(); ++i)
{
if ((*i)->BelongsToGroup(section))
else
{
// Force DynamicVariables temporarily (it will reset back to original setting in ReadConfig())
(*i)->SetDynamicVariables(true);
if (value.empty())
{
GetParser().DeleteValue(section, option);
}
else
{
GetParser().SetValue(section, option, value);
}
GetParser().SetValue((*j)->GetOriginalName(), option, value);
}
}
}
else
for (std::list<CMeasure*>::const_iterator i = m_Measures.begin(); i != m_Measures.end(); ++i)
{
CMeter* meter = GetMeter(section);
if (meter)
if ((*i)->BelongsToGroup(section))
{
// Force DynamicVariables temporarily (it will reset back to original setting in ReadConfig())
meter->SetDynamicVariables(true);
(*i)->SetDynamicVariables(true);
if (value.empty())
{
@ -1505,34 +1427,48 @@ void CMeterWindow::SetOption(const WCHAR* arg, bool group)
{
GetParser().SetValue(section, option, value);
}
return;
}
CMeasure* measure = GetMeasure(section);
if (measure)
{
// Force DynamicVariables temporarily (it will reset back to original setting in ReadConfig())
measure->SetDynamicVariables(true);
if (value.empty())
{
GetParser().DeleteValue(section, option);
}
else
{
GetParser().SetValue(section, option, value);
}
return;
}
// Is it a style?
}
}
else
{
Log(LOG_ERROR, L"!SetOption: Invalid parameters");
CMeter* meter = GetMeter(section);
if (meter)
{
// Force DynamicVariables temporarily (it will reset back to original setting in ReadConfig())
meter->SetDynamicVariables(true);
if (value.empty())
{
GetParser().DeleteValue(section, option);
}
else
{
GetParser().SetValue(section, option, value);
}
return;
}
CMeasure* measure = GetMeasure(section);
if (measure)
{
// Force DynamicVariables temporarily (it will reset back to original setting in ReadConfig())
measure->SetDynamicVariables(true);
if (value.empty())
{
GetParser().DeleteValue(section, option);
}
else
{
GetParser().SetValue(section, option, value);
}
return;
}
// Is it a style?
}
}
@ -2061,7 +1997,7 @@ void CMeterWindow::WriteConfig(INT setting)
*/
bool CMeterWindow::ReadSkin()
{
std::wstring iniFile = m_SkinPath + m_SkinName;
std::wstring iniFile = m_Rainmeter->GetSkinPath() + m_SkinName;
iniFile += L'\\';
iniFile += m_SkinIniFile;
@ -2203,7 +2139,7 @@ bool CMeterWindow::ReadSkin()
// It wasn't found in the fonts folder, check the local folder
if (nResults != Ok)
{
szFontFile = m_SkinPath; // Get the local path
szFontFile = m_Rainmeter->GetSkinPath(); // Get the local path
szFontFile += m_SkinName;
szFontFile += L'\\';
szFontFile += localFont;
@ -3199,6 +3135,24 @@ void CMeterWindow::FadeWindow(int from, int to)
}
}
void CMeterWindow::HideFade()
{
m_Hidden = true;
if (IsWindowVisible(m_Window))
{
FadeWindow(m_AlphaValue, 0);
}
}
void CMeterWindow::ShowFade()
{
m_Hidden = false;
if (!IsWindowVisible(m_Window))
{
FadeWindow(0, (m_WindowHide == HIDEMODE_FADEOUT) ? 255 : m_AlphaValue);
}
}
/*
** ShowWindowIfAppropriate
**
@ -3533,7 +3487,7 @@ LRESULT CMeterWindow::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (wParam == ID_CONTEXT_SKINMENU_EDITSKIN)
{
std::wstring command = m_SkinPath + m_SkinName;
std::wstring command = m_Rainmeter->GetSkinPath() + m_SkinName;
command += L'\\';
command += m_SkinIniFile;
bool writable = CSystem::IsFileWritable(command.c_str());
@ -3551,7 +3505,7 @@ LRESULT CMeterWindow::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam)
}
else if (wParam == ID_CONTEXT_SKINMENU_OPENSKINSFOLDER)
{
std::wstring command = L'"' + m_SkinPath;
std::wstring command = L'"' + m_Rainmeter->GetSkinPath();
command += m_SkinName;
command += L'"';
RunCommand(NULL, command.c_str(), SW_SHOWNORMAL);
@ -4889,6 +4843,7 @@ LRESULT CMeterWindow::OnDelayedExecute(UINT uMsg, WPARAM wParam, LPARAM lParam)
OnCopyData(WM_COPYDATA, NULL, (LPARAM)&copyData);
}
return 0;
}
@ -4967,66 +4922,22 @@ LRESULT CMeterWindow::OnCopyData(UINT uMsg, WPARAM wParam, LPARAM lParam)
break;
}
}
if (!found)
if (found)
{
Log(LOG_WARNING, L"Unable to bang a deactivated config");
return TRUE; // This meterwindow has been deactivated
}
const WCHAR* str = (const WCHAR*)pCopyDataStruct->lpData;
if (_wcsnicmp(L"PLAY ", str, 5) == 0 ||
_wcsnicmp(L"PLAYLOOP ", str, 9) == 0 ||
_wcsnicmp(L"PLAYSTOP", str, 8) == 0)
{
// Audio commands are special cases.
m_Rainmeter->ExecuteCommand(str, this);
return TRUE;
}
std::wstring bang, arg;
// Find the first space
const WCHAR* pos = wcschr(str, L' ');
if (pos)
{
bang.assign(str, 0, pos - str);
arg = pos + 1;
const WCHAR* command = (const WCHAR*)pCopyDataStruct->lpData;
m_Rainmeter->ExecuteCommand(command, this);
}
else
{
bang = str;
// This meterwindow has been deactivated
Log(LOG_WARNING, L"Unable to bang a deactivated config");
}
if (_wcsicmp(bang.c_str(), L"!RainmeterWriteKeyValue") == 0 ||
_wcsicmp(bang.c_str(), L"!WriteKeyValue") == 0)
{
// !RainmeterWriteKeyValue is a special case.
if (CRainmeter::ParseString(arg.c_str()).size() < 4)
{
// Add the current config filepath to the args
arg += L" \"";
arg += m_SkinPath;
arg += m_SkinName;
arg += L'\\';
arg += m_SkinIniFile;
arg += L'"';
}
}
// Add the current config name to the args. If it's not defined already
// the bang only affects this config, if there already is a config defined
// another one doesn't matter.
arg += L" \"";
arg += m_SkinName;
arg += L'"';
return m_Rainmeter->ExecuteBang(bang, arg, this);
}
else
{
return FALSE;
return TRUE;
}
return FALSE;
}
/*
@ -5076,8 +4987,8 @@ void CMeterWindow::MakePathAbsolute(std::wstring& path)
else
{
std::wstring absolute;
absolute.reserve(m_SkinPath.size() + m_SkinName.size() + 1 + path.size());
absolute = m_SkinPath;
absolute.reserve(m_Rainmeter->GetSkinPath().size() + m_SkinName.size() + 1 + path.size());
absolute = m_Rainmeter->GetSkinPath();
absolute += m_SkinName;
absolute += L'\\';
absolute += path;

View File

@ -157,32 +157,31 @@ enum BANGCOMMAND
class CRainmeter;
class CMeasure;
class CMeter;
class CMeasureScript;
class CMeterWindow : public CGroup
{
public:
CMeterWindow(const std::wstring& path, const std::wstring& config, const std::wstring& iniFile);
CMeterWindow(const std::wstring& config, const std::wstring& iniFile);
~CMeterWindow();
int Initialize(CRainmeter& Rainmeter);
CRainmeter* GetMainObject() { return m_Rainmeter; }
void RunBang(BANGCOMMAND bang, const WCHAR* arg);
void RunBang(BANGCOMMAND bang, const std::vector<std::wstring>& args);
void MoveMeter(int x, int y, const WCHAR* name);
void HideMeter(const WCHAR* name, bool group = false);
void ShowMeter(const WCHAR* name, bool group = false);
void ToggleMeter(const WCHAR* name, bool group = false);
void UpdateMeter(const WCHAR* name, bool group = false);
void DisableMeasure(const WCHAR* name, bool group = false);
void EnableMeasure(const WCHAR* name, bool group = false);
void ToggleMeasure(const WCHAR* name, bool group = false);
void UpdateMeasure(const WCHAR* name, bool group = false);
void HideMeter(const std::wstring& name, bool group = false);
void ShowMeter(const std::wstring& name, bool group = false);
void ToggleMeter(const std::wstring& name, bool group = false);
void MoveMeter(const std::wstring& name, int x, int y);
void UpdateMeter(const std::wstring& name, bool group = false);
void DisableMeasure(const std::wstring& name, bool group = false);
void EnableMeasure(const std::wstring& name, bool group = false);
void ToggleMeasure(const std::wstring& name, bool group = false);
void UpdateMeasure(const std::wstring& name, bool group = false);
void Refresh(bool init, bool all = false);
void Redraw();
void SetOption(const WCHAR* name, bool group);
void SetOption(const std::wstring& section, const std::wstring& option, const std::wstring& value, bool group);
void SetMouseLeaveEvent(bool cancel);
@ -190,8 +189,10 @@ public:
void ChangeZPos(ZPOSITION zPos, bool all = false);
void ChangeSingleZPos(ZPOSITION zPos, bool all = false);
void FadeWindow(int from, int to);
void HideFade();
void ShowFade();
void ResizeBlur(const WCHAR* arg, int mode);
void ResizeBlur(const std::wstring& arg, int mode);
bool IsBlur() { return m_Blur; }
void SetBlur(bool b) { m_Blur = b; }
@ -443,7 +444,6 @@ private:
std::list<CMeasure*> m_Measures; // All the measures
std::list<CMeter*> m_Meters; // All the meters
const std::wstring m_SkinPath; // Path of the skin folder
const std::wstring m_SkinName; // Name of the current skin folder
const std::wstring m_SkinIniFile; // Name of the current skin iniFile

View File

@ -214,51 +214,40 @@ std::vector<std::wstring> CRainmeter::ParseString(LPCTSTR str)
** Parses Bang args
**
*/
void CRainmeter::BangWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs)
void CRainmeter::BangWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs, CMeterWindow* meterWindow)
{
std::vector<std::wstring> subStrings = ParseString(arg);
size_t subStringsSize = subStrings.size();
std::wstring config;
std::wstring argument;
// Don't include the config name from the arg if there is one
for (size_t i = 0; i < numOfArgs; ++i)
{
if (i != 0) argument += L' ';
if (i < subStringsSize)
{
argument += subStrings[i];
}
}
const size_t subStringsSize = subStrings.size();
if (subStringsSize >= numOfArgs)
{
if (subStringsSize > numOfArgs)
if (subStringsSize == numOfArgs && meterWindow)
{
config = subStrings[numOfArgs];
meterWindow->RunBang(bang, subStrings);
}
if (!config.empty() && (config.size() != 1 || config[0] != L'*'))
else // if (subStringsSize > numOfArgs)
{
// Config defined, so bang only that
CMeterWindow* meterWindow = GetMeterWindow(config);
if (meterWindow)
const std::wstring& config = subStrings[numOfArgs];
if (!config.empty() && (config.length() != 1 || config[0] != L'*'))
{
meterWindow->RunBang(bang, argument.c_str());
CMeterWindow* meterWindow = GetMeterWindow(config);
if (meterWindow)
{
meterWindow->RunBang(bang, subStrings);
}
else
{
LogWithArgs(LOG_ERROR, L"Bang: Config \"%s\" not found", config.c_str());
}
}
else
{
LogWithArgs(LOG_ERROR, L"Bang: Config \"%s\" not found", config.c_str());
}
}
else
{
// No config defined -> apply to all.
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_Meters.begin();
for (; iter != m_Meters.end(); ++iter)
{
((*iter).second)->RunBang(bang, argument.c_str());
// No config defined -> apply to all.
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_Meters.begin();
for (; iter != m_Meters.end(); ++iter)
{
((*iter).second)->RunBang(bang, subStrings);
}
}
}
}
@ -274,7 +263,7 @@ void CRainmeter::BangWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfAr
** Parses Bang args for Group
**
*/
void CRainmeter::BangGroupWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs)
void CRainmeter::BangGroupWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs, CMeterWindow* meterWindow)
{
std::vector<std::wstring> subStrings = ParseString(arg);
@ -294,7 +283,7 @@ void CRainmeter::BangGroupWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t nu
}
argument += (*iter).second->GetSkinName();
argument += L'"';
BangWithArgs(bang, argument.c_str(), numOfArgs);
BangWithArgs(bang, argument.c_str(), numOfArgs, meterWindow);
}
}
else
@ -478,10 +467,23 @@ void CRainmeter::Bang_TrayMenu()
** !WriteKeyValue bang
**
*/
void CRainmeter::Bang_WriteKeyValue(const WCHAR* arg)
void CRainmeter::Bang_WriteKeyValue(const WCHAR* arg, CMeterWindow* meterWindow)
{
std::vector<std::wstring> subStrings = ParseString(arg);
if (subStrings.size() < 4)
{
if (!meterWindow) return;
// Add the config filepath to the args
std::wstring path;
path += m_SkinPath;
path += meterWindow->GetSkinName();
path += L'\\';
path += meterWindow->GetSkinIniFile();
subStrings.push_back(std::move(path));
}
if (subStrings.size() > 3)
{
const std::wstring& strIniFile = subStrings[3];
@ -1064,7 +1066,7 @@ void CRainmeter::ActivateConfig(int configIndex, int iniIndex)
m_ConfigStrings[configIndex].active = iniIndex + 1;
WriteActive(skinConfig, iniIndex);
CreateMeterWindow(m_SkinPath, skinConfig, skinIniFile);
CreateMeterWindow(skinConfig, skinIniFile);
}
}
@ -1125,9 +1127,9 @@ void CRainmeter::WriteActive(const std::wstring& config, int iniIndex)
WritePrivateProfileString(config.c_str(), L"Active", buffer, m_IniFile.c_str());
}
void CRainmeter::CreateMeterWindow(const std::wstring& path, const std::wstring& config, const std::wstring& iniFile)
void CRainmeter::CreateMeterWindow(const std::wstring& config, const std::wstring& iniFile)
{
CMeterWindow* mw = new CMeterWindow(path, config, iniFile);
CMeterWindow* mw = new CMeterWindow(config, iniFile);
if (mw)
{
@ -1186,7 +1188,7 @@ bool CRainmeter::DeleteMeterWindow(CMeterWindow* meterWindow, bool bLater)
if (meterWindow)
{
m_DelayDeleteList.push_back(meterWindow);
meterWindow->RunBang(BANG_HIDEFADE, NULL); // Fade out the window
meterWindow->HideFade();
}
}
else
@ -1524,309 +1526,311 @@ void CRainmeter::ScanForThemes(const std::wstring& path)
}
}
BOOL CRainmeter::ExecuteBang(const std::wstring& bang, const std::wstring& arg, CMeterWindow* meterWindow)
void CRainmeter::ExecuteBang(const std::wstring& name, std::wstring& arg, CMeterWindow* meterWindow)
{
const WCHAR* name = bang.c_str();
const WCHAR* bang = name.c_str();
const WCHAR* args = arg.c_str();
// Skip "!Rainmeter" or "!"
name += (_wcsnicmp(name, L"!Rainmeter", 10) == 0) ? 10 : 1;
if (_wcsicmp(name, L"Refresh") == 0)
if (_wcsnicmp(bang, L"Rainmeter", 9) == 0)
{
BangWithArgs(BANG_REFRESH, args, 0);
// Skip "Rainmeter"
bang += 9;
}
else if (_wcsicmp(name, L"RefreshApp") == 0)
if (_wcsicmp(bang, L"Refresh") == 0)
{
BangWithArgs(BANG_REFRESH, args, 0, meterWindow);
}
else if (_wcsicmp(bang, L"RefreshApp") == 0)
{
// Refresh needs to be delayed since it crashes if done during Update()
PostMessage(GetTrayWindow()->GetWindow(), WM_TRAY_DELAYED_REFRESH_ALL, (WPARAM)NULL, (LPARAM)NULL);
}
else if (_wcsicmp(name, L"Redraw") == 0)
else if (_wcsicmp(bang, L"Redraw") == 0)
{
BangWithArgs(BANG_REDRAW, args, 0);
BangWithArgs(BANG_REDRAW, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"Update") == 0)
else if (_wcsicmp(bang, L"Update") == 0)
{
BangWithArgs(BANG_UPDATE, args, 0);
BangWithArgs(BANG_UPDATE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"Hide") == 0)
else if (_wcsicmp(bang, L"Hide") == 0)
{
BangWithArgs(BANG_HIDE, args, 0);
BangWithArgs(BANG_HIDE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"Show") == 0)
else if (_wcsicmp(bang, L"Show") == 0)
{
BangWithArgs(BANG_SHOW, args, 0);
BangWithArgs(BANG_SHOW, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"Toggle") == 0)
else if (_wcsicmp(bang, L"Toggle") == 0)
{
BangWithArgs(BANG_TOGGLE, args, 0);
BangWithArgs(BANG_TOGGLE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"HideFade") == 0)
else if (_wcsicmp(bang, L"HideFade") == 0)
{
BangWithArgs(BANG_HIDEFADE, args, 0);
BangWithArgs(BANG_HIDEFADE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"ShowFade") == 0)
else if (_wcsicmp(bang, L"ShowFade") == 0)
{
BangWithArgs(BANG_SHOWFADE, args, 0);
BangWithArgs(BANG_SHOWFADE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"ToggleFade") == 0)
else if (_wcsicmp(bang, L"ToggleFade") == 0)
{
BangWithArgs(BANG_TOGGLEFADE, args, 0);
BangWithArgs(BANG_TOGGLEFADE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"HideMeter") == 0)
else if (_wcsicmp(bang, L"HideMeter") == 0)
{
BangWithArgs(BANG_HIDEMETER, args, 1);
BangWithArgs(BANG_HIDEMETER, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"ShowMeter") == 0)
else if (_wcsicmp(bang, L"ShowMeter") == 0)
{
BangWithArgs(BANG_SHOWMETER, args, 1);
BangWithArgs(BANG_SHOWMETER, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"ToggleMeter") == 0)
else if (_wcsicmp(bang, L"ToggleMeter") == 0)
{
BangWithArgs(BANG_TOGGLEMETER, args, 1);
BangWithArgs(BANG_TOGGLEMETER, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"MoveMeter") == 0)
else if (_wcsicmp(bang, L"MoveMeter") == 0)
{
BangWithArgs(BANG_MOVEMETER, args, 3);
BangWithArgs(BANG_MOVEMETER, args, 3, meterWindow);
}
else if (_wcsicmp(name, L"UpdateMeter") == 0)
else if (_wcsicmp(bang, L"UpdateMeter") == 0)
{
BangWithArgs(BANG_UPDATEMETER, args, 1);
BangWithArgs(BANG_UPDATEMETER, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"DisableMeasure") == 0)
else if (_wcsicmp(bang, L"DisableMeasure") == 0)
{
BangWithArgs(BANG_DISABLEMEASURE, args, 1);
BangWithArgs(BANG_DISABLEMEASURE, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"EnableMeasure") == 0)
else if (_wcsicmp(bang, L"EnableMeasure") == 0)
{
BangWithArgs(BANG_ENABLEMEASURE, args, 1);
BangWithArgs(BANG_ENABLEMEASURE, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"ToggleMeasure") == 0)
else if (_wcsicmp(bang, L"ToggleMeasure") == 0)
{
BangWithArgs(BANG_TOGGLEMEASURE, args, 1);
BangWithArgs(BANG_TOGGLEMEASURE, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"UpdateMeasure") == 0)
else if (_wcsicmp(bang, L"UpdateMeasure") == 0)
{
BangWithArgs(BANG_UPDATEMEASURE, args, 1);
BangWithArgs(BANG_UPDATEMEASURE, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"CommandMeasure") == 0)
else if (_wcsicmp(bang, L"CommandMeasure") == 0)
{
BangWithArgs(BANG_COMMANDMEASURE, args, 2);
BangWithArgs(BANG_COMMANDMEASURE, args, 2, meterWindow);
}
else if (_wcsicmp(name, L"ShowBlur") == 0)
else if (_wcsicmp(bang, L"ShowBlur") == 0)
{
BangWithArgs(BANG_SHOWBLUR, args, 0);
BangWithArgs(BANG_SHOWBLUR, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"HideBlur") == 0)
else if (_wcsicmp(bang, L"HideBlur") == 0)
{
BangWithArgs(BANG_HIDEBLUR, args, 0);
BangWithArgs(BANG_HIDEBLUR, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"ToggleBlur") == 0)
else if (_wcsicmp(bang, L"ToggleBlur") == 0)
{
BangWithArgs(BANG_TOGGLEBLUR, args, 0);
BangWithArgs(BANG_TOGGLEBLUR, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"AddBlur") == 0)
else if (_wcsicmp(bang, L"AddBlur") == 0)
{
BangWithArgs(BANG_ADDBLUR, args, 1);
BangWithArgs(BANG_ADDBLUR, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"RemoveBlur") == 0)
else if (_wcsicmp(bang, L"RemoveBlur") == 0)
{
BangWithArgs(BANG_REMOVEBLUR, args, 1);
BangWithArgs(BANG_REMOVEBLUR, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"ActivateConfig") == 0)
else if (_wcsicmp(bang, L"ActivateConfig") == 0)
{
Bang_ActivateConfig(args);
}
else if (_wcsicmp(name, L"DeactivateConfig") == 0)
else if (_wcsicmp(bang, L"DeactivateConfig") == 0)
{
Bang_DeactivateConfig(args);
}
else if (_wcsicmp(name, L"ToggleConfig") == 0)
else if (_wcsicmp(bang, L"ToggleConfig") == 0)
{
Bang_ToggleConfig(args);
}
else if (_wcsicmp(name, L"Move") == 0)
else if (_wcsicmp(bang, L"Move") == 0)
{
BangWithArgs(BANG_MOVE, args, 2);
BangWithArgs(BANG_MOVE, args, 2, meterWindow);
}
else if (_wcsicmp(name, L"ZPos") == 0 || _wcsicmp(name, L"ChangeZPos") == 0) // For backwards compatibility
else if (_wcsicmp(bang, L"ZPos") == 0 || _wcsicmp(bang, L"ChangeZPos") == 0) // For backwards compatibility
{
BangWithArgs(BANG_ZPOS, args, 1);
BangWithArgs(BANG_ZPOS, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"ClickThrough") == 0)
else if (_wcsicmp(bang, L"ClickThrough") == 0)
{
BangWithArgs(BANG_CLICKTHROUGH, args, 1);
BangWithArgs(BANG_CLICKTHROUGH, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"Draggable") == 0)
else if (_wcsicmp(bang, L"Draggable") == 0)
{
BangWithArgs(BANG_DRAGGABLE, args, 1);
BangWithArgs(BANG_DRAGGABLE, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"SnapEdges") == 0)
else if (_wcsicmp(bang, L"SnapEdges") == 0)
{
BangWithArgs(BANG_SNAPEDGES, args, 1);
BangWithArgs(BANG_SNAPEDGES, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"KeepOnScreen") == 0)
else if (_wcsicmp(bang, L"KeepOnScreen") == 0)
{
BangWithArgs(BANG_KEEPONSCREEN, args, 1);
BangWithArgs(BANG_KEEPONSCREEN, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"SetTransparency") == 0)
else if (_wcsicmp(bang, L"SetTransparency") == 0)
{
BangWithArgs(BANG_SETTRANSPARENCY, args, 1);
BangWithArgs(BANG_SETTRANSPARENCY, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"SetVariable") == 0)
else if (_wcsicmp(bang, L"SetVariable") == 0)
{
BangWithArgs(BANG_SETVARIABLE, args, 2);
BangWithArgs(BANG_SETVARIABLE, args, 2, meterWindow);
}
else if (_wcsicmp(name, L"SetOption") == 0)
else if (_wcsicmp(bang, L"SetOption") == 0)
{
BangWithArgs(BANG_SETOPTION, args, 3);
BangWithArgs(BANG_SETOPTION, args, 3, meterWindow);
}
else if (_wcsicmp(name, L"RefreshGroup") == 0)
else if (_wcsicmp(bang, L"RefreshGroup") == 0)
{
BangGroupWithArgs(BANG_REFRESH, args, 0);
BangGroupWithArgs(BANG_REFRESH, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"UpdateGroup") == 0)
else if (_wcsicmp(bang, L"UpdateGroup") == 0)
{
BangGroupWithArgs(BANG_UPDATE, args, 0);
BangGroupWithArgs(BANG_UPDATE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"RedrawGroup") == 0)
else if (_wcsicmp(bang, L"RedrawGroup") == 0)
{
BangGroupWithArgs(BANG_REDRAW, args, 0);
BangGroupWithArgs(BANG_REDRAW, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"HideGroup") == 0)
else if (_wcsicmp(bang, L"HideGroup") == 0)
{
BangGroupWithArgs(BANG_HIDE, args, 0);
BangGroupWithArgs(BANG_HIDE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"ShowGroup") == 0)
else if (_wcsicmp(bang, L"ShowGroup") == 0)
{
BangGroupWithArgs(BANG_SHOW, args, 0);
BangGroupWithArgs(BANG_SHOW, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"ToggleGroup") == 0)
else if (_wcsicmp(bang, L"ToggleGroup") == 0)
{
BangGroupWithArgs(BANG_TOGGLE, args, 0);
BangGroupWithArgs(BANG_TOGGLE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"HideFadeGroup") == 0)
else if (_wcsicmp(bang, L"HideFadeGroup") == 0)
{
BangGroupWithArgs(BANG_HIDEFADE, args, 0);
BangGroupWithArgs(BANG_HIDEFADE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"ShowFadeGroup") == 0)
else if (_wcsicmp(bang, L"ShowFadeGroup") == 0)
{
BangGroupWithArgs(BANG_SHOWFADE, args, 0);
BangGroupWithArgs(BANG_SHOWFADE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"ToggleFadeGroup") == 0)
else if (_wcsicmp(bang, L"ToggleFadeGroup") == 0)
{
BangGroupWithArgs(BANG_TOGGLEFADE, args, 0);
BangGroupWithArgs(BANG_TOGGLEFADE, args, 0, meterWindow);
}
else if (_wcsicmp(name, L"HideMeterGroup") == 0)
else if (_wcsicmp(bang, L"HideMeterGroup") == 0)
{
BangWithArgs(BANG_HIDEMETERGROUP, args, 1);
BangWithArgs(BANG_HIDEMETERGROUP, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"ShowMeterGroup") == 0)
else if (_wcsicmp(bang, L"ShowMeterGroup") == 0)
{
BangWithArgs(BANG_SHOWMETERGROUP, args, 1);
BangWithArgs(BANG_SHOWMETERGROUP, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"ToggleMeterGroup") == 0)
else if (_wcsicmp(bang, L"ToggleMeterGroup") == 0)
{
BangWithArgs(BANG_TOGGLEMETERGROUP, args, 1);
BangWithArgs(BANG_TOGGLEMETERGROUP, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"UpdateMeterGroup") == 0)
else if (_wcsicmp(bang, L"UpdateMeterGroup") == 0)
{
BangWithArgs(BANG_UPDATEMETERGROUP, args, 1);
BangWithArgs(BANG_UPDATEMETERGROUP, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"DisableMeasureGroup") == 0)
else if (_wcsicmp(bang, L"DisableMeasureGroup") == 0)
{
BangWithArgs(BANG_DISABLEMEASUREGROUP, args, 1);
BangWithArgs(BANG_DISABLEMEASUREGROUP, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"EnableMeasureGroup") == 0)
else if (_wcsicmp(bang, L"EnableMeasureGroup") == 0)
{
BangWithArgs(BANG_ENABLEMEASUREGROUP, args, 1);
BangWithArgs(BANG_ENABLEMEASUREGROUP, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"ToggleMeasureGroup") == 0)
else if (_wcsicmp(bang, L"ToggleMeasureGroup") == 0)
{
BangWithArgs(BANG_TOGGLEMEASUREGROUP, args, 1);
BangWithArgs(BANG_TOGGLEMEASUREGROUP, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"UpdateMeasureGroup") == 0)
else if (_wcsicmp(bang, L"UpdateMeasureGroup") == 0)
{
BangWithArgs(BANG_UPDATEMEASUREGROUP, args, 1);
BangWithArgs(BANG_UPDATEMEASUREGROUP, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"DeactivateConfigGroup") == 0)
else if (_wcsicmp(bang, L"DeactivateConfigGroup") == 0)
{
Bang_DeactivateConfigGroup(args);
}
else if (_wcsicmp(name, L"ZPosGroup") == 0)
else if (_wcsicmp(bang, L"ZPosGroup") == 0)
{
BangGroupWithArgs(BANG_ZPOS, args, 1);
BangGroupWithArgs(BANG_ZPOS, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"ClickThroughGroup") == 0)
else if (_wcsicmp(bang, L"ClickThroughGroup") == 0)
{
BangGroupWithArgs(BANG_CLICKTHROUGH, args, 1);
BangGroupWithArgs(BANG_CLICKTHROUGH, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"DraggableGroup") == 0)
else if (_wcsicmp(bang, L"DraggableGroup") == 0)
{
BangGroupWithArgs(BANG_DRAGGABLE, args, 1);
BangGroupWithArgs(BANG_DRAGGABLE, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"SnapEdgesGroup") == 0)
else if (_wcsicmp(bang, L"SnapEdgesGroup") == 0)
{
BangGroupWithArgs(BANG_SNAPEDGES, args, 1);
BangGroupWithArgs(BANG_SNAPEDGES, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"KeepOnScreenGroup") == 0)
else if (_wcsicmp(bang, L"KeepOnScreenGroup") == 0)
{
BangGroupWithArgs(BANG_KEEPONSCREEN, args, 1);
BangGroupWithArgs(BANG_KEEPONSCREEN, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"SetTransparencyGroup") == 0)
else if (_wcsicmp(bang, L"SetTransparencyGroup") == 0)
{
BangGroupWithArgs(BANG_SETTRANSPARENCY, args, 1);
BangGroupWithArgs(BANG_SETTRANSPARENCY, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"SetVariableGroup") == 0)
else if (_wcsicmp(bang, L"SetVariableGroup") == 0)
{
BangGroupWithArgs(BANG_SETVARIABLE, args, 2);
BangGroupWithArgs(BANG_SETVARIABLE, args, 2, meterWindow);
}
else if (_wcsicmp(name, L"SetOptionGroup") == 0)
else if (_wcsicmp(bang, L"SetOptionGroup") == 0)
{
BangWithArgs(BANG_SETOPTIONGROUP, args, 3);
BangWithArgs(BANG_SETOPTIONGROUP, args, 3, meterWindow);
}
else if (_wcsicmp(name, L"WriteKeyValue") == 0)
else if (_wcsicmp(bang, L"WriteKeyValue") == 0)
{
Bang_WriteKeyValue(args);
Bang_WriteKeyValue(args, meterWindow);
}
else if (_wcsicmp(name, L"PluginBang") == 0)
else if (_wcsicmp(bang, L"PluginBang") == 0)
{
BangWithArgs(BANG_PLUGIN, args, 1);
BangWithArgs(BANG_PLUGIN, args, 1, meterWindow);
}
else if (_wcsicmp(name, L"SetClip") == 0)
else if (_wcsicmp(bang, L"SetClip") == 0)
{
Bang_SetClip(args);
}
else if (_wcsicmp(name, L"About") == 0)
else if (_wcsicmp(bang, L"About") == 0)
{
CDialogAbout::Open(args);
}
else if (_wcsicmp(name, L"Manage") == 0)
else if (_wcsicmp(bang, L"Manage") == 0)
{
CDialogManage::Open(args);
}
else if (_wcsicmp(name, L"SkinMenu") == 0)
else if (_wcsicmp(bang, L"SkinMenu") == 0)
{
Bang_SkinMenu(args);
}
else if (_wcsicmp(name, L"TrayMenu") == 0)
else if (_wcsicmp(bang, L"TrayMenu") == 0)
{
Bang_TrayMenu();
}
else if (_wcsicmp(name, L"ResetStats") == 0)
else if (_wcsicmp(bang, L"ResetStats") == 0)
{
ResetStats();
}
else if (_wcsicmp(name, L"Quit") == 0)
else if (_wcsicmp(bang, L"Quit") == 0)
{
// Quit needs to be delayed since it crashes if done during Update()
PostMessage(GetTrayWindow()->GetWindow(), WM_COMMAND, MAKEWPARAM(ID_CONTEXT_QUIT, 0), (LPARAM)NULL);
}
else if (_wcsicmp(bang.c_str(), L"!Execute") == 0)
else if (_wcsicmp(name.c_str(), L"Execute") == 0)
{
// Special case for multibang execution
std::wstring::size_type start = std::wstring::npos;
std::wstring::size_type end = std::wstring::npos;
int count = 0;
for (size_t i = 0, isize = arg.size(); i < isize; ++i)
{
@ -1844,12 +1848,13 @@ BOOL CRainmeter::ExecuteBang(const std::wstring& bang, const std::wstring& arg,
if (count == 0 && start != std::wstring::npos)
{
end = i;
// Change ] to NULL
arg[i] = L'\0';
std::wstring command = arg.substr(start + 1, end - (start + 1));
// Skip leading whitespace
std::wstring::size_type notwhite = command.find_first_not_of(L" \t\r\n");
ExecuteCommand(command.c_str() + notwhite, meterWindow);
// Skip whitespace
start = arg.find_first_not_of(L" \t\r\n", start + 1, 4);
ExecuteCommand(arg.c_str() + start, meterWindow);
}
}
else if (args[i] == L'"' && isize > (i + 2) && args[i + 1] == L'"' && args[i + 2] == L'"')
@ -1864,18 +1869,15 @@ BOOL CRainmeter::ExecuteBang(const std::wstring& bang, const std::wstring& arg,
}
}
}
else if (_wcsicmp(name, L"LsBoxHook") == 0)
else if (_wcsicmp(bang, L"LsBoxHook") == 0)
{
// Deprecated.
}
else
{
std::wstring error = L"Unknown bang: " + bang;
std::wstring error = L"Unknown bang: " + name;
Log(LOG_ERROR, error.c_str());
return FALSE;
}
return TRUE;
}
/*
@ -1886,94 +1888,79 @@ BOOL CRainmeter::ExecuteBang(const std::wstring& bang, const std::wstring& arg,
*/
void CRainmeter::ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow)
{
std::wstring strCommand = command;
if (meterWindow && _wcsnicmp(L"!execute", command, 8) != 0)
if (command[0] == L'!') // Bang
{
meterWindow->GetParser().ReplaceMeasures(strCommand);
}
++command; // Skip "!"
std::wstring bang, arg;
if (!strCommand.empty())
{
command = strCommand.c_str();
if (command[0] == L'!') // Bang
// Find the first space
const WCHAR* pos = wcschr(command, L' ');
if (pos)
{
if (meterWindow)
{
// Fake WM_COPYDATA to deliver bangs
COPYDATASTRUCT cds;
cds.cbData = 1; // Size doesn't matter as long as not empty
cds.dwData = 1;
cds.lpData = (void*)command;
meterWindow->OnCopyData(WM_COPYDATA, NULL, (LPARAM)&cds);
}
else
{
std::wstring bang, arg;
size_t pos = strCommand.find(L' ');
if (pos != std::wstring::npos)
{
bang.assign(strCommand, 0, pos);
strCommand.erase(0, pos + 1);
arg = strCommand;
}
else
{
bang = strCommand;
}
ExecuteBang(bang, arg, meterWindow);
}
bang.assign(command, 0, pos - command);
arg.assign(pos + 1);
}
else
{
// Check for built-ins
if (_wcsnicmp(L"PLAY", command, 4) == 0)
{
if (command[4] == L' ' || // PLAY
_wcsnicmp(L"LOOP ", &command[4], 5) == 0) // PLAYLOOP
{
command += 4; // Skip PLAY
DWORD flags = SND_FILENAME | SND_ASYNC;
if (command[0] != L' ')
{
flags |= SND_LOOP | SND_NODEFAULT;
command += 4; // Skip LOOP
}
++command; // Skip the space
if (command[0] != L'\0')
{
strCommand = command;
// Strip the quotes
std::wstring::size_type len = strCommand.length();
if (len >= 2 && strCommand[0] == L'"' && strCommand[len - 1] == L'"')
{
len -= 2;
strCommand.assign(strCommand, 1, len);
}
if (meterWindow)
{
meterWindow->MakePathAbsolute(strCommand);
}
PlaySound(strCommand.c_str(), NULL, flags);
}
return;
}
else if (_wcsnicmp(L"STOP", &command[4], 4) == 0) // PLAYSTOP
{
PlaySound(NULL, NULL, SND_PURGE);
return;
}
}
// Run command
RunCommand(NULL, command, SW_SHOWNORMAL);
bang = command;
}
if (meterWindow && _wcsnicmp(L"Execute", command, 7) != 0)
{
meterWindow->GetParser().ReplaceMeasures(bang);
}
ExecuteBang(bang, arg, meterWindow);
}
else
{
// Check for built-ins
if (_wcsnicmp(L"PLAY", command, 4) == 0)
{
if (command[4] == L' ' || // PLAY
_wcsnicmp(L"LOOP ", &command[4], 5) == 0) // PLAYLOOP
{
command += 4; // Skip PLAY
DWORD flags = SND_FILENAME | SND_ASYNC;
if (command[0] != L' ')
{
flags |= SND_LOOP | SND_NODEFAULT;
command += 4; // Skip LOOP
}
++command; // Skip the space
if (command[0] != L'\0')
{
std::wstring sound = command;
// Strip the quotes
std::wstring::size_type len = sound.length();
if (len >= 2 && sound[0] == L'"' && sound[len - 1] == L'"')
{
len -= 2;
sound.assign(sound, 1, len);
}
if (meterWindow)
{
meterWindow->MakePathAbsolute(sound);
}
PlaySound(sound.c_str(), NULL, flags);
}
return;
}
else if (_wcsnicmp(L"STOP", &command[4], 4) == 0) // PLAYSTOP
{
PlaySound(NULL, NULL, SND_PURGE);
return;
}
}
// Run command
RunCommand(NULL, command, SW_SHOWNORMAL);
}
}

View File

@ -198,7 +198,7 @@ public:
const std::wstring& GetTrayExecuteDL() { return m_TrayExecuteDL; }
const std::wstring& GetTrayExecuteDM() { return m_TrayExecuteDM; }
BOOL ExecuteBang(const std::wstring& bang, const std::wstring& arg, CMeterWindow* meterWindow);
void ExecuteBang(const std::wstring& name, std::wstring& arg, CMeterWindow* meterWindow);
void ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow);
void RefreshAll();
@ -215,8 +215,8 @@ public:
friend class CDialogManage;
private:
void BangWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs);
void BangGroupWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs);
void BangWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs, CMeterWindow* meterWindow);
void BangGroupWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs, CMeterWindow* meterWindow);
void Bang_ActivateConfig(const WCHAR* arg);
void Bang_DeactivateConfig(const WCHAR* arg);
void Bang_ToggleConfig(const WCHAR* arg);
@ -224,10 +224,10 @@ private:
void Bang_SetClip(const WCHAR* arg);
void Bang_SkinMenu(const WCHAR* arg);
void Bang_TrayMenu();
void Bang_WriteKeyValue(const WCHAR* arg);
void Bang_WriteKeyValue(const WCHAR* arg, CMeterWindow* meterWindow);
void ActivateActiveConfigs();
void CreateMeterWindow(const std::wstring& path, const std::wstring& config, const std::wstring& iniFile);
void CreateMeterWindow(const std::wstring& config, const std::wstring& iniFile);
bool DeleteMeterWindow(CMeterWindow* meterWindow, bool bLater);
void WriteActive(const std::wstring& config, int iniIndex);
void ScanForConfigs(const std::wstring& path);