2009-02-10 18:37:48 +00:00
|
|
|
/*
|
|
|
|
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2009-10-07 16:45:14 +00:00
|
|
|
#include "StdAfx.h"
|
2009-02-10 18:37:48 +00:00
|
|
|
#include "Rainmeter.h"
|
2011-02-07 08:02:12 +00:00
|
|
|
#include "TrayWindow.h"
|
2010-03-20 19:40:30 +00:00
|
|
|
#include "System.h"
|
2009-02-10 18:37:48 +00:00
|
|
|
#include "Error.h"
|
2011-08-28 10:58:26 +00:00
|
|
|
#include "DialogAbout.h"
|
|
|
|
#include "DialogManage.h"
|
2009-02-10 18:37:48 +00:00
|
|
|
#include "MeasureNet.h"
|
2009-10-07 16:45:14 +00:00
|
|
|
#include "MeterString.h"
|
2011-02-07 08:02:12 +00:00
|
|
|
#include "resource.h"
|
2009-02-10 18:37:48 +00:00
|
|
|
#include "UpdateCheck.h"
|
2011-02-07 08:02:12 +00:00
|
|
|
#include "../Version.h"
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-01-30 09:31:41 +00:00
|
|
|
#include "DisableThreadLibraryCalls.h" // contains DllMain entry point
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
using namespace Gdiplus;
|
|
|
|
|
|
|
|
CRainmeter* Rainmeter; // The module
|
|
|
|
|
2011-07-06 20:31:20 +00:00
|
|
|
bool CRainmeter::c_DummyLitestep = false;
|
2009-02-10 18:37:48 +00:00
|
|
|
std::wstring CRainmeter::c_CmdLine;
|
|
|
|
|
|
|
|
/*
|
|
|
|
** ParseString
|
|
|
|
**
|
|
|
|
** Splits the given string into substrings
|
|
|
|
**
|
|
|
|
*/
|
2010-08-03 15:10:42 +00:00
|
|
|
std::vector<std::wstring> CRainmeter::ParseString(LPCTSTR str)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
std::vector<std::wstring> result;
|
|
|
|
if (str)
|
|
|
|
{
|
|
|
|
std::wstring arg = str;
|
|
|
|
|
|
|
|
// Split the argument between first space.
|
|
|
|
// Or if string is in quotes, the after the second quote.
|
|
|
|
|
2011-08-17 05:56:46 +00:00
|
|
|
size_t pos;
|
|
|
|
std::wstring newStr;
|
|
|
|
while ((pos = arg.find_first_not_of(L' ')) != std::wstring::npos)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-08-17 05:56:46 +00:00
|
|
|
if (arg[pos] == L'"')
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-08-17 18:16:13 +00:00
|
|
|
if (arg.size() > (pos + 2) &&
|
|
|
|
arg[pos + 1] == L'"' && arg[pos + 2] == L'"')
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
|
|
|
// Eat found quotes and finding ending """
|
|
|
|
arg.erase(0, pos + 3);
|
2011-08-17 18:16:13 +00:00
|
|
|
|
|
|
|
size_t extra = 4;
|
|
|
|
if ((pos = arg.find(L"\"\"\" ")) == std::wstring::npos)
|
|
|
|
{
|
|
|
|
extra = 3;
|
|
|
|
pos = arg.find(L"\"\"\"");
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-08-17 05:56:46 +00:00
|
|
|
if (pos != std::wstring::npos)
|
|
|
|
{
|
|
|
|
newStr.assign(arg, 0, pos);
|
2011-08-17 18:16:13 +00:00
|
|
|
arg.erase(0, pos + extra);
|
2011-08-17 05:56:46 +00:00
|
|
|
|
|
|
|
result.push_back(newStr);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Skip stripping quotes
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Eat found quote and find ending quote
|
|
|
|
arg.erase(0, pos + 1);
|
2011-08-17 18:16:13 +00:00
|
|
|
pos = arg.find_first_of(L'"');
|
2011-08-17 05:56:46 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-08-17 05:56:46 +00:00
|
|
|
if (pos > 0)
|
|
|
|
{
|
|
|
|
// Eat everything until non-space (and non-quote) char
|
|
|
|
arg.erase(0, pos);
|
|
|
|
}
|
2011-01-27 15:23:15 +00:00
|
|
|
|
2011-08-17 05:56:46 +00:00
|
|
|
// Find the second quote
|
|
|
|
pos = arg.find_first_of(L' ');
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2011-08-17 05:56:46 +00:00
|
|
|
if (pos != std::wstring::npos)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-08-17 05:56:46 +00:00
|
|
|
newStr.assign(arg, 0, pos);
|
|
|
|
arg.erase(0, pos + 1);
|
|
|
|
|
|
|
|
// Strip quotes
|
2011-08-17 18:16:13 +00:00
|
|
|
while ((pos = newStr.find(L'"')) != std::wstring::npos)
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
|
|
|
newStr.erase(pos, 1);
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
result.push_back(newStr);
|
|
|
|
}
|
2011-08-17 18:16:13 +00:00
|
|
|
else // quote or space not found
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (arg.size() > 0)
|
|
|
|
{
|
2011-08-17 18:16:13 +00:00
|
|
|
// Strip quotes
|
|
|
|
while ((pos = arg.find(L'"')) != std::wstring::npos)
|
|
|
|
{
|
|
|
|
arg.erase(pos, 1);
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
result.push_back(arg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2011-03-29 19:21:57 +00:00
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
/*
|
|
|
|
** initModuleEx
|
|
|
|
**
|
|
|
|
** This is called when the plugin is initialized
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
int initModuleEx(HWND ParentWnd, HINSTANCE dllInst, LPCSTR szPath)
|
|
|
|
{
|
2011-09-08 14:39:25 +00:00
|
|
|
int result = 1;
|
2011-03-29 19:21:57 +00:00
|
|
|
|
|
|
|
try
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-09-08 14:39:25 +00:00
|
|
|
Rainmeter = new CRainmeter;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
if (Rainmeter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-09-08 14:39:25 +00:00
|
|
|
result = Rainmeter->Initialize(ParentWnd, dllInst, szPath);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-01-27 15:23:15 +00:00
|
|
|
}
|
2011-09-08 14:39:25 +00:00
|
|
|
catch (CError& error)
|
2011-01-27 15:23:15 +00:00
|
|
|
{
|
2009-02-10 18:37:48 +00:00
|
|
|
MessageBox(ParentWnd, error.GetString().c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION);
|
|
|
|
}
|
|
|
|
|
2011-09-08 14:39:25 +00:00
|
|
|
return result;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** quitModule
|
|
|
|
**
|
|
|
|
** This is called when the plugin quits.
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void quitModule(HINSTANCE dllInst)
|
|
|
|
{
|
2011-03-29 19:21:57 +00:00
|
|
|
if (Rainmeter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
Rainmeter->Quit(dllInst);
|
|
|
|
delete Rainmeter;
|
|
|
|
Rainmeter = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Initialize
|
|
|
|
**
|
|
|
|
** Init Rainmeter
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void Initialize(bool DummyLS, LPCTSTR CmdLine)
|
|
|
|
{
|
|
|
|
CRainmeter::SetDummyLitestep(DummyLS);
|
|
|
|
CRainmeter::SetCommandLine(CmdLine);
|
|
|
|
}
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2010-12-11 16:30:49 +00:00
|
|
|
** ExecuteBang
|
|
|
|
**
|
|
|
|
** Runs a bang command. This is called from the main application
|
|
|
|
** when a command is given as a command line argument.
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void ExecuteBang(LPCTSTR szBang)
|
|
|
|
{
|
2011-02-16 14:46:17 +00:00
|
|
|
if (Rainmeter && szBang)
|
|
|
|
{
|
|
|
|
// ExecuteBang needs to be delayed since it crashes if done during processing.
|
|
|
|
// The receiver must free a given string buffer (lParam) by using free().
|
|
|
|
WCHAR* bang = _wcsdup(szBang);
|
|
|
|
PostMessage(Rainmeter->GetTrayWindow()->GetWindow(), WM_TRAY_DELAYED_EXECUTE, (WPARAM)NULL, (LPARAM)bang);
|
|
|
|
}
|
2010-12-11 16:30:49 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
** ReadConfigString
|
|
|
|
**
|
|
|
|
** Reads a config string. Used by the plugins.
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
LPCTSTR ReadConfigString(LPCTSTR section, LPCTSTR key, LPCTSTR defValue)
|
|
|
|
{
|
2011-03-29 19:21:57 +00:00
|
|
|
if (Rainmeter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
CConfigParser* parser = Rainmeter->GetCurrentParser();
|
|
|
|
if (parser)
|
|
|
|
{
|
2009-08-26 19:29:49 +00:00
|
|
|
return parser->ReadString(section, key, defValue, false).c_str();
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-03-29 19:21:57 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-12-16 20:35:44 +00:00
|
|
|
/*
|
|
|
|
** PluginBridge
|
|
|
|
**
|
|
|
|
** Receives a command and data from a plugin and returns a result. Used by plugins.
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
LPCTSTR PluginBridge(LPCTSTR _sCommand, LPCTSTR _sData)
|
|
|
|
{
|
2011-03-29 19:21:57 +00:00
|
|
|
if (Rainmeter)
|
2010-12-16 20:35:44 +00:00
|
|
|
{
|
|
|
|
static std::wstring result;
|
|
|
|
|
2011-06-02 01:54:05 +00:00
|
|
|
if (_sCommand == NULL || *_sCommand == L'\0')
|
|
|
|
{
|
|
|
|
return L"noop";
|
|
|
|
}
|
|
|
|
|
2010-12-16 20:35:44 +00:00
|
|
|
if (_sData == NULL) _sData = L"";
|
|
|
|
|
|
|
|
std::wstring sCommand = _sCommand;
|
|
|
|
std::transform(sCommand.begin(), sCommand.end(), sCommand.begin(), ::towlower);
|
|
|
|
|
|
|
|
// Command GetConfig
|
|
|
|
// Data unquoted full path and filename given to the plugin on initialize
|
|
|
|
// (note: this is CaSe-SeNsItIvE!)
|
|
|
|
// Execution none
|
|
|
|
// Result the config name if found or a blank string if not
|
|
|
|
if (sCommand == L"getconfig")
|
|
|
|
{
|
|
|
|
// returns the config name, lookup by INI file
|
|
|
|
|
2011-06-02 01:54:05 +00:00
|
|
|
CMeterWindow *meterWindow = Rainmeter->GetMeterWindowByINI(_sData);
|
2010-12-16 20:35:44 +00:00
|
|
|
if (meterWindow)
|
|
|
|
{
|
2011-02-15 17:39:24 +00:00
|
|
|
result = L"\"";
|
|
|
|
result += meterWindow->GetSkinName();
|
|
|
|
result += L"\"";
|
2010-12-16 20:35:44 +00:00
|
|
|
return result.c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
return L"";
|
|
|
|
}
|
|
|
|
|
2011-06-02 01:54:05 +00:00
|
|
|
// Command GetWindow
|
|
|
|
// Data [the config name]
|
|
|
|
// Execution none
|
|
|
|
// Result the HWND to the specified config window if found, 'error' otherwise
|
|
|
|
if (sCommand == L"getwindow")
|
|
|
|
{
|
|
|
|
std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData);
|
|
|
|
|
|
|
|
if (subStrings.size() >= 1)
|
|
|
|
{
|
|
|
|
const std::wstring& config = subStrings[0];
|
|
|
|
|
|
|
|
CMeterWindow *meterWindow = Rainmeter->GetMeterWindow(config);
|
|
|
|
if (meterWindow)
|
|
|
|
{
|
|
|
|
WCHAR buf1[64];
|
|
|
|
_snwprintf_s(buf1, _TRUNCATE, L"%lu", PtrToUlong(meterWindow->GetWindow()));
|
|
|
|
result = buf1;
|
|
|
|
return result.c_str();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return L"error";
|
|
|
|
}
|
|
|
|
|
2010-12-16 20:35:44 +00:00
|
|
|
// Command GetVariable
|
|
|
|
// Data [the config name]
|
|
|
|
// Execution none
|
|
|
|
// Result the value of the variable
|
|
|
|
if (sCommand == L"getvariable")
|
|
|
|
{
|
|
|
|
std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData);
|
|
|
|
|
|
|
|
if (subStrings.size() >= 2)
|
|
|
|
{
|
2010-12-21 04:49:01 +00:00
|
|
|
const std::wstring& config = subStrings[0];
|
2010-12-16 20:35:44 +00:00
|
|
|
|
|
|
|
CMeterWindow *meterWindow = Rainmeter->GetMeterWindow(config);
|
|
|
|
if (meterWindow)
|
|
|
|
{
|
2010-12-21 04:49:01 +00:00
|
|
|
const std::wstring& variable = subStrings[1];
|
2010-12-16 20:35:44 +00:00
|
|
|
std::wstring result_from_parser;
|
|
|
|
|
|
|
|
if (meterWindow->GetParser().GetVariable(variable, result_from_parser))
|
|
|
|
{
|
|
|
|
result = result_from_parser;
|
|
|
|
return result.c_str();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return L"";
|
|
|
|
}
|
|
|
|
|
|
|
|
// Command SetVariable
|
|
|
|
// Data [the config name] [variable data]
|
|
|
|
// Execution the indicated variable is updated
|
|
|
|
// Result 'success' if the config was found, 'error' otherwise
|
|
|
|
if (sCommand == L"setvariable")
|
|
|
|
{
|
|
|
|
std::vector<std::wstring> subStrings = CRainmeter::ParseString(_sData);
|
|
|
|
|
|
|
|
if (subStrings.size() >= 2)
|
|
|
|
{
|
2010-12-21 04:49:01 +00:00
|
|
|
const std::wstring& config = subStrings[0];
|
2010-12-16 20:35:44 +00:00
|
|
|
std::wstring arguments;
|
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
for (size_t i = 1, isize = subStrings.size(); i < isize; ++i)
|
2010-12-16 20:35:44 +00:00
|
|
|
{
|
|
|
|
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";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
result = L"er1/";
|
|
|
|
result += subStrings[0];
|
|
|
|
result += L"/";
|
|
|
|
TCHAR x[100];
|
|
|
|
_snwprintf_s(x, _TRUNCATE, L"%d", subStrings.size());
|
|
|
|
result += x;
|
|
|
|
return result.c_str();
|
|
|
|
*/
|
|
|
|
return L"error";
|
|
|
|
}
|
|
|
|
|
|
|
|
return L"noop";
|
2011-03-29 19:21:57 +00:00
|
|
|
}
|
2010-12-16 20:35:44 +00:00
|
|
|
|
|
|
|
return L"error:no rainmeter!";
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
/*
|
|
|
|
** BangWithArgs
|
|
|
|
**
|
|
|
|
** Parses Bang args
|
|
|
|
**
|
|
|
|
*/
|
2009-02-14 10:11:28 +00:00
|
|
|
void BangWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-03-29 19:21:57 +00:00
|
|
|
if (Rainmeter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-08-03 15:10:42 +00:00
|
|
|
std::vector<std::wstring> subStrings = CRainmeter::ParseString(arg);
|
2011-02-15 13:22:19 +00:00
|
|
|
size_t subStringsSize = subStrings.size();
|
2009-02-10 18:37:48 +00:00
|
|
|
std::wstring config;
|
|
|
|
std::wstring argument;
|
|
|
|
|
|
|
|
// Don't include the config name from the arg if there is one
|
2010-03-30 22:37:05 +00:00
|
|
|
for (size_t i = 0; i < numOfArgs; ++i)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
if (i != 0) argument += L" ";
|
2011-02-15 13:22:19 +00:00
|
|
|
if (i < subStringsSize)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
argument += subStrings[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
if (subStringsSize >= numOfArgs)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
if (subStringsSize > numOfArgs)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
config = subStrings[numOfArgs];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((!config.empty()) && (config != L"*"))
|
|
|
|
{
|
|
|
|
// Config defined, so bang only that
|
|
|
|
CMeterWindow* meterWindow = Rainmeter->GetMeterWindow(config);
|
|
|
|
|
|
|
|
if (meterWindow)
|
|
|
|
{
|
|
|
|
if (bang == BANG_LSHOOK)
|
|
|
|
{
|
|
|
|
// LsHook is a special case
|
|
|
|
meterWindow->RunBang(bang, arg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
meterWindow->RunBang(bang, argument.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"Bang: Config \"%s\" not found", config.c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// No config defined -> apply to all.
|
2011-02-15 13:22:19 +00:00
|
|
|
const std::map<std::wstring, CMeterWindow*>& windows = Rainmeter->GetAllMeterWindows();
|
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = windows.begin();
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
for (; iter != windows.end(); ++iter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-03-29 21:50:05 +00:00
|
|
|
((*iter).second)->RunBang(bang, argument.c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
Log(LOG_ERROR, L"Bang: Incorrect number of arugments");
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:38:12 +00:00
|
|
|
/*
|
|
|
|
** BangGroupWithArgs
|
|
|
|
**
|
|
|
|
** Parses Bang args for Group
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void BangGroupWithArgs(BANGCOMMAND bang, const WCHAR* arg, size_t numOfArgs)
|
|
|
|
{
|
|
|
|
if (Rainmeter)
|
|
|
|
{
|
2010-08-03 15:10:42 +00:00
|
|
|
std::vector<std::wstring> subStrings = CRainmeter::ParseString(arg);
|
2010-07-17 13:38:12 +00:00
|
|
|
|
|
|
|
if (subStrings.size() > numOfArgs)
|
|
|
|
{
|
|
|
|
std::multimap<int, CMeterWindow*> windows;
|
|
|
|
Rainmeter->GetMeterWindowsByLoadOrder(windows, subStrings[numOfArgs]);
|
|
|
|
|
|
|
|
std::multimap<int, CMeterWindow*>::const_iterator iter = windows.begin();
|
|
|
|
for (; iter != windows.end(); ++iter)
|
|
|
|
{
|
|
|
|
std::wstring argument = L"\"";
|
|
|
|
for (size_t i = 0; i < numOfArgs; ++i)
|
|
|
|
{
|
|
|
|
argument += subStrings[i];
|
|
|
|
argument += L"\" \"";
|
|
|
|
}
|
|
|
|
argument += (*iter).second->GetSkinName();
|
|
|
|
argument += L"\"";
|
|
|
|
BangWithArgs(bang, argument.c_str(), numOfArgs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
Log(LOG_ERROR, L"BangGroup: Incorrect number of arguments");
|
2010-07-17 13:38:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-12-17 00:09:37 +00:00
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Callbacks for Litestep
|
|
|
|
//
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
/*
|
|
|
|
** RainmeterHide
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterHide bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterHide(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_HIDE, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterShow
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterShow bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterShow(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SHOW, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterToggle
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterToggle bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterToggle(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLE, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
2010-03-20 19:40:30 +00:00
|
|
|
/*
|
|
|
|
** RainmeterHideFade
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterHideFade bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterHideFade(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_HIDEFADE, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterShowFade
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterShowFade bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterShowFade(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SHOWFADE, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterToggleFade
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterToggleFade bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterToggleFade(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEFADE, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
2011-04-08 18:14:32 +00:00
|
|
|
/*
|
|
|
|
** RainmeterHideBlur
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterHideBlur bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterHideBlur(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_HIDEBLUR, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterShowBlur
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterShowBlur bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterShowBlur(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SHOWBLUR, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterToggleBlur
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterToggleBlur bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterToggleBlur(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEBLUR, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterAddBlur
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterAddBlur bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterAddBlur(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_ADDBLUR, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterRemoveBlur
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterRemoveBlur bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterRemoveBlur(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_REMOVEBLUR, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
/*
|
|
|
|
** RainmeterHideMeter
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterHideMeter bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterHideMeter(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_HIDEMETER, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterShowMeter
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterShowMeter bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterShowMeter(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SHOWMETER, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterToggleMeter
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterToggleMeter bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterToggleMeter(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEMETER, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2010-12-17 00:09:37 +00:00
|
|
|
/*
|
|
|
|
** RainmeterMoveMeter
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterMoveMeter bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterMoveMeter(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_MOVEMETER, ConvertToWide(arg).c_str(), 3);
|
|
|
|
}
|
|
|
|
|
2010-12-28 13:31:17 +00:00
|
|
|
/*
|
|
|
|
** RainmeterUpdateMeter
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterUpdateMeter bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterUpdateMeter(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_UPDATEMETER, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
/*
|
2010-07-07 23:54:20 +00:00
|
|
|
** RainmeterDisableMeasure
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
2010-07-07 23:54:20 +00:00
|
|
|
** Callback for the !RainmeterDisableMeasure bang
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterDisableMeasure(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_DISABLEMEASURE, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-07-07 23:54:20 +00:00
|
|
|
** RainmeterEnableMeasure
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
2010-07-07 23:54:20 +00:00
|
|
|
** Callback for the !RainmeterEnableMeasure bang
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterEnableMeasure(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_ENABLEMEASURE, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterToggleMeasure
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterToggleMeasure bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterToggleMeasure(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEMEASURE, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2010-12-28 13:31:17 +00:00
|
|
|
/*
|
|
|
|
** RainmeterUpdateMeasure
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterUpdateMeasure bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterUpdateMeasure(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_UPDATEMEASURE, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2011-07-09 09:23:28 +00:00
|
|
|
/*
|
|
|
|
** RainmeterCommandMeasure
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterCommandMeasure bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterCommandMeasure(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_COMMANDMEASURE, ConvertToWide(arg).c_str(), 2);
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
/*
|
|
|
|
** RainmeterRefresh
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterRefresh bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterRefresh(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_REFRESH, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
2010-03-29 21:50:05 +00:00
|
|
|
/*
|
|
|
|
** RainmeterRefreshApp
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterRefreshApp bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterRefreshApp(HWND, const char* arg)
|
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterRefreshAppWide();
|
2010-03-29 21:50:05 +00:00
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
/*
|
|
|
|
** RainmeterRedraw
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterRedraw bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterRedraw(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_REDRAW, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
2010-12-28 13:31:17 +00:00
|
|
|
/*
|
|
|
|
** RainmeterUpdate
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterUpdate bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterUpdate(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_UPDATE, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
/*
|
|
|
|
** RainmeterActivateConfig
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterActivateConfig bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterActivateConfig(HWND, const char* arg)
|
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterActivateConfigWide(ConvertToWide(arg).c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterDeactivateConfig
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterDeactivateConfig bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterDeactivateConfig(HWND, const char* arg)
|
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterDeactivateConfigWide(ConvertToWide(arg).c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterToggleConfig
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterToggleConfig bang
|
|
|
|
**
|
|
|
|
*/
|
2010-07-17 13:02:34 +00:00
|
|
|
void RainmeterToggleConfig(HWND, const char* arg)
|
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterToggleConfigWide(ConvertToWide(arg).c_str());
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterMove
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterMove bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterMove(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_MOVE, ConvertToWide(arg).c_str(), 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterZPos
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterZPos bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterZPos(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_ZPOS, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2010-08-22 12:08:38 +00:00
|
|
|
/*
|
|
|
|
** RainmeterClickThrough
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterClickThrough bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterClickThrough(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_CLICKTHROUGH, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterDraggable
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterDraggable bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterDraggable(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_DRAGGABLE, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterSnapEdges
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterSnapEdges bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterSnapEdges(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SNAPEDGES, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterKeepOnScreen
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterKeepOnScreen bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterKeepOnScreen(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_KEEPONSCREEN, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
/*
|
|
|
|
** RainmeterSetTransparency
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterSetTransparency bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterSetTransparency(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SETTRANSPARENCY, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterSetVariable
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterSetVariable bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterSetVariable(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SETVARIABLE, ConvertToWide(arg).c_str(), 2);
|
|
|
|
}
|
|
|
|
|
2011-07-27 10:42:35 +00:00
|
|
|
/*
|
|
|
|
** RainmeterSetOption
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterSetOption bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterSetOption(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SETOPTION, ConvertToWide(arg).c_str(), 3);
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
/*
|
|
|
|
** RainmeterHideGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterHideGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterHideGroup(HWND, const char* arg)
|
|
|
|
{
|
2010-07-17 13:38:12 +00:00
|
|
|
BangGroupWithArgs(BANG_HIDE, ConvertToWide(arg).c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterShowGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterShowGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterShowGroup(HWND, const char* arg)
|
|
|
|
{
|
2010-07-17 13:38:12 +00:00
|
|
|
BangGroupWithArgs(BANG_SHOW, ConvertToWide(arg).c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterToggleGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterToggleGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterToggleGroup(HWND, const char* arg)
|
|
|
|
{
|
2010-07-17 13:38:12 +00:00
|
|
|
BangGroupWithArgs(BANG_TOGGLE, ConvertToWide(arg).c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterHideFadeGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterHideFadeGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterHideFadeGroup(HWND, const char* arg)
|
|
|
|
{
|
2010-07-17 13:38:12 +00:00
|
|
|
BangGroupWithArgs(BANG_HIDEFADE, ConvertToWide(arg).c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterShowFadeGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterShowFadeGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterShowFadeGroup(HWND, const char* arg)
|
|
|
|
{
|
2010-07-17 13:38:12 +00:00
|
|
|
BangGroupWithArgs(BANG_SHOWFADE, ConvertToWide(arg).c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterToggleFadeGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterToggleFadeGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterToggleFadeGroup(HWND, const char* arg)
|
|
|
|
{
|
2010-07-17 13:38:12 +00:00
|
|
|
BangGroupWithArgs(BANG_TOGGLEFADE, ConvertToWide(arg).c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterHideMeterGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterHideMeterGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterHideMeterGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_HIDEMETERGROUP, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterShowMeterGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterShowMeterGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterShowMeterGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SHOWMETERGROUP, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterToggleMeterGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterToggleMeterGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterToggleMeterGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEMETERGROUP, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2010-12-28 13:31:17 +00:00
|
|
|
/*
|
|
|
|
** RainmeterUpdateMeterGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterUpdateMeterGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterUpdateMeterGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_UPDATEMETERGROUP, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
/*
|
|
|
|
** RainmeterDisableMeasureGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterDisableMeasureGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterDisableMeasureGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_DISABLEMEASUREGROUP, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterEnableMeasureGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterEnableMeasureGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterEnableMeasureGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_ENABLEMEASUREGROUP, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterToggleMeasureGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterToggleMeasureGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterToggleMeasureGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEMEASUREGROUP, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2010-12-28 13:31:17 +00:00
|
|
|
/*
|
|
|
|
** RainmeterUpdateMeasureGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterUpdateMeasureGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterUpdateMeasureGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_UPDATEMEASUREGROUP, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
/*
|
|
|
|
** RainmeterRefreshGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterRefreshGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterRefreshGroup(HWND, const char* arg)
|
|
|
|
{
|
2010-07-17 13:38:12 +00:00
|
|
|
BangGroupWithArgs(BANG_REFRESH, ConvertToWide(arg).c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterRedrawGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterRedrawGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterRedrawGroup(HWND, const char* arg)
|
|
|
|
{
|
2010-07-17 13:38:12 +00:00
|
|
|
BangGroupWithArgs(BANG_REDRAW, ConvertToWide(arg).c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
2010-12-28 13:31:17 +00:00
|
|
|
/*
|
|
|
|
** RainmeterUpdateGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterUpdateGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterUpdateGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangGroupWithArgs(BANG_UPDATE, ConvertToWide(arg).c_str(), 0);
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
/*
|
|
|
|
** RainmeterDeactivateConfigGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterDeactivateConfigGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterDeactivateConfigGroup(HWND, const char* arg)
|
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterDeactivateConfigGroupWide(ConvertToWide(arg).c_str());
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterZPosGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterZPosGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterZPosGroup(HWND, const char* arg)
|
|
|
|
{
|
2010-07-17 13:38:12 +00:00
|
|
|
BangGroupWithArgs(BANG_ZPOS, ConvertToWide(arg).c_str(), 1);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
2010-08-22 12:08:38 +00:00
|
|
|
/*
|
|
|
|
** RainmeterClickThroughGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterClickThroughGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterClickThroughGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangGroupWithArgs(BANG_CLICKTHROUGH, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterDraggableGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterDraggableGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterDraggableGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangGroupWithArgs(BANG_DRAGGABLE, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterSnapEdgesGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterSnapEdgesGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterSnapEdgesGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangGroupWithArgs(BANG_SNAPEDGES, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterKeepOnScreenGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterKeepOnScreenGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterKeepOnScreenGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangGroupWithArgs(BANG_KEEPONSCREEN, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
/*
|
|
|
|
** RainmeterSetTransparencyGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterSetTransparencyGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterSetTransparencyGroup(HWND, const char* arg)
|
|
|
|
{
|
2010-07-17 13:38:12 +00:00
|
|
|
BangGroupWithArgs(BANG_SETTRANSPARENCY, ConvertToWide(arg).c_str(), 1);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterSetVariableGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterSetVariableGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterSetVariableGroup(HWND, const char* arg)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-07-17 13:38:12 +00:00
|
|
|
BangGroupWithArgs(BANG_SETVARIABLE, ConvertToWide(arg).c_str(), 2);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-07-27 10:42:35 +00:00
|
|
|
/*
|
|
|
|
** RainmeterSetOptionGroup
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterSetOptionGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterSetOptionGroup(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangGroupWithArgs(BANG_SETOPTION, ConvertToWide(arg).c_str(), 3);
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
/*
|
2010-07-17 13:02:34 +00:00
|
|
|
** RainmeterLsHook
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
2010-07-17 13:02:34 +00:00
|
|
|
** Callback for the !RainmeterLsHook bang
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
|
|
|
*/
|
2010-07-17 13:02:34 +00:00
|
|
|
void RainmeterLsHook(HWND, const char* arg)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
BangWithArgs(BANG_LSHOOK, ConvertToWide(arg).c_str(), 0);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-07-17 13:02:34 +00:00
|
|
|
** RainmeterAbout
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
2010-07-17 13:02:34 +00:00
|
|
|
** Callback for the !RainmeterAbout bang
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
|
|
|
*/
|
2010-07-17 13:02:34 +00:00
|
|
|
void RainmeterAbout(HWND, const char* arg)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2011-08-28 16:42:34 +00:00
|
|
|
RainmeterAboutWide(ConvertToWide(arg).c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterManage
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterManage bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterManage(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
RainmeterManageWide(ConvertToWide(arg).c_str());
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterSkinMenu
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterSkinMenu bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterSkinMenu(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
RainmeterSkinMenuWide(ConvertToWide(arg).c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterTrayMenu
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterTrayMenu bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterTrayMenu(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
RainmeterTrayMenuWide();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterResetStats
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterResetStats bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterResetStats(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
RainmeterResetStatsWide();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterWriteKeyValue
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterWriteKeyValue bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterWriteKeyValue(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
RainmeterWriteKeyValueWide(ConvertToWide(arg).c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterPluginBang
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterPluginBang bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterPluginBang(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_PLUGIN, ConvertToWide(arg).c_str(), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterQuit
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterQuit bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterQuit(HWND, const char* arg)
|
|
|
|
{
|
|
|
|
RainmeterQuitWide();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Callbacks for Unicode support
|
|
|
|
//
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterActivateConfigWide
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterActivateConfig bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterActivateConfigWide(const WCHAR* arg)
|
|
|
|
{
|
|
|
|
if (Rainmeter)
|
|
|
|
{
|
|
|
|
std::vector<std::wstring> subStrings = CRainmeter::ParseString(arg);
|
|
|
|
|
|
|
|
if (subStrings.size() > 1)
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
std::pair<int, int> indexes = Rainmeter->GetMeterWindowIndex(subStrings[0], subStrings[1]);
|
|
|
|
if (indexes.first != -1 && indexes.second != -1)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
Rainmeter->ActivateConfig(indexes.first, indexes.second);
|
|
|
|
return;
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"!ActivateConfig: \"%s\\%s\" not found", subStrings[0].c_str(), subStrings[1].c_str());
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// If we got this far, something went wrong
|
2011-09-09 16:31:55 +00:00
|
|
|
Log(LOG_ERROR, L"!ActivateConfig: Invalid parameters");
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterDeactivateConfigWide
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterDeactivateConfig bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterDeactivateConfigWide(const WCHAR* arg)
|
|
|
|
{
|
|
|
|
if (Rainmeter)
|
|
|
|
{
|
|
|
|
std::vector<std::wstring> subStrings = CRainmeter::ParseString(arg);
|
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
if (!subStrings.empty())
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
|
|
|
CMeterWindow* mw = Rainmeter->GetMeterWindow(subStrings[0]);
|
|
|
|
if (mw)
|
|
|
|
{
|
|
|
|
Rainmeter->DeactivateConfig(mw, -1);
|
|
|
|
return;
|
|
|
|
}
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_WARNING, L"!DeactivateConfig: \"%s\" not active", subStrings[0].c_str());
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
Log(LOG_ERROR, L"!DeactivateConfig: Invalid parameters");
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterToggleConfigWide
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterToggleConfig bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterToggleConfigWide(const WCHAR* arg)
|
|
|
|
{
|
|
|
|
if (Rainmeter)
|
|
|
|
{
|
|
|
|
std::vector<std::wstring> subStrings = CRainmeter::ParseString(arg);
|
|
|
|
|
|
|
|
if (subStrings.size() >= 2)
|
|
|
|
{
|
|
|
|
CMeterWindow* mw = Rainmeter->GetMeterWindow(subStrings[0]);
|
|
|
|
if (mw)
|
|
|
|
{
|
|
|
|
Rainmeter->DeactivateConfig(mw, -1);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If the config wasn't active, activate it
|
|
|
|
RainmeterActivateConfigWide(arg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
Log(LOG_ERROR, L"!ToggleConfig: Invalid parameters");
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterDeactivateConfigGroupWide
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterDeactivateConfigGroup bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterDeactivateConfigGroupWide(const WCHAR* arg)
|
|
|
|
{
|
|
|
|
if (Rainmeter)
|
|
|
|
{
|
|
|
|
std::vector<std::wstring> subStrings = CRainmeter::ParseString(arg);
|
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
if (!subStrings.empty())
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
|
|
|
std::multimap<int, CMeterWindow*> windows;
|
|
|
|
Rainmeter->GetMeterWindowsByLoadOrder(windows, subStrings[0]);
|
|
|
|
|
|
|
|
std::multimap<int, CMeterWindow*>::const_iterator iter = windows.begin();
|
|
|
|
for (; iter != windows.end(); ++iter)
|
|
|
|
{
|
|
|
|
Rainmeter->DeactivateConfig((*iter).second, -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
Log(LOG_ERROR, L"!DeactivateConfigGroup: Invalid parameters");
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterRefreshAppWide
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterRefreshApp bang
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterRefreshAppWide()
|
|
|
|
{
|
|
|
|
if (Rainmeter)
|
|
|
|
{
|
|
|
|
// Refresh needs to be delayed since it crashes if done during Update()
|
2011-02-16 14:46:17 +00:00
|
|
|
PostMessage(Rainmeter->GetTrayWindow()->GetWindow(), WM_TRAY_DELAYED_REFRESH_ALL, (WPARAM)NULL, (LPARAM)NULL);
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** RainmeterAboutWide
|
|
|
|
**
|
|
|
|
** Callback for the !RainmeterAbout bang
|
|
|
|
**
|
|
|
|
*/
|
2011-08-28 10:58:26 +00:00
|
|
|
void RainmeterAboutWide(const WCHAR* arg)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-08-25 14:36:20 +00:00
|
|
|
if (Rainmeter)
|
|
|
|
{
|
2011-08-28 10:58:26 +00:00
|
|
|
int tab = 0;
|
|
|
|
if (arg)
|
|
|
|
{
|
|
|
|
if (_wcsnicmp(arg, L"Measures", 8) == 0)
|
|
|
|
{
|
|
|
|
tab = 1;
|
|
|
|
}
|
|
|
|
else if (_wcsnicmp(arg, L"Plugins", 7) == 0)
|
|
|
|
{
|
|
|
|
tab = 2;
|
|
|
|
}
|
2011-08-28 14:08:48 +00:00
|
|
|
else if (_wcsnicmp(arg, L"Version", 7) == 0)
|
|
|
|
{
|
|
|
|
tab = 3;
|
|
|
|
}
|
2011-08-28 10:58:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CDialogAbout::Open(tab);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2011-08-28 16:42:34 +00:00
|
|
|
** RainmeterManageWide
|
2011-08-28 10:58:26 +00:00
|
|
|
**
|
2011-08-28 16:42:34 +00:00
|
|
|
** Callback for the !RainmeterManage bang
|
2011-08-28 10:58:26 +00:00
|
|
|
**
|
|
|
|
*/
|
|
|
|
void RainmeterManageWide(const WCHAR* arg)
|
|
|
|
{
|
|
|
|
if (Rainmeter)
|
|
|
|
{
|
|
|
|
int tab = 0;
|
|
|
|
if (arg)
|
|
|
|
{
|
|
|
|
if (_wcsnicmp(arg, L"Themes", 6) == 0)
|
|
|
|
{
|
|
|
|
tab = 1;
|
|
|
|
}
|
|
|
|
else if (_wcsnicmp(arg, L"Settings", 8) == 0)
|
|
|
|
{
|
|
|
|
tab = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CDialogManage::Open(tab);
|
2010-08-25 14:36:20 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2010-03-20 19:40:30 +00:00
|
|
|
/*
|
2010-12-17 00:09:37 +00:00
|
|
|
** RainmeterSkinMenuWide
|
2010-03-20 19:40:30 +00:00
|
|
|
**
|
2010-07-17 13:02:34 +00:00
|
|
|
** Callback for the !RainmeterSkinMenu bang
|
2010-03-20 19:40:30 +00:00
|
|
|
**
|
|
|
|
*/
|
2010-12-17 00:09:37 +00:00
|
|
|
void RainmeterSkinMenuWide(const WCHAR* arg)
|
2010-03-20 19:40:30 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
if (Rainmeter)
|
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
std::vector<std::wstring> subStrings = CRainmeter::ParseString(arg);
|
2010-03-20 19:40:30 +00:00
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
if (!subStrings.empty())
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-07-22 00:31:59 +00:00
|
|
|
CMeterWindow* mw = Rainmeter->GetMeterWindow(subStrings[0]);
|
|
|
|
if (mw)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-07-22 00:31:59 +00:00
|
|
|
POINT pos;
|
|
|
|
GetCursorPos(&pos);
|
|
|
|
Rainmeter->ShowContextMenu(pos, mw);
|
|
|
|
return;
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_WARNING, L"!SkinMenu: \"%s\" not active", subStrings[0].c_str());
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
Log(LOG_ERROR, L"!SkinMenu: Invalid parameter");
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-12-17 00:09:37 +00:00
|
|
|
** RainmeterTrayMenuWide
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
2010-07-17 13:02:34 +00:00
|
|
|
** Callback for the !RainmeterTrayMenu bang
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
|
|
|
*/
|
2010-12-17 00:09:37 +00:00
|
|
|
void RainmeterTrayMenuWide()
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
if (Rainmeter)
|
|
|
|
{
|
|
|
|
POINT pos;
|
|
|
|
GetCursorPos(&pos);
|
|
|
|
Rainmeter->ShowContextMenu(pos, NULL);
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-12-17 00:09:37 +00:00
|
|
|
** RainmeterResetStatsWide
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
|
|
|
** Callback for the !RainmeterResetStats bang
|
|
|
|
**
|
|
|
|
*/
|
2010-12-17 00:09:37 +00:00
|
|
|
void RainmeterResetStatsWide()
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-03-29 19:21:57 +00:00
|
|
|
if (Rainmeter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
Rainmeter->ResetStats();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2010-12-17 00:09:37 +00:00
|
|
|
** RainmeterWriteKeyValueWide
|
2010-08-03 15:10:42 +00:00
|
|
|
**
|
|
|
|
** Callback for the !RainmeterWriteKeyValue bang
|
|
|
|
**
|
|
|
|
*/
|
2010-12-17 00:09:37 +00:00
|
|
|
void RainmeterWriteKeyValueWide(const WCHAR* arg)
|
2010-08-03 15:10:42 +00:00
|
|
|
{
|
|
|
|
if (Rainmeter)
|
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
std::vector<std::wstring> subStrings = CRainmeter::ParseString(arg);
|
2010-08-03 15:10:42 +00:00
|
|
|
|
|
|
|
if (subStrings.size() > 3)
|
|
|
|
{
|
|
|
|
const std::wstring& iniFile = subStrings[3];
|
|
|
|
|
2011-09-09 17:15:02 +00:00
|
|
|
if (iniFile.find(L"..\\") != std::string::npos || iniFile.find(L"../") != std::string::npos)
|
2010-08-03 15:10:42 +00:00
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: Illegal path: %s", iniFile.c_str());
|
2010-08-03 15:10:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-12-16 20:35:44 +00:00
|
|
|
const std::wstring& skinPath = Rainmeter->GetSkinPath();
|
|
|
|
const std::wstring settingsPath = Rainmeter->GetSettingsPath();
|
|
|
|
|
|
|
|
if (_wcsnicmp(iniFile.c_str(), skinPath.c_str(), skinPath.size()) != 0 &&
|
|
|
|
_wcsnicmp(iniFile.c_str(), settingsPath.c_str(), settingsPath.size()) != 0)
|
2010-08-03 15:10:42 +00:00
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: Illegal path: %s", iniFile.c_str());
|
2010-08-03 15:10:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify whether the file exists
|
|
|
|
if (_waccess(iniFile.c_str(), 0) == -1)
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: File not found: %s", iniFile.c_str());
|
2010-08-03 15:10:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify whether the file is read-only
|
|
|
|
DWORD attr = GetFileAttributes(iniFile.c_str());
|
|
|
|
if (attr == -1 || (attr & FILE_ATTRIBUTE_READONLY))
|
|
|
|
{
|
2011-07-06 20:31:20 +00:00
|
|
|
LogWithArgs(LOG_WARNING, L"!WriteKeyValue: File is read-only: %s", iniFile.c_str());
|
2010-08-03 15:10:42 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Avoid "IniFileMapping"
|
|
|
|
std::vector<std::wstring> iniFileMappings;
|
|
|
|
CSystem::GetIniFileMappingList(iniFileMappings);
|
|
|
|
std::wstring iniWrite = CSystem::GetTemporaryFile(iniFileMappings, iniFile);
|
|
|
|
if (iniWrite == L"<>") // error occurred
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool temporary = !iniWrite.empty();
|
|
|
|
|
|
|
|
if (temporary)
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
if (CRainmeter::GetDebug()) LogWithArgs(LOG_DEBUG, L"!WriteKeyValue: Writing to: %s (Temp: %s)", iniFile.c_str(), iniWrite.c_str());
|
2010-08-03 15:10:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
if (CRainmeter::GetDebug()) LogWithArgs(LOG_DEBUG, L"!WriteKeyValue: Writing to: %s", iniFile.c_str());
|
2010-08-03 15:10:42 +00:00
|
|
|
iniWrite = iniFile;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::wstring& strSection = subStrings[0];
|
|
|
|
const std::wstring& strKey = subStrings[1];
|
|
|
|
const std::wstring& strValue = subStrings[2];
|
|
|
|
|
2011-07-07 23:25:45 +00:00
|
|
|
bool formula = false;
|
2010-08-03 15:10:42 +00:00
|
|
|
BOOL write = 0;
|
|
|
|
|
|
|
|
if (subStrings.size() > 4)
|
|
|
|
{
|
|
|
|
CMeterWindow* mw = Rainmeter->GetMeterWindow(subStrings[4]);
|
|
|
|
if (mw)
|
|
|
|
{
|
|
|
|
double value;
|
|
|
|
formula = mw->GetParser().ReadFormula(strValue, &value);
|
2011-03-29 19:21:57 +00:00
|
|
|
|
2010-08-03 15:10:42 +00:00
|
|
|
// Formula read fine
|
2011-07-07 23:25:45 +00:00
|
|
|
if (formula)
|
2010-08-03 15:10:42 +00:00
|
|
|
{
|
2010-12-16 20:35:44 +00:00
|
|
|
WCHAR buffer[256];
|
2011-07-04 18:05:07 +00:00
|
|
|
int len = _snwprintf_s(buffer, _TRUNCATE, L"%.5f", value);
|
|
|
|
CMeasure::RemoveTrailingZero(buffer, len);
|
2010-08-03 15:10:42 +00:00
|
|
|
|
|
|
|
const std::wstring& resultString = buffer;
|
|
|
|
|
|
|
|
write = WritePrivateProfileString(strSection.c_str(), strKey.c_str(), resultString.c_str(), iniWrite.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-07 23:25:45 +00:00
|
|
|
if (!formula)
|
2010-08-03 15:10:42 +00:00
|
|
|
{
|
|
|
|
write = WritePrivateProfileString(strSection.c_str(), strKey.c_str(), strValue.c_str(), iniWrite.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (temporary)
|
|
|
|
{
|
|
|
|
if (write != 0)
|
|
|
|
{
|
|
|
|
WritePrivateProfileString(NULL, NULL, NULL, iniWrite.c_str()); // FLUSH
|
|
|
|
|
|
|
|
// Copy the file back
|
|
|
|
if (!CSystem::CopyFiles(iniWrite, iniFile))
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: Failed to copy temporary file to original filepath: %s (Temp: %s)", iniFile.c_str(), iniWrite.c_str());
|
2010-08-03 15:10:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else // failed
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: Failed to write to: %s (Temp: %s)", iniFile.c_str(), iniWrite.c_str());
|
2010-08-03 15:10:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Remove a temporary file
|
|
|
|
CSystem::RemoveFile(iniWrite);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (write == 0) // failed
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: Failed to write to: %s", iniFile.c_str());
|
2010-08-03 15:10:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
Log(LOG_ERROR, L"!WriteKeyValue: Invalid parameters");
|
2010-08-03 15:10:42 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
/*
|
2010-12-17 00:09:37 +00:00
|
|
|
** RainmeterQuitWide
|
2009-08-04 09:48:03 +00:00
|
|
|
**
|
|
|
|
** Callback for the !RainmeterQuit bang
|
|
|
|
**
|
|
|
|
*/
|
2010-12-17 00:09:37 +00:00
|
|
|
void RainmeterQuitWide()
|
2009-08-04 09:48:03 +00:00
|
|
|
{
|
2010-04-02 01:35:53 +00:00
|
|
|
if (Rainmeter)
|
|
|
|
{
|
|
|
|
// Quit needs to be delayed since it crashes if done during Update()
|
2010-04-02 06:54:51 +00:00
|
|
|
PostMessage(Rainmeter->GetTrayWindow()->GetWindow(), WM_COMMAND, MAKEWPARAM(ID_CONTEXT_QUIT, 0), (LPARAM)NULL);
|
2010-04-02 01:35:53 +00:00
|
|
|
}
|
2009-08-04 09:48:03 +00:00
|
|
|
}
|
|
|
|
|
2009-08-26 17:37:15 +00:00
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// The class starts here
|
|
|
|
//
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
|
2010-11-11 20:24:59 +00:00
|
|
|
GlobalConfig CRainmeter::c_GlobalConfig = {0};
|
2010-02-13 03:07:34 +00:00
|
|
|
bool CRainmeter::c_Debug = false;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2009-02-10 18:37:48 +00:00
|
|
|
** CRainmeter
|
|
|
|
**
|
|
|
|
** Constructor
|
|
|
|
**
|
|
|
|
*/
|
2011-01-29 00:11:01 +00:00
|
|
|
CRainmeter::CRainmeter() :
|
|
|
|
m_TrayWindow(),
|
2011-08-28 10:58:26 +00:00
|
|
|
m_DisableVersionCheck(false),
|
|
|
|
m_NewVersion(false),
|
2011-01-29 00:11:01 +00:00
|
|
|
m_DesktopWorkAreaChanged(false),
|
|
|
|
m_DesktopWorkAreaType(false),
|
|
|
|
m_MenuActive(false),
|
|
|
|
m_DisableRDP(false),
|
|
|
|
m_DisableDragging(false),
|
|
|
|
m_Logging(false),
|
|
|
|
m_CurrentParser(),
|
|
|
|
m_Instance(),
|
|
|
|
m_GDIplusToken()
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-12-05 23:33:51 +00:00
|
|
|
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
|
|
|
|
2011-08-28 10:58:26 +00:00
|
|
|
InitCommonControls();
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
// Initialize GDI+.
|
|
|
|
GdiplusStartupInput gdiplusStartupInput;
|
|
|
|
GdiplusStartup(&m_GDIplusToken, &gdiplusStartupInput, NULL);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2009-02-10 18:37:48 +00:00
|
|
|
** ~CRainmeter
|
|
|
|
**
|
|
|
|
** Destructor
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
CRainmeter::~CRainmeter()
|
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
DeleteMeterWindow(NULL, false); // This removes the window from the vector
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
if (m_TrayWindow) delete m_TrayWindow;
|
|
|
|
|
2010-03-29 21:50:05 +00:00
|
|
|
CSystem::Finalize();
|
|
|
|
|
|
|
|
CMeasureNet::UpdateIFTable();
|
|
|
|
CMeasureNet::UpdateStats();
|
2009-07-27 12:30:28 +00:00
|
|
|
WriteStats(true);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-02-13 03:07:34 +00:00
|
|
|
CMeasureNet::FinalizeNewApi();
|
|
|
|
|
2009-10-07 16:45:14 +00:00
|
|
|
CMeterString::FreeFontCache();
|
|
|
|
|
2010-07-10 12:56:37 +00:00
|
|
|
// Change the work area back
|
|
|
|
if (m_DesktopWorkAreaChanged)
|
|
|
|
{
|
|
|
|
UpdateDesktopWorkArea(true);
|
|
|
|
}
|
|
|
|
|
2011-08-31 11:06:35 +00:00
|
|
|
FinalizeLitestep();
|
2010-12-05 23:33:51 +00:00
|
|
|
|
2011-08-31 11:06:35 +00:00
|
|
|
CoUninitialize();
|
2010-09-19 09:21:25 +00:00
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
GdiplusShutdown(m_GDIplusToken);
|
|
|
|
}
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2009-02-10 18:37:48 +00:00
|
|
|
** Initialize
|
|
|
|
**
|
|
|
|
** The main initialization function for the module.
|
|
|
|
** May throw CErrors !!!!
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
int CRainmeter::Initialize(HWND Parent, HINSTANCE Instance, LPCSTR szPath)
|
|
|
|
{
|
2011-09-08 14:39:25 +00:00
|
|
|
int result = 0;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-09-08 14:39:25 +00:00
|
|
|
if (Parent == NULL || Instance == NULL)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-09-08 14:39:25 +00:00
|
|
|
throw CError(L"Null parameter", __LINE__, __FILE__);
|
2011-03-29 19:21:57 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
m_Instance = Instance;
|
2011-02-15 13:22:19 +00:00
|
|
|
|
|
|
|
WCHAR* tmpSzPath = new WCHAR[MAX_LINE_LENGTH];
|
|
|
|
GetModuleFileName(m_Instance, tmpSzPath, MAX_LINE_LENGTH);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
// Remove the module's name from the path
|
2011-02-15 13:22:19 +00:00
|
|
|
WCHAR* pos = wcsrchr(tmpSzPath, L'\\');
|
2011-03-29 19:21:57 +00:00
|
|
|
if (pos)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2009-09-12 11:11:40 +00:00
|
|
|
*(pos + 1) = L'\0';
|
2011-03-29 19:21:57 +00:00
|
|
|
}
|
|
|
|
else
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
tmpSzPath[0] = L'\0';
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
m_Path = tmpSzPath;
|
2010-09-11 19:39:45 +00:00
|
|
|
|
2011-08-31 11:06:35 +00:00
|
|
|
InitalizeLitestep();
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-05-02 11:58:02 +00:00
|
|
|
bool bDefaultIniLocation = false;
|
2009-07-24 07:56:37 +00:00
|
|
|
|
2009-07-26 21:08:46 +00:00
|
|
|
if (c_CmdLine.empty())
|
2009-07-21 12:26:50 +00:00
|
|
|
{
|
2010-11-25 22:00:34 +00:00
|
|
|
m_IniFile = m_Path;
|
|
|
|
m_IniFile += L"Rainmeter.ini";
|
2009-07-21 12:26:50 +00:00
|
|
|
|
2009-07-26 21:08:46 +00:00
|
|
|
// If the ini file doesn't exist in the program folder store it to the %APPDATA% instead so that things work better in Vista/Win7
|
|
|
|
if (_waccess(m_IniFile.c_str(), 0) == -1)
|
2009-07-21 12:26:50 +00:00
|
|
|
{
|
2009-08-26 17:37:15 +00:00
|
|
|
m_IniFile = L"%APPDATA%\\Rainmeter\\Rainmeter.ini";
|
|
|
|
ExpandEnvironmentVariables(m_IniFile);
|
2011-05-02 11:58:02 +00:00
|
|
|
bDefaultIniLocation = true;
|
2009-07-21 12:26:50 +00:00
|
|
|
|
2010-09-21 08:32:41 +00:00
|
|
|
// If the ini file doesn't exist in the %APPDATA% either, create a default Rainmeter.ini file.
|
2009-07-21 12:26:50 +00:00
|
|
|
if (_waccess(m_IniFile.c_str(), 0) == -1)
|
|
|
|
{
|
|
|
|
CreateDefaultConfigFile(m_IniFile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-07-26 21:08:46 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// The command line defines the location of Rainmeter.ini (or whatever it calls it).
|
|
|
|
std::wstring iniFile = c_CmdLine;
|
2010-08-05 10:46:04 +00:00
|
|
|
if (iniFile[0] == L'\"')
|
2009-07-26 21:08:46 +00:00
|
|
|
{
|
2010-08-05 10:46:04 +00:00
|
|
|
if (iniFile.length() == 1)
|
|
|
|
{
|
|
|
|
iniFile.clear();
|
|
|
|
}
|
|
|
|
else if (iniFile[iniFile.length() - 1] == L'\"')
|
|
|
|
{
|
2011-07-14 00:26:53 +00:00
|
|
|
iniFile.assign(iniFile, 1, iniFile.length() - 2);
|
2010-08-05 10:46:04 +00:00
|
|
|
}
|
2009-07-26 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2009-08-26 17:37:15 +00:00
|
|
|
ExpandEnvironmentVariables(iniFile);
|
2009-07-26 21:08:46 +00:00
|
|
|
|
2010-08-05 10:46:04 +00:00
|
|
|
if (iniFile.empty() || iniFile[iniFile.length() - 1] == L'\\')
|
2009-07-26 21:08:46 +00:00
|
|
|
{
|
|
|
|
iniFile += L"Rainmeter.ini";
|
|
|
|
}
|
2010-09-17 08:47:22 +00:00
|
|
|
else if (iniFile.length() <= 4 || _wcsicmp(iniFile.substr(iniFile.length() - 4).c_str(), L".ini") != 0)
|
2009-07-26 21:08:46 +00:00
|
|
|
{
|
|
|
|
iniFile += L"\\Rainmeter.ini";
|
|
|
|
}
|
|
|
|
|
2010-08-05 10:46:04 +00:00
|
|
|
if (iniFile[0] != L'\\' && iniFile[0] != L'/' && iniFile.find_first_of(L':') == std::wstring::npos)
|
|
|
|
{
|
|
|
|
// Make absolute path
|
|
|
|
iniFile.insert(0, m_Path);
|
|
|
|
}
|
|
|
|
|
2009-07-26 21:08:46 +00:00
|
|
|
m_IniFile = iniFile;
|
|
|
|
|
2010-09-21 08:32:41 +00:00
|
|
|
// If the ini file doesn't exist, create a default Rainmeter.ini file.
|
2009-07-26 21:08:46 +00:00
|
|
|
if (_waccess(m_IniFile.c_str(), 0) == -1)
|
|
|
|
{
|
|
|
|
CreateDefaultConfigFile(m_IniFile);
|
|
|
|
}
|
2011-05-02 11:58:02 +00:00
|
|
|
bDefaultIniLocation = true;
|
2009-07-26 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2011-07-14 00:26:53 +00:00
|
|
|
// Set the log file and stats file location
|
2011-04-16 20:05:14 +00:00
|
|
|
m_LogFile = m_StatsFile = m_IniFile;
|
2010-08-05 10:46:04 +00:00
|
|
|
size_t logFileLen = m_LogFile.length();
|
2010-09-17 08:47:22 +00:00
|
|
|
if (logFileLen > 4 && _wcsicmp(m_LogFile.substr(logFileLen - 4).c_str(), L".ini") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
2010-08-05 10:46:04 +00:00
|
|
|
m_LogFile.replace(logFileLen - 4, 4, L".log");
|
2011-07-14 00:26:53 +00:00
|
|
|
m_StatsFile.replace(logFileLen - 4, 4, L".stats");
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_LogFile += L".log"; // Append the extension so that we don't accidentally overwrite the ini file
|
2011-04-16 20:05:14 +00:00
|
|
|
m_StatsFile += L".stats";
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Read Logging settings beforehand
|
|
|
|
m_Logging = 0!=GetPrivateProfileInt(L"Rainmeter", L"Logging", 0, m_IniFile.c_str());
|
|
|
|
c_Debug = 0!=GetPrivateProfileInt(L"Rainmeter", L"Debug", 0, m_IniFile.c_str());
|
|
|
|
|
2010-07-08 10:59:06 +00:00
|
|
|
if (m_Logging)
|
|
|
|
{
|
|
|
|
StartLogging();
|
|
|
|
}
|
|
|
|
|
2011-05-02 11:58:02 +00:00
|
|
|
m_PluginPath = m_AddonPath = m_SkinPath = m_Path;
|
2009-07-26 21:08:46 +00:00
|
|
|
m_PluginPath += L"Plugins\\";
|
2010-11-25 22:00:34 +00:00
|
|
|
m_AddonPath += L"Addons\\";
|
2011-05-02 11:58:02 +00:00
|
|
|
m_SkinPath += L"Skins\\";
|
2009-07-21 12:26:50 +00:00
|
|
|
|
2011-05-02 11:58:02 +00:00
|
|
|
// Read the skin folder from the ini file
|
|
|
|
tmpSzPath[0] = L'\0';
|
|
|
|
if (GetPrivateProfileString(L"Rainmeter", L"SkinPath", L"", tmpSzPath, MAX_LINE_LENGTH, m_IniFile.c_str()) > 0)
|
2009-07-24 07:56:37 +00:00
|
|
|
{
|
2011-05-02 11:58:02 +00:00
|
|
|
m_SkinPath = tmpSzPath;
|
|
|
|
ExpandEnvironmentVariables(m_SkinPath);
|
|
|
|
|
|
|
|
if (!m_SkinPath.empty())
|
|
|
|
{
|
|
|
|
WCHAR ch = m_SkinPath[m_SkinPath.size() - 1];
|
|
|
|
if (ch != L'\\' && ch != L'/')
|
|
|
|
{
|
|
|
|
m_SkinPath += L"\\";
|
|
|
|
}
|
|
|
|
}
|
2011-05-01 17:10:49 +00:00
|
|
|
}
|
2011-05-02 11:58:02 +00:00
|
|
|
else if (bDefaultIniLocation)
|
2011-05-01 17:10:49 +00:00
|
|
|
{
|
2011-05-02 11:58:02 +00:00
|
|
|
// If the skin path is not defined in the Rainmeter.ini file use My Documents/Rainmeter/Skins
|
2011-02-15 13:22:19 +00:00
|
|
|
tmpSzPath[0] = L'\0';
|
2011-05-02 11:58:02 +00:00
|
|
|
HRESULT hr = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, tmpSzPath);
|
|
|
|
if (SUCCEEDED(hr))
|
2009-07-24 07:56:37 +00:00
|
|
|
{
|
2011-05-02 11:58:02 +00:00
|
|
|
// Make the folders if they don't exist yet
|
2011-02-15 13:22:19 +00:00
|
|
|
m_SkinPath = tmpSzPath;
|
2011-05-02 11:58:02 +00:00
|
|
|
m_SkinPath += L"\\Rainmeter";
|
|
|
|
CreateDirectory(m_SkinPath.c_str(), NULL);
|
|
|
|
m_SkinPath += L"\\Skins\\";
|
|
|
|
DWORD result = CreateDirectory(m_SkinPath.c_str(), NULL);
|
|
|
|
if (result != 0)
|
2009-07-24 07:56:37 +00:00
|
|
|
{
|
2011-05-02 11:58:02 +00:00
|
|
|
// The folder was created successfully which means that it wasn't available yet.
|
|
|
|
// Copy the default skin to the Skins folder
|
|
|
|
std::wstring strFrom(m_Path + L"Skins\\*.*");
|
|
|
|
std::wstring strTo(m_SkinPath);
|
|
|
|
CSystem::CopyFiles(strFrom, strTo);
|
|
|
|
|
|
|
|
// This shouldn't be copied
|
|
|
|
std::wstring strNote = strTo + L"Read me before copying skins here.txt";
|
|
|
|
CSystem::RemoveFile(strNote);
|
|
|
|
|
|
|
|
// Copy also the themes to the %APPDATA%
|
|
|
|
strFrom = std::wstring(m_Path + L"Themes\\*.*");
|
|
|
|
strTo = std::wstring(GetSettingsPath() + L"Themes\\");
|
|
|
|
CreateDirectory(strTo.c_str(), NULL);
|
|
|
|
CSystem::CopyFiles(strFrom, strTo);
|
2009-07-24 07:56:37 +00:00
|
|
|
}
|
|
|
|
}
|
2011-05-01 17:10:49 +00:00
|
|
|
else
|
2009-07-24 07:56:37 +00:00
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
Log(LOG_WARNING, L"Documents folder not found");
|
2009-07-24 07:56:37 +00:00
|
|
|
}
|
2011-05-02 11:58:02 +00:00
|
|
|
|
|
|
|
WritePrivateProfileString(L"Rainmeter", L"SkinPath", m_SkinPath.c_str(), m_IniFile.c_str());
|
2009-07-24 07:56:37 +00:00
|
|
|
}
|
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
delete [] tmpSzPath;
|
|
|
|
tmpSzPath = NULL;
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
if (!c_DummyLitestep)
|
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
char* tmpSz = new char[MAX_LINE_LENGTH];
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
// Check if step.rc has overrides these values
|
|
|
|
if (GetRCString("RainmeterIniFile", tmpSz, NULL, MAX_LINE_LENGTH - 1))
|
|
|
|
{
|
|
|
|
m_IniFile = ConvertToWide(tmpSz);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetRCString("RainmeterSkinPath", tmpSz, NULL, MAX_LINE_LENGTH - 1))
|
|
|
|
{
|
|
|
|
m_SkinPath = ConvertToWide(tmpSz);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetRCString("RainmeterPluginPath", tmpSz, NULL, MAX_LINE_LENGTH - 1))
|
|
|
|
{
|
|
|
|
m_PluginPath = ConvertToWide(tmpSz);
|
|
|
|
}
|
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
delete [] tmpSz;
|
|
|
|
|
2010-08-06 07:40:43 +00:00
|
|
|
if (!m_SkinPath.empty())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-08-06 07:40:43 +00:00
|
|
|
WCHAR ch = m_SkinPath[m_SkinPath.size() - 1];
|
|
|
|
if (ch != L'\\' && ch != L'/')
|
|
|
|
{
|
|
|
|
m_SkinPath += L"\\";
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-19 23:06:13 +00:00
|
|
|
LogWithArgs(LOG_NOTICE, L"Path: %s", m_Path.c_str());
|
|
|
|
LogWithArgs(LOG_NOTICE, L"IniFile: %s", m_IniFile.c_str());
|
|
|
|
LogWithArgs(LOG_NOTICE, L"SkinPath: %s", m_SkinPath.c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-11-25 22:00:34 +00:00
|
|
|
// Extract volume path from program path
|
|
|
|
// E.g.:
|
|
|
|
// "C:\path\" to "C:"
|
|
|
|
// "\\server\share\" to "\\server\share"
|
|
|
|
// "\\server\C:\path\" to "\\server\C:"
|
|
|
|
std::wstring::size_type loc;
|
|
|
|
if ((loc = m_Path.find_first_of(L':')) != std::wstring::npos)
|
|
|
|
{
|
2011-07-14 00:26:53 +00:00
|
|
|
m_Drive.assign(m_Path, 0, loc + 1);
|
2010-11-25 22:00:34 +00:00
|
|
|
}
|
|
|
|
else if (m_Path.length() >= 2 && (m_Path[0] == L'\\' || m_Path[0] == L'/') && (m_Path[1] == L'\\' || m_Path[1] == L'/'))
|
|
|
|
{
|
|
|
|
if ((loc = m_Path.find_first_of(L"\\/", 2)) != std::wstring::npos)
|
|
|
|
{
|
|
|
|
std::wstring::size_type loc2;
|
|
|
|
if ((loc2 = m_Path.find_first_of(L"\\/", loc + 1)) != std::wstring::npos || loc != (m_Path.length() - 1))
|
|
|
|
{
|
|
|
|
loc = loc2;
|
|
|
|
}
|
|
|
|
}
|
2011-07-14 00:26:53 +00:00
|
|
|
m_Drive.assign(m_Path, 0, loc);
|
2010-11-25 22:00:34 +00:00
|
|
|
}
|
|
|
|
|
2009-07-24 07:56:37 +00:00
|
|
|
// Test that the Rainmeter.ini file is writable
|
2011-05-02 11:58:02 +00:00
|
|
|
TestSettingsFile(bDefaultIniLocation);
|
2009-07-24 07:56:37 +00:00
|
|
|
|
2010-03-20 19:40:30 +00:00
|
|
|
CSystem::Initialize(Instance);
|
|
|
|
CMeasureNet::InitializeNewApi();
|
|
|
|
|
|
|
|
if (c_Debug)
|
|
|
|
{
|
2010-12-20 08:57:37 +00:00
|
|
|
Log(LOG_DEBUG, L"Enumerating installed font families...");
|
2010-03-20 19:40:30 +00:00
|
|
|
CMeterString::EnumerateInstalledFontFamilies();
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
// Tray must exist before configs are read
|
|
|
|
m_TrayWindow = new CTrayWindow(m_Instance);
|
|
|
|
|
|
|
|
ScanForConfigs(m_SkinPath);
|
2009-08-12 17:11:52 +00:00
|
|
|
ScanForThemes(GetSettingsPath() + L"Themes");
|
2009-07-24 07:56:37 +00:00
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
if (m_ConfigStrings.empty())
|
2009-07-24 07:56:37 +00:00
|
|
|
{
|
|
|
|
std::wstring error = L"There are no available skins at:\n" + m_SkinPath;
|
2010-09-21 11:09:36 +00:00
|
|
|
MessageBox(NULL, error.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONERROR);
|
2009-07-24 07:56:37 +00:00
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
ReadGeneralSettings(m_IniFile);
|
|
|
|
|
2010-06-21 16:00:19 +00:00
|
|
|
WritePrivateProfileString(L"Rainmeter", L"CheckUpdate", NULL , m_IniFile.c_str());
|
|
|
|
|
|
|
|
if (!m_DisableVersionCheck)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
CheckUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
ResetStats();
|
|
|
|
ReadStats();
|
|
|
|
|
|
|
|
// Change the work area if necessary
|
|
|
|
if (m_DesktopWorkAreaChanged)
|
|
|
|
{
|
2010-07-10 12:56:37 +00:00
|
|
|
UpdateDesktopWorkArea(false);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// If we're running as Litestep's plugin, register the !bangs
|
2011-03-29 19:21:57 +00:00
|
|
|
if (!c_DummyLitestep)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
int Msgs[] = { LM_GETREVID, 0 };
|
|
|
|
// Register RevID message to Litestep
|
|
|
|
if (m_TrayWindow && m_TrayWindow->GetWindow()) ::SendMessage(GetLitestepWnd(), LM_REGISTERMESSAGE, (WPARAM)m_TrayWindow->GetWindow(), (LPARAM)Msgs);
|
|
|
|
|
|
|
|
AddBangCommand("!RainmeterRefresh", RainmeterRefresh);
|
|
|
|
AddBangCommand("!RainmeterRedraw", RainmeterRedraw);
|
2010-12-28 13:31:17 +00:00
|
|
|
AddBangCommand("!RainmeterUpdate", RainmeterUpdate);
|
2009-02-10 18:37:48 +00:00
|
|
|
AddBangCommand("!RainmeterHide", RainmeterHide);
|
|
|
|
AddBangCommand("!RainmeterShow", RainmeterShow);
|
|
|
|
AddBangCommand("!RainmeterToggle", RainmeterToggle);
|
2010-03-20 19:40:30 +00:00
|
|
|
AddBangCommand("!RainmeterHideFade", RainmeterHideFade);
|
|
|
|
AddBangCommand("!RainmeterShowFade", RainmeterShowFade);
|
|
|
|
AddBangCommand("!RainmeterToggleFade", RainmeterToggleFade);
|
2011-04-08 18:14:32 +00:00
|
|
|
AddBangCommand("!RainmeterHideBlur", RainmeterHideBlur);
|
|
|
|
AddBangCommand("!RainmeterShowBlur", RainmeterShowBlur);
|
|
|
|
AddBangCommand("!RainmeterToggleBlur", RainmeterToggleBlur);
|
|
|
|
AddBangCommand("!RainmeterAddBlur", RainmeterAddBlur);
|
|
|
|
AddBangCommand("!RainmeterRemoveBlur", RainmeterRemoveBlur);
|
2009-02-10 18:37:48 +00:00
|
|
|
AddBangCommand("!RainmeterHideMeter", RainmeterHideMeter);
|
|
|
|
AddBangCommand("!RainmeterShowMeter", RainmeterShowMeter);
|
|
|
|
AddBangCommand("!RainmeterToggleMeter", RainmeterToggleMeter);
|
2010-07-17 13:02:34 +00:00
|
|
|
AddBangCommand("!RainmeterMoveMeter", RainmeterMoveMeter);
|
2010-12-28 13:31:17 +00:00
|
|
|
AddBangCommand("!RainmeterUpdateMeter", RainmeterUpdateMeter);
|
2009-02-10 18:37:48 +00:00
|
|
|
AddBangCommand("!RainmeterDisableMeasure", RainmeterDisableMeasure);
|
|
|
|
AddBangCommand("!RainmeterEnableMeasure", RainmeterEnableMeasure);
|
|
|
|
AddBangCommand("!RainmeterToggleMeasure", RainmeterToggleMeasure);
|
2010-12-28 13:31:17 +00:00
|
|
|
AddBangCommand("!RainmeterUpdateMeasure", RainmeterUpdateMeasure);
|
2010-07-17 13:02:34 +00:00
|
|
|
AddBangCommand("!RainmeterActivateConfig", RainmeterActivateConfig);
|
|
|
|
AddBangCommand("!RainmeterDeactivateConfig", RainmeterDeactivateConfig);
|
|
|
|
AddBangCommand("!RainmeterToggleConfig", RainmeterToggleConfig);
|
|
|
|
AddBangCommand("!RainmeterMove", RainmeterMove);
|
|
|
|
AddBangCommand("!RainmeterZPos", RainmeterZPos);
|
2010-08-22 12:08:38 +00:00
|
|
|
AddBangCommand("!RainmeterClickThrough", RainmeterClickThrough);
|
|
|
|
AddBangCommand("!RainmeterDraggable", RainmeterDraggable);
|
|
|
|
AddBangCommand("!RainmeterSnapEdges", RainmeterSnapEdges);
|
|
|
|
AddBangCommand("!RainmeterKeepOnScreen", RainmeterKeepOnScreen);
|
2010-07-17 13:02:34 +00:00
|
|
|
AddBangCommand("!RainmeterSetTransparency", RainmeterSetTransparency);
|
|
|
|
AddBangCommand("!RainmeterSetVariable", RainmeterSetVariable);
|
|
|
|
|
|
|
|
AddBangCommand("!RainmeterRefreshGroup", RainmeterRefreshGroup);
|
|
|
|
AddBangCommand("!RainmeterRedrawGroup", RainmeterRedrawGroup);
|
2010-12-28 13:31:17 +00:00
|
|
|
AddBangCommand("!RainmeterUpdateGroup", RainmeterUpdateGroup);
|
2010-07-17 13:02:34 +00:00
|
|
|
AddBangCommand("!RainmeterHideGroup", RainmeterHideGroup);
|
|
|
|
AddBangCommand("!RainmeterShowGroup", RainmeterShowGroup);
|
|
|
|
AddBangCommand("!RainmeterToggleGroup", RainmeterToggleGroup);
|
|
|
|
AddBangCommand("!RainmeterHideFadeGroup", RainmeterHideFadeGroup);
|
|
|
|
AddBangCommand("!RainmeterShowFadeGroup", RainmeterShowFadeGroup);
|
|
|
|
AddBangCommand("!RainmeterToggleFadeGroup", RainmeterToggleFadeGroup);
|
2010-07-07 23:46:44 +00:00
|
|
|
AddBangCommand("!RainmeterHideMeterGroup", RainmeterHideMeterGroup);
|
|
|
|
AddBangCommand("!RainmeterShowMeterGroup", RainmeterShowMeterGroup);
|
|
|
|
AddBangCommand("!RainmeterToggleMeterGroup", RainmeterToggleMeterGroup);
|
2010-12-28 13:31:17 +00:00
|
|
|
AddBangCommand("!RainmeterUpdateMeterGroup", RainmeterUpdateMeterGroup);
|
2010-07-07 23:46:44 +00:00
|
|
|
AddBangCommand("!RainmeterDisableMeasureGroup", RainmeterDisableMeasureGroup);
|
|
|
|
AddBangCommand("!RainmeterEnableMeasureGroup", RainmeterEnableMeasureGroup);
|
|
|
|
AddBangCommand("!RainmeterToggleMeasureGroup", RainmeterToggleMeasureGroup);
|
2010-12-28 13:31:17 +00:00
|
|
|
AddBangCommand("!RainmeterUpdateMeasureGroup", RainmeterUpdateMeasureGroup);
|
2010-07-17 13:02:34 +00:00
|
|
|
AddBangCommand("!RainmeterDeactivateConfigGroup", RainmeterDeactivateConfigGroup);
|
|
|
|
AddBangCommand("!RainmeterZPosGroup", RainmeterZPosGroup);
|
2010-08-22 12:08:38 +00:00
|
|
|
AddBangCommand("!RainmeterClickThroughGroup", RainmeterClickThroughGroup);
|
|
|
|
AddBangCommand("!RainmeterDraggableGroup", RainmeterDraggableGroup);
|
|
|
|
AddBangCommand("!RainmeterSnapEdgesGroup", RainmeterSnapEdgesGroup);
|
|
|
|
AddBangCommand("!RainmeterKeepOnScreenGroup", RainmeterKeepOnScreenGroup);
|
2010-07-17 13:02:34 +00:00
|
|
|
AddBangCommand("!RainmeterSetTransparencyGroup", RainmeterSetTransparencyGroup);
|
|
|
|
AddBangCommand("!RainmeterSetVariableGroup", RainmeterSetVariableGroup);
|
|
|
|
|
|
|
|
AddBangCommand("!RainmeterRefreshApp", RainmeterRefreshApp);
|
2009-02-10 18:37:48 +00:00
|
|
|
AddBangCommand("!RainmeterLsBoxHook", RainmeterLsHook);
|
|
|
|
AddBangCommand("!RainmeterAbout", RainmeterAbout);
|
2011-08-28 16:42:34 +00:00
|
|
|
AddBangCommand("!RainmeterManage", RainmeterManage);
|
2010-07-17 13:02:34 +00:00
|
|
|
AddBangCommand("!RainmeterSkinMenu", RainmeterSkinMenu);
|
|
|
|
AddBangCommand("!RainmeterTrayMenu", RainmeterTrayMenu);
|
2009-02-10 18:37:48 +00:00
|
|
|
AddBangCommand("!RainmeterResetStats", RainmeterResetStats);
|
2010-08-03 15:10:42 +00:00
|
|
|
AddBangCommand("!RainmeterWriteKeyValue", RainmeterWriteKeyValue);
|
2009-02-10 18:37:48 +00:00
|
|
|
AddBangCommand("!RainmeterPluginBang", RainmeterPluginBang);
|
2009-08-04 09:48:03 +00:00
|
|
|
AddBangCommand("!RainmeterQuit", RainmeterQuit);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2010-03-20 19:40:30 +00:00
|
|
|
// Create meter windows for active configs
|
2011-09-04 18:06:19 +00:00
|
|
|
ActivateActiveConfigs();
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-09-08 14:39:25 +00:00
|
|
|
return result; // Alles OK
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2009-07-21 12:26:50 +00:00
|
|
|
** CreateDefaultConfigFile
|
|
|
|
**
|
2011-04-16 20:05:14 +00:00
|
|
|
** Creates the default Rainmeter.ini file with illustro\System enabled.
|
2009-07-21 12:26:50 +00:00
|
|
|
**
|
|
|
|
*/
|
2010-11-11 20:24:59 +00:00
|
|
|
void CRainmeter::CreateDefaultConfigFile(const std::wstring& strFile)
|
2009-07-21 12:26:50 +00:00
|
|
|
{
|
|
|
|
size_t pos = strFile.find_last_of(L'\\');
|
|
|
|
if (pos != std::wstring::npos)
|
|
|
|
{
|
2011-07-12 13:37:31 +00:00
|
|
|
std::wstring strPath(strFile, 0, pos);
|
2009-07-21 12:26:50 +00:00
|
|
|
CreateDirectory(strPath.c_str(), NULL);
|
|
|
|
}
|
|
|
|
|
2009-07-26 21:08:46 +00:00
|
|
|
std::wstring defaultIni = GetPath() + L"Default.ini";
|
|
|
|
if (_waccess(defaultIni.c_str(), 0) == -1)
|
2009-07-21 12:26:50 +00:00
|
|
|
{
|
2011-08-28 10:58:26 +00:00
|
|
|
WritePrivateProfileString(L"Rainmeter", L"\r\n[illustro\\System]\r\nActive", L"1", strFile.c_str());
|
2009-07-26 21:08:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-08-03 15:10:42 +00:00
|
|
|
CSystem::CopyFiles(defaultIni, GetIniFile());
|
2009-07-21 12:26:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
void CRainmeter::ReloadSettings()
|
|
|
|
{
|
|
|
|
ScanForConfigs(m_SkinPath);
|
2009-08-12 17:11:52 +00:00
|
|
|
ScanForThemes(GetSettingsPath() + L"Themes");
|
2009-02-10 18:37:48 +00:00
|
|
|
ReadGeneralSettings(m_IniFile);
|
|
|
|
}
|
|
|
|
|
2011-09-04 18:06:19 +00:00
|
|
|
void CRainmeter::ActivateActiveConfigs()
|
|
|
|
{
|
|
|
|
std::multimap<int, int>::const_iterator iter = m_ConfigOrders.begin();
|
|
|
|
for ( ; iter != m_ConfigOrders.end(); ++iter)
|
|
|
|
{
|
|
|
|
const CONFIG& config = m_ConfigStrings[(*iter).second];
|
|
|
|
if (config.active > 0 && config.active <= (int)config.iniFiles.size())
|
|
|
|
{
|
|
|
|
ActivateConfig((*iter).second, config.active - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
void CRainmeter::ActivateConfig(int configIndex, int iniIndex)
|
|
|
|
{
|
2009-02-14 10:11:28 +00:00
|
|
|
if (configIndex >= 0 && configIndex < (int)m_ConfigStrings.size())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-07-22 00:31:59 +00:00
|
|
|
const std::wstring skinIniFile = m_ConfigStrings[configIndex].iniFiles[iniIndex];
|
|
|
|
const std::wstring skinConfig = m_ConfigStrings[configIndex].config;
|
2011-02-15 13:22:19 +00:00
|
|
|
const std::wstring& skinPath = m_SkinPath;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
// Verify that the config is not already active
|
2010-03-30 22:37:05 +00:00
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_Meters.find(skinConfig);
|
2009-02-10 18:37:48 +00:00
|
|
|
if (iter != m_Meters.end())
|
|
|
|
{
|
|
|
|
if (((*iter).second)->GetSkinIniFile() == skinIniFile)
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_WARNING, L"!ActivateConfig: \"%s\" already active", skinConfig.c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Deactivate the existing config
|
2011-02-02 23:17:44 +00:00
|
|
|
DeactivateConfig((*iter).second, configIndex);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-22 00:31:59 +00:00
|
|
|
// Verify whether the ini-file exists
|
2010-11-25 22:00:34 +00:00
|
|
|
std::wstring skinIniPath = skinPath + skinConfig;
|
2010-07-22 00:31:59 +00:00
|
|
|
skinIniPath += L"\\";
|
|
|
|
skinIniPath += skinIniFile;
|
|
|
|
|
|
|
|
if (_waccess(skinIniPath.c_str(), 0) == -1)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-11-25 22:00:34 +00:00
|
|
|
std::wstring message = L"Unable to activate skin \"" + skinConfig;
|
2010-09-21 11:09:36 +00:00
|
|
|
message += L"\\";
|
2010-11-11 20:24:59 +00:00
|
|
|
message += skinIniFile;
|
2011-09-09 16:31:55 +00:00
|
|
|
message += L"\": File not found";
|
2010-07-22 00:31:59 +00:00
|
|
|
MessageBox(NULL, message.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION);
|
|
|
|
return;
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-07-22 00:31:59 +00:00
|
|
|
m_ConfigStrings[configIndex].active = iniIndex + 1;
|
|
|
|
WriteActive(skinConfig, iniIndex);
|
2009-10-18 13:31:55 +00:00
|
|
|
|
2011-09-10 22:04:51 +00:00
|
|
|
CreateMeterWindow(skinPath, skinConfig, skinIniFile);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-28 10:58:26 +00:00
|
|
|
bool CRainmeter::DeactivateConfig(CMeterWindow* meterWindow, int configIndex, bool save)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2009-02-14 10:11:28 +00:00
|
|
|
if (configIndex >= 0 && configIndex < (int)m_ConfigStrings.size())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
m_ConfigStrings[configIndex].active = 0; // Deactivate the config
|
|
|
|
}
|
2010-07-22 00:31:59 +00:00
|
|
|
else if (configIndex == -1 && meterWindow)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-07-22 00:31:59 +00:00
|
|
|
// Deactivate the config by using the meter window's config name
|
|
|
|
const std::wstring skinConfig = meterWindow->GetSkinName();
|
2011-02-15 13:22:19 +00:00
|
|
|
for (size_t i = 0, isize = m_ConfigStrings.size(); i < isize; ++i)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-09-17 08:47:22 +00:00
|
|
|
if (_wcsicmp(skinConfig.c_str(), m_ConfigStrings[i].config.c_str()) == 0)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
|
|
|
m_ConfigStrings[i].active = 0;
|
|
|
|
break;
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (meterWindow)
|
|
|
|
{
|
2011-08-28 10:58:26 +00:00
|
|
|
if (save)
|
|
|
|
{
|
|
|
|
// Disable the config in the ini-file
|
|
|
|
WriteActive(meterWindow->GetSkinName(), -1);
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-02-02 23:17:44 +00:00
|
|
|
return DeleteMeterWindow(meterWindow, true);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-07-22 00:31:59 +00:00
|
|
|
void CRainmeter::WriteActive(const std::wstring& config, int iniIndex)
|
|
|
|
{
|
2010-12-13 09:00:02 +00:00
|
|
|
WCHAR buffer[32];
|
2010-12-16 20:35:44 +00:00
|
|
|
_snwprintf_s(buffer, _TRUNCATE, L"%i", iniIndex + 1);
|
2010-07-22 00:31:59 +00:00
|
|
|
WritePrivateProfileString(config.c_str(), L"Active", buffer, m_IniFile.c_str());
|
|
|
|
}
|
|
|
|
|
2010-11-11 20:24:59 +00:00
|
|
|
void CRainmeter::CreateMeterWindow(const std::wstring& path, const std::wstring& config, const std::wstring& iniFile)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2009-07-24 07:56:37 +00:00
|
|
|
CMeterWindow* mw = new CMeterWindow(path, config, iniFile);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
if (mw)
|
|
|
|
{
|
|
|
|
m_Meters[config] = mw;
|
2010-08-30 22:51:58 +00:00
|
|
|
|
2011-09-10 22:04:51 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
mw->Initialize(*this);
|
|
|
|
|
|
|
|
CDialogManage::UpdateSkins(mw);
|
|
|
|
}
|
|
|
|
catch (CError& error)
|
|
|
|
{
|
|
|
|
DeleteMeterWindow(mw, false);
|
|
|
|
LogError(error);
|
|
|
|
}
|
|
|
|
|
2011-09-10 22:31:05 +00:00
|
|
|
CDialogAbout::UpdateSkins();
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-17 06:43:18 +00:00
|
|
|
void CRainmeter::ClearDeleteLaterList()
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-08-28 10:58:26 +00:00
|
|
|
if (!m_DelayDeleteList.empty())
|
2009-10-17 06:43:18 +00:00
|
|
|
{
|
2011-08-28 10:58:26 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
CMeterWindow* meterWindow = m_DelayDeleteList.front();
|
2009-10-18 13:31:55 +00:00
|
|
|
|
2011-08-28 10:58:26 +00:00
|
|
|
// Remove from the delete later list
|
|
|
|
m_DelayDeleteList.remove(meterWindow);
|
2009-10-18 13:31:55 +00:00
|
|
|
|
2011-08-28 10:58:26 +00:00
|
|
|
// Remove from the meter window list if it is still there
|
|
|
|
std::map<std::wstring, CMeterWindow*>::iterator iter = m_Meters.begin();
|
|
|
|
for (; iter != m_Meters.end(); ++iter)
|
2009-10-18 13:31:55 +00:00
|
|
|
{
|
2011-08-28 10:58:26 +00:00
|
|
|
if ((*iter).second == meterWindow)
|
|
|
|
{
|
|
|
|
m_Meters.erase(iter);
|
|
|
|
break;
|
|
|
|
}
|
2009-10-18 13:31:55 +00:00
|
|
|
}
|
2011-08-28 10:58:26 +00:00
|
|
|
|
2011-09-08 23:10:41 +00:00
|
|
|
CDialogManage::UpdateSkins(meterWindow, true);
|
2011-08-28 10:58:26 +00:00
|
|
|
delete meterWindow;
|
2009-10-18 13:31:55 +00:00
|
|
|
}
|
2011-08-28 10:58:26 +00:00
|
|
|
while (!m_DelayDeleteList.empty());
|
2010-04-08 23:16:43 +00:00
|
|
|
|
2011-08-28 10:58:26 +00:00
|
|
|
CDialogAbout::UpdateSkins();
|
2009-10-17 06:43:18 +00:00
|
|
|
}
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2009-10-17 06:43:18 +00:00
|
|
|
bool CRainmeter::DeleteMeterWindow(CMeterWindow* meterWindow, bool bLater)
|
|
|
|
{
|
|
|
|
if (bLater)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
if (meterWindow)
|
|
|
|
{
|
|
|
|
m_DelayDeleteList.push_back(meterWindow);
|
|
|
|
meterWindow->RunBang(BANG_HIDEFADE, NULL); // Fade out the window
|
|
|
|
}
|
2009-10-17 06:43:18 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
if (meterWindow)
|
|
|
|
{
|
|
|
|
m_DelayDeleteList.remove(meterWindow); // Remove the window from the delete later list if it is there
|
|
|
|
}
|
2009-10-17 06:43:18 +00:00
|
|
|
|
|
|
|
std::map<std::wstring, CMeterWindow*>::iterator iter = m_Meters.begin();
|
2010-03-30 22:37:05 +00:00
|
|
|
for (; iter != m_Meters.end(); ++iter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2009-10-17 06:43:18 +00:00
|
|
|
if (meterWindow == NULL)
|
|
|
|
{
|
|
|
|
// Delete all meter windows
|
|
|
|
delete (*iter).second;
|
2011-03-29 19:21:57 +00:00
|
|
|
}
|
2009-10-17 06:43:18 +00:00
|
|
|
else if ((*iter).second == meterWindow)
|
|
|
|
{
|
|
|
|
m_Meters.erase(iter);
|
2010-04-08 23:16:43 +00:00
|
|
|
delete meterWindow;
|
2010-08-30 22:51:58 +00:00
|
|
|
|
2009-10-17 06:43:18 +00:00
|
|
|
return true;
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2009-10-17 06:43:18 +00:00
|
|
|
if (meterWindow == NULL)
|
|
|
|
{
|
|
|
|
m_Meters.clear();
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
CMeterWindow* CRainmeter::GetMeterWindow(const std::wstring& config)
|
|
|
|
{
|
2010-03-30 22:37:05 +00:00
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_Meters.begin();
|
|
|
|
for (; iter != m_Meters.end(); ++iter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-09-17 08:47:22 +00:00
|
|
|
if (_wcsicmp((*iter).first.c_str(), config.c_str()) == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
return (*iter).second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2010-03-23 16:15:07 +00:00
|
|
|
|
2010-12-16 17:04:14 +00:00
|
|
|
// Added by Peter Souza IV / psouza4 / 2010.12.13
|
|
|
|
//
|
|
|
|
// Returns a CMeterWindow object given a config's INI path and filename. Since plugins
|
|
|
|
// get the full path and filename of an INI file on Initialize(), but not the name of
|
|
|
|
// the config, this is used to convert the INI filename to a config name.
|
|
|
|
CMeterWindow* CRainmeter::GetMeterWindowByINI(const std::wstring& ini_searching)
|
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
if (_wcsnicmp(m_SkinPath.c_str(), ini_searching.c_str(), m_SkinPath.length()) == 0)
|
2010-12-16 17:04:14 +00:00
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
const std::wstring config_searching = ini_searching.substr(m_SkinPath.length());
|
2010-12-16 17:04:14 +00:00
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_Meters.begin();
|
|
|
|
for (; iter != m_Meters.end(); ++iter)
|
2010-12-16 17:04:14 +00:00
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
std::wstring config_current = (*iter).second->GetSkinName() + L"\\";
|
|
|
|
config_current += (*iter).second->GetSkinIniFile();
|
|
|
|
|
|
|
|
if (_wcsicmp(config_current.c_str(), config_searching.c_str()) == 0)
|
|
|
|
{
|
|
|
|
return (*iter).second;
|
|
|
|
}
|
2010-12-16 17:04:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-09-08 23:10:41 +00:00
|
|
|
std::pair<int, int> CRainmeter::GetMeterWindowIndex(const std::wstring& config, const std::wstring& iniFile)
|
2011-09-08 14:39:25 +00:00
|
|
|
{
|
|
|
|
std::pair<int, int> indexes;
|
|
|
|
|
|
|
|
for (int i = 0, isize = (int)m_ConfigStrings.size(); i < isize; ++i)
|
|
|
|
{
|
2011-09-08 23:10:41 +00:00
|
|
|
if (_wcsicmp(m_ConfigStrings[i].config.c_str(), config.c_str()) == 0)
|
2011-09-08 14:39:25 +00:00
|
|
|
{
|
|
|
|
for (int j = 0, jsize = (int)m_ConfigStrings[i].iniFiles.size(); j < jsize; ++j)
|
|
|
|
{
|
2011-09-08 23:10:41 +00:00
|
|
|
if (_wcsicmp(m_ConfigStrings[i].iniFiles[j].c_str(), iniFile.c_str()) == 0)
|
2011-09-08 14:39:25 +00:00
|
|
|
{
|
|
|
|
indexes = std::make_pair(i, j);
|
2011-09-08 23:10:41 +00:00
|
|
|
return indexes;
|
2011-09-08 14:39:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-08 23:10:41 +00:00
|
|
|
indexes = std::make_pair(-1, -1); // error
|
2011-09-08 14:39:25 +00:00
|
|
|
return indexes;
|
|
|
|
}
|
|
|
|
|
2010-03-23 16:15:07 +00:00
|
|
|
CMeterWindow* CRainmeter::GetMeterWindow(HWND hwnd)
|
|
|
|
{
|
2010-03-30 22:37:05 +00:00
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_Meters.begin();
|
|
|
|
for (; iter != m_Meters.end(); ++iter)
|
2010-03-23 16:15:07 +00:00
|
|
|
{
|
|
|
|
if ((*iter).second->GetWindow() == hwnd)
|
|
|
|
{
|
|
|
|
return (*iter).second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
void CRainmeter::GetMeterWindowsByLoadOrder(std::multimap<int, CMeterWindow*>& windows, const std::wstring& group)
|
|
|
|
{
|
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_Meters.begin();
|
|
|
|
for (; iter != m_Meters.end(); ++iter)
|
|
|
|
{
|
|
|
|
CMeterWindow* mw = (*iter).second;
|
|
|
|
if (mw && (group.empty() || mw->BelongsToGroup(group)))
|
|
|
|
{
|
|
|
|
windows.insert(std::pair<int, CMeterWindow*>(GetLoadOrder((*iter).first), mw));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-15 16:54:47 +00:00
|
|
|
void CRainmeter::SetLoadOrder(int configIndex, int order)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
std::multimap<int, int>::iterator iter = m_ConfigOrders.begin();
|
2010-03-30 22:37:05 +00:00
|
|
|
for ( ; iter != m_ConfigOrders.end(); ++iter)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
if ((*iter).second == configIndex) // already exists
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
if ((*iter).first != order)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
|
|
|
m_ConfigOrders.erase(iter);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
m_ConfigOrders.insert(std::pair<int, int>(order, configIndex));
|
2010-03-29 21:50:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int CRainmeter::GetLoadOrder(const std::wstring& config)
|
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
std::multimap<int, int>::const_iterator iter = m_ConfigOrders.begin();
|
2010-03-30 22:37:05 +00:00
|
|
|
for ( ; iter != m_ConfigOrders.end(); ++iter)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
if (m_ConfigStrings[(*iter).second].config == config)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
|
|
|
return (*iter).first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-08 14:39:25 +00:00
|
|
|
// LoadOrder not specified
|
2010-03-29 21:50:05 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2009-02-10 18:37:48 +00:00
|
|
|
** Quit
|
|
|
|
**
|
|
|
|
** Called when the module quits
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void CRainmeter::Quit(HINSTANCE dllInst)
|
|
|
|
{
|
|
|
|
// If we're running as Litestep's plugin, unregister the !bangs
|
2011-03-29 19:21:57 +00:00
|
|
|
if (!c_DummyLitestep)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
int Msgs[] = { LM_GETREVID, 0 };
|
|
|
|
// Unregister RevID message
|
|
|
|
if (m_TrayWindow && m_TrayWindow->GetWindow()) ::SendMessage(GetLitestepWnd(), LM_UNREGISTERMESSAGE, (WPARAM)m_TrayWindow->GetWindow(), (LPARAM)Msgs);
|
|
|
|
|
|
|
|
RemoveBangCommand("!RainmeterRefresh");
|
|
|
|
RemoveBangCommand("!RainmeterRedraw");
|
2010-12-28 13:31:17 +00:00
|
|
|
RemoveBangCommand("!RainmeterUpdate");
|
2009-02-10 18:37:48 +00:00
|
|
|
RemoveBangCommand("!RainmeterHide");
|
|
|
|
RemoveBangCommand("!RainmeterShow");
|
|
|
|
RemoveBangCommand("!RainmeterToggle");
|
2010-03-20 19:40:30 +00:00
|
|
|
RemoveBangCommand("!RainmeterHideFade");
|
|
|
|
RemoveBangCommand("!RainmeterShowFade");
|
|
|
|
RemoveBangCommand("!RainmeterToggleFade");
|
2011-04-08 18:14:32 +00:00
|
|
|
RemoveBangCommand("!RainmeterHideBlur");
|
|
|
|
RemoveBangCommand("!RainmeterShowBlur");
|
|
|
|
RemoveBangCommand("!RainmeterToggleBlur");
|
|
|
|
RemoveBangCommand("!RainmeterAddBlur");
|
|
|
|
RemoveBangCommand("!RainmeterRemoveBlur");
|
2009-02-10 18:37:48 +00:00
|
|
|
RemoveBangCommand("!RainmeterHideMeter");
|
|
|
|
RemoveBangCommand("!RainmeterShowMeter");
|
|
|
|
RemoveBangCommand("!RainmeterToggleMeter");
|
2010-07-17 13:02:34 +00:00
|
|
|
RemoveBangCommand("!RainmeterMoveMeter");
|
2010-12-28 13:31:17 +00:00
|
|
|
RemoveBangCommand("!RainmeterUpdateMeter");
|
2009-02-10 18:37:48 +00:00
|
|
|
RemoveBangCommand("!RainmeterHideMeasure");
|
|
|
|
RemoveBangCommand("!RainmeterShowMeasure");
|
|
|
|
RemoveBangCommand("!RainmeterToggleMeasure");
|
2010-12-28 13:31:17 +00:00
|
|
|
RemoveBangCommand("!RainmeterUpdateMeasure");
|
2009-02-10 18:37:48 +00:00
|
|
|
RemoveBangCommand("!RainmeterActivateConfig");
|
|
|
|
RemoveBangCommand("!RainmeterDeactivateConfig");
|
|
|
|
RemoveBangCommand("!RainmeterToggleConfig");
|
|
|
|
RemoveBangCommand("!RainmeterMove");
|
|
|
|
RemoveBangCommand("!RainmeterZPos");
|
2010-08-22 12:08:38 +00:00
|
|
|
RemoveBangCommand("!RainmeterClickThrough");
|
|
|
|
RemoveBangCommand("!RainmeterDraggable");
|
|
|
|
RemoveBangCommand("!RainmeterSnapEdges");
|
|
|
|
RemoveBangCommand("!RainmeterKeepOnScreen");
|
2010-03-20 19:40:30 +00:00
|
|
|
RemoveBangCommand("!RainmeterSetTransparency");
|
2010-07-17 13:02:34 +00:00
|
|
|
RemoveBangCommand("!RainmeterSetVariable");
|
|
|
|
|
|
|
|
RemoveBangCommand("!RainmeterRefreshGroup");
|
|
|
|
RemoveBangCommand("!RainmeterRedrawGroup");
|
2010-12-28 13:31:17 +00:00
|
|
|
RemoveBangCommand("!RainmeterUpdateGroup");
|
2010-07-17 13:02:34 +00:00
|
|
|
RemoveBangCommand("!RainmeterHideGroup");
|
|
|
|
RemoveBangCommand("!RainmeterShowGroup");
|
|
|
|
RemoveBangCommand("!RainmeterToggleGroup");
|
|
|
|
RemoveBangCommand("!RainmeterHideFadeGroup");
|
|
|
|
RemoveBangCommand("!RainmeterShowFadeGroup");
|
|
|
|
RemoveBangCommand("!RainmeterToggleFadeGroup");
|
|
|
|
RemoveBangCommand("!RainmeterHideMeterGroup");
|
|
|
|
RemoveBangCommand("!RainmeterShowMeterGroup");
|
|
|
|
RemoveBangCommand("!RainmeterToggleMeterGroup");
|
2010-12-28 13:31:17 +00:00
|
|
|
RemoveBangCommand("!RainmeterUpdateMeterGroup");
|
2010-07-17 13:02:34 +00:00
|
|
|
RemoveBangCommand("!RainmeterHideMeasureGroup");
|
|
|
|
RemoveBangCommand("!RainmeterShowMeasureGroup");
|
|
|
|
RemoveBangCommand("!RainmeterToggleMeasureGroup");
|
2010-12-28 13:31:17 +00:00
|
|
|
RemoveBangCommand("!RainmeterUpdateMeasureGroup");
|
2010-07-17 13:02:34 +00:00
|
|
|
RemoveBangCommand("!RainmeterDeactivateConfigGroup");
|
|
|
|
RemoveBangCommand("!RainmeterZPosGroup");
|
2010-08-22 12:08:38 +00:00
|
|
|
RemoveBangCommand("!RainmeterClickThroughGroup");
|
|
|
|
RemoveBangCommand("!RainmeterDraggableGroup");
|
|
|
|
RemoveBangCommand("!RainmeterSnapEdgesGroup");
|
|
|
|
RemoveBangCommand("!RainmeterKeepOnScreenGroup");
|
2010-07-17 13:02:34 +00:00
|
|
|
RemoveBangCommand("!RainmeterSetTransparencyGroup");
|
|
|
|
RemoveBangCommand("!RainmeterSetVariableGroup");
|
|
|
|
|
|
|
|
RemoveBangCommand("!RainmeterRefreshApp");
|
2009-02-10 18:37:48 +00:00
|
|
|
RemoveBangCommand("!RainmeterLsBoxHook");
|
|
|
|
RemoveBangCommand("!RainmeterAbout");
|
2011-08-28 16:42:34 +00:00
|
|
|
RemoveBangCommand("!RainmeterManage");
|
2010-07-17 13:02:34 +00:00
|
|
|
RemoveBangCommand("!RainmeterSkinMenu");
|
|
|
|
RemoveBangCommand("!RainmeterTrayMenu");
|
2009-02-10 18:37:48 +00:00
|
|
|
RemoveBangCommand("!RainmeterResetStats");
|
2010-08-03 15:25:38 +00:00
|
|
|
RemoveBangCommand("!RainmeterWriteKeyValue");
|
2009-02-10 18:37:48 +00:00
|
|
|
RemoveBangCommand("!RainmeterPluginBang");
|
2009-08-04 09:48:03 +00:00
|
|
|
RemoveBangCommand("!RainmeterQuit");
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2009-02-10 18:37:48 +00:00
|
|
|
** ScanForConfigs
|
|
|
|
**
|
|
|
|
** Scans all the subfolders and locates the ini-files.
|
|
|
|
*/
|
2010-11-11 20:24:59 +00:00
|
|
|
void CRainmeter::ScanForConfigs(const std::wstring& path)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
m_ConfigStrings.clear();
|
|
|
|
m_ConfigMenu.clear();
|
2010-03-29 21:50:05 +00:00
|
|
|
m_ConfigOrders.clear();
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2009-09-18 18:42:50 +00:00
|
|
|
ScanForConfigsRecursive(path, L"", 0, m_ConfigMenu, false);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2010-11-11 20:24:59 +00:00
|
|
|
int CRainmeter::ScanForConfigsRecursive(const std::wstring& path, std::wstring base, int index, std::vector<CONFIGMENU>& menu, bool DontRecurse)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-03-29 19:21:57 +00:00
|
|
|
WIN32_FIND_DATA fileData; // Data structure describes the file found
|
|
|
|
HANDLE hSearch; // Search handle returned by FindFirstFile
|
2011-07-15 11:48:50 +00:00
|
|
|
std::list<std::wstring> folders;
|
|
|
|
const bool first = base.empty();
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-07-15 11:48:50 +00:00
|
|
|
// Scan all .ini files and folders from the subfolder
|
|
|
|
std::wstring filter = path + base;
|
|
|
|
filter += L"\\*";
|
|
|
|
|
|
|
|
hSearch = FindFirstFileEx(
|
|
|
|
filter.c_str(),
|
|
|
|
(CSystem::GetOSPlatform() >= OSPLATFORM_7) ? FindExInfoBasic : FindExInfoStandard,
|
|
|
|
&fileData,
|
|
|
|
FindExSearchNameMatch,
|
|
|
|
NULL,
|
|
|
|
0);
|
|
|
|
|
|
|
|
if (hSearch != INVALID_HANDLE_VALUE)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
CONFIG config;
|
|
|
|
config.config = base;
|
2011-07-15 11:48:50 +00:00
|
|
|
config.active = 0;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2011-07-15 11:48:50 +00:00
|
|
|
if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
|
|
{
|
|
|
|
if (!(wcscmp(L"Backup", fileData.cFileName) == 0 && first) && // Skip the backup folder
|
|
|
|
wcscmp(L".", fileData.cFileName) != 0 &&
|
|
|
|
wcscmp(L"..", fileData.cFileName) != 0)
|
|
|
|
{
|
|
|
|
folders.push_back(fileData.cFileName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!first)
|
2010-07-18 21:35:52 +00:00
|
|
|
{
|
2011-07-15 11:48:50 +00:00
|
|
|
// Check whether the extension is ".ini"
|
|
|
|
size_t filenameLen = wcslen(fileData.cFileName);
|
|
|
|
if (filenameLen >= 4 && _wcsicmp(fileData.cFileName + (filenameLen - 4), L".ini") == 0)
|
|
|
|
{
|
|
|
|
CONFIGMENU menuItem;
|
|
|
|
menuItem.name = fileData.cFileName;
|
|
|
|
menuItem.index = m_ConfigStrings.size();
|
|
|
|
menu.push_back(menuItem);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-07-15 11:48:50 +00:00
|
|
|
config.iniFiles.push_back(fileData.cFileName);
|
|
|
|
config.commands.push_back(ID_CONFIG_FIRST + index++);
|
|
|
|
}
|
2010-07-18 21:35:52 +00:00
|
|
|
}
|
2011-07-15 11:48:50 +00:00
|
|
|
} while (FindNextFile(hSearch, &fileData));
|
|
|
|
|
|
|
|
FindClose(hSearch);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
if (!config.iniFiles.empty())
|
|
|
|
{
|
|
|
|
m_ConfigStrings.push_back(config);
|
|
|
|
}
|
2011-07-15 11:48:50 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-07-15 11:48:50 +00:00
|
|
|
if (!first)
|
|
|
|
{
|
2009-02-10 18:37:48 +00:00
|
|
|
base += L"\\";
|
|
|
|
}
|
|
|
|
|
2011-07-15 11:48:50 +00:00
|
|
|
std::list<std::wstring>::const_iterator iter = folders.begin();
|
|
|
|
for ( ; iter != folders.end(); ++iter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-07-15 11:48:50 +00:00
|
|
|
CONFIGMENU menuItem;
|
|
|
|
menuItem.name = (*iter);
|
|
|
|
menuItem.index = -1;
|
|
|
|
menu.push_back(menuItem);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-07-15 11:48:50 +00:00
|
|
|
if (!DontRecurse)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-07-15 11:48:50 +00:00
|
|
|
std::vector<CONFIGMENU>::iterator iter2 = menu.end() - 1;
|
|
|
|
index = ScanForConfigsRecursive(path, base + (*iter), index, (*iter2).children, false);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-07-15 11:48:50 +00:00
|
|
|
// Remove menu item if it has no child
|
|
|
|
if ((*iter2).children.empty())
|
2009-09-18 18:42:50 +00:00
|
|
|
{
|
2011-07-15 11:48:50 +00:00
|
|
|
menu.erase(iter2);
|
2009-09-18 18:42:50 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-07-15 11:48:50 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2009-08-12 17:11:52 +00:00
|
|
|
** ScanForThemes
|
|
|
|
**
|
|
|
|
** Scans the given folder for themes
|
|
|
|
*/
|
2010-11-11 20:24:59 +00:00
|
|
|
void CRainmeter::ScanForThemes(const std::wstring& path)
|
2009-08-12 17:11:52 +00:00
|
|
|
{
|
|
|
|
m_Themes.clear();
|
|
|
|
|
|
|
|
WIN32_FIND_DATA fileData; // Data structure describes the file found
|
2011-03-29 19:21:57 +00:00
|
|
|
HANDLE hSearch; // Search handle returned by FindFirstFile
|
2009-08-12 17:11:52 +00:00
|
|
|
|
|
|
|
// Scan for folders
|
|
|
|
std::wstring folders = path + L"\\*";
|
|
|
|
|
2011-07-15 11:48:50 +00:00
|
|
|
hSearch = FindFirstFileEx(
|
|
|
|
folders.c_str(),
|
|
|
|
(CSystem::GetOSPlatform() >= OSPLATFORM_7) ? FindExInfoBasic : FindExInfoStandard,
|
|
|
|
&fileData,
|
|
|
|
FindExSearchNameMatch,
|
|
|
|
NULL,
|
|
|
|
0);
|
|
|
|
|
|
|
|
if (hSearch != INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
do
|
2009-08-12 17:11:52 +00:00
|
|
|
{
|
2011-07-15 11:48:50 +00:00
|
|
|
if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY &&
|
|
|
|
wcscmp(L".", fileData.cFileName) != 0 &&
|
|
|
|
wcscmp(L"..", fileData.cFileName) != 0)
|
|
|
|
{
|
|
|
|
m_Themes.push_back(fileData.cFileName);
|
|
|
|
}
|
|
|
|
} while (FindNextFile(hSearch, &fileData));
|
2009-08-12 17:11:52 +00:00
|
|
|
|
2011-07-15 11:48:50 +00:00
|
|
|
FindClose(hSearch);
|
|
|
|
}
|
2009-08-12 17:11:52 +00:00
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
BOOL CRainmeter::ExecuteBang(const std::wstring& bang, const std::wstring& arg, CMeterWindow* meterWindow)
|
|
|
|
{
|
2011-07-03 08:58:53 +00:00
|
|
|
// Skip "!Rainmeter" or "!"
|
2011-07-03 15:21:48 +00:00
|
|
|
LPCWSTR name = bang.c_str();
|
|
|
|
name += (_wcsnicmp(name, L"!Rainmeter", 10) == 0) ? 10 : 1;
|
2011-07-03 08:58:53 +00:00
|
|
|
|
|
|
|
if (_wcsicmp(name, L"Refresh") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_REFRESH, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"RefreshApp") == 0)
|
2009-12-01 01:35:43 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterRefreshAppWide();
|
2009-12-01 01:35:43 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"Redraw") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_REDRAW, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"Update") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_UPDATE, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"Hide") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_HIDE, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"Show") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SHOW, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"Toggle") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLE, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"HideFade") == 0)
|
2010-03-20 19:40:30 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_HIDEFADE, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ShowFade") == 0)
|
2010-03-20 19:40:30 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SHOWFADE, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ToggleFade") == 0)
|
2010-03-20 19:40:30 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEFADE, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"HideMeter") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_HIDEMETER, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ShowMeter") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SHOWMETER, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ToggleMeter") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEMETER, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"MoveMeter") == 0)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_MOVEMETER, arg.c_str(), 3);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"UpdateMeter") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_UPDATEMETER, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"DisableMeasure") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_DISABLEMEASURE, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"EnableMeasure") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_ENABLEMEASURE, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ToggleMeasure") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEMEASURE, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"UpdateMeasure") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_UPDATEMEASURE, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-09 09:23:28 +00:00
|
|
|
else if (_wcsicmp(name, L"CommandMeasure") == 0)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_COMMANDMEASURE, arg.c_str(), 2);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ShowBlur") == 0)
|
2011-04-08 18:14:32 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SHOWBLUR, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"HideBlur") == 0)
|
2011-04-08 18:14:32 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_HIDEBLUR, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ToggleBlur") == 0)
|
2011-04-08 18:14:32 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEBLUR, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"AddBlur") == 0)
|
2011-04-08 18:14:32 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_ADDBLUR, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"RemoveBlur") == 0)
|
2011-04-08 18:14:32 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_REMOVEBLUR, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ActivateConfig") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterActivateConfigWide(arg.c_str());
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"DeactivateConfig") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterDeactivateConfigWide(arg.c_str());
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ToggleConfig") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterToggleConfigWide(arg.c_str());
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"Move") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_MOVE, arg.c_str(), 2);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ZPos") == 0 || _wcsicmp(name, L"ChangeZPos") == 0) // For backwards compatibility
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_ZPOS, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ClickThrough") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_CLICKTHROUGH, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"Draggable") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_DRAGGABLE, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"SnapEdges") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SNAPEDGES, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"KeepOnScreen") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_KEEPONSCREEN, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"SetTransparency") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SETTRANSPARENCY, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"SetVariable") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SETVARIABLE, arg.c_str(), 2);
|
|
|
|
}
|
2011-07-27 10:42:35 +00:00
|
|
|
else if (_wcsicmp(name, L"SetOption") == 0)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SETOPTION, arg.c_str(), 3);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"RefreshGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_REFRESH, arg.c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"UpdateGroup") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
|
|
|
BangGroupWithArgs(BANG_UPDATE, arg.c_str(), 0);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"RedrawGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_REDRAW, arg.c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"HideGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_HIDE, arg.c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ShowGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_SHOW, arg.c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ToggleGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_TOGGLE, arg.c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"HideFadeGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_HIDEFADE, arg.c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ShowFadeGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_SHOWFADE, arg.c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ToggleFadeGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_TOGGLEFADE, arg.c_str(), 0);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"HideMeterGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_HIDEMETERGROUP, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ShowMeterGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SHOWMETERGROUP, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ToggleMeterGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEMETERGROUP, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"UpdateMeterGroup") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_UPDATEMETERGROUP, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"DisableMeasureGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_DISABLEMEASUREGROUP, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"EnableMeasureGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_ENABLEMEASUREGROUP, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ToggleMeasureGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_TOGGLEMEASUREGROUP, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"UpdateMeasureGroup") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_UPDATEMEASUREGROUP, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"DeactivateConfigGroup") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterDeactivateConfigGroupWide(arg.c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ZPosGroup") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_ZPOS, arg.c_str(), 1);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ClickThroughGroup") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_CLICKTHROUGH, arg.c_str(), 1);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"DraggableGroup") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_DRAGGABLE, arg.c_str(), 1);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"SnapEdgesGroup") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_SNAPEDGES, arg.c_str(), 1);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"KeepOnScreenGroup") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_KEEPONSCREEN, arg.c_str(), 1);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"SetTransparencyGroup") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_SETTRANSPARENCY, arg.c_str(), 1);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"SetVariableGroup") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
BangGroupWithArgs(BANG_SETVARIABLE, arg.c_str(), 2);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-07-27 10:42:35 +00:00
|
|
|
else if (_wcsicmp(name, L"SetOptionGroup") == 0)
|
|
|
|
{
|
|
|
|
BangWithArgs(BANG_SETOPTIONGROUP, arg.c_str(), 3);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"About") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-08-28 10:58:26 +00:00
|
|
|
RainmeterAboutWide(arg.c_str());
|
|
|
|
}
|
|
|
|
else if (_wcsicmp(name, L"Manage") == 0)
|
|
|
|
{
|
|
|
|
RainmeterManageWide(arg.c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"SkinMenu") == 0)
|
2010-03-20 19:40:30 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterSkinMenuWide(arg.c_str());
|
2010-03-20 19:40:30 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"TrayMenu") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterTrayMenuWide();
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"ResetStats") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterResetStatsWide();
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"WriteKeyValue") == 0)
|
2010-08-03 15:10:42 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterWriteKeyValueWide(arg.c_str());
|
2010-08-03 15:10:42 +00:00
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"PluginBang") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
BangWithArgs(BANG_PLUGIN, arg.c_str(), 1);
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"LsBoxHook") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
// Nothing to do here (this works only with Litestep)
|
|
|
|
}
|
2011-07-03 08:58:53 +00:00
|
|
|
else if (_wcsicmp(name, L"Quit") == 0)
|
2009-08-04 09:48:03 +00:00
|
|
|
{
|
2010-12-17 00:09:37 +00:00
|
|
|
RainmeterQuitWide();
|
2009-08-04 09:48:03 +00:00
|
|
|
}
|
2011-07-03 15:21:48 +00:00
|
|
|
else if (_wcsicmp(bang.c_str(), L"!Execute") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
// Special case for multibang execution
|
|
|
|
std::wstring::size_type start = std::wstring::npos;
|
|
|
|
std::wstring::size_type end = std::wstring::npos;
|
|
|
|
int count = 0;
|
2011-02-15 13:22:19 +00:00
|
|
|
for (size_t i = 0, isize = arg.size(); i < isize; ++i)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
if (arg[i] == L'[')
|
|
|
|
{
|
|
|
|
if (count == 0)
|
|
|
|
{
|
|
|
|
start = i;
|
|
|
|
}
|
2010-03-30 22:37:05 +00:00
|
|
|
++count;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
else if (arg[i] == L']')
|
|
|
|
{
|
2010-03-30 22:37:05 +00:00
|
|
|
--count;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
if (count == 0 && start != std::wstring::npos)
|
|
|
|
{
|
|
|
|
end = i;
|
|
|
|
|
|
|
|
std::wstring command = arg.substr(start + 1, end - (start + 1));
|
|
|
|
// trim leading whitespace
|
2011-07-18 00:32:09 +00:00
|
|
|
std::wstring::size_type notwhite = command.find_first_not_of(L" \t\r\n");
|
2009-02-10 18:37:48 +00:00
|
|
|
command.erase(0, notwhite);
|
|
|
|
ExecuteCommand(command.c_str(), meterWindow);
|
|
|
|
}
|
|
|
|
}
|
2011-08-17 18:51:43 +00:00
|
|
|
else if (isize > (i + 2) &&
|
|
|
|
arg[i] == L'"' && arg[i + 1] == L'"' && arg[i + 2] == L'"')
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
|
|
|
i += 3;
|
|
|
|
|
|
|
|
std::wstring::size_type pos = arg.find(L"\"\"\"", i);
|
|
|
|
if (pos != std::wstring::npos)
|
|
|
|
{
|
|
|
|
i = pos + 2; // Skip "", loop will skip last "
|
|
|
|
}
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-08 15:37:33 +00:00
|
|
|
std::wstring error = L"Unknown bang: " + bang;
|
|
|
|
Log(LOG_ERROR, error.c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** ParseCommand
|
|
|
|
**
|
|
|
|
** Replaces the measure names with the actual text values.
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
std::wstring CRainmeter::ParseCommand(const WCHAR* command, CMeterWindow* meterWindow)
|
|
|
|
{
|
|
|
|
std::wstring strCommand = command;
|
|
|
|
|
2010-09-17 08:47:22 +00:00
|
|
|
if (_wcsnicmp(L"!execute", command, 8) == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
return strCommand;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find the [measures]
|
|
|
|
size_t start = 0, end = 0;
|
|
|
|
while (start != std::wstring::npos && end != std::wstring::npos)
|
|
|
|
{
|
|
|
|
start = strCommand.find(L'[', start);
|
|
|
|
if (start != std::wstring::npos)
|
|
|
|
{
|
2011-07-29 17:46:21 +00:00
|
|
|
end = strCommand.find(L']', start + 1);
|
2009-02-10 18:37:48 +00:00
|
|
|
if (end != std::wstring::npos)
|
|
|
|
{
|
|
|
|
std::wstring measureName = strCommand.substr(start + 1, end - (start + 1));
|
2011-07-29 17:46:21 +00:00
|
|
|
if (!measureName.empty() && measureName[0] != L'!') // Ignore bangs
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-07-29 17:46:21 +00:00
|
|
|
if (meterWindow)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-07-29 17:46:21 +00:00
|
|
|
if (strCommand[start + 1] == L'*' && strCommand[end - 1] == L'*')
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-07-29 17:46:21 +00:00
|
|
|
strCommand.erase(start + 1, 1);
|
|
|
|
strCommand.erase(end - 2, 1);
|
|
|
|
start = end - 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
const std::list<CMeasure*>& measures = meterWindow->GetMeasures();
|
|
|
|
std::list<CMeasure*>::const_iterator iter = measures.begin();
|
|
|
|
for ( ; iter != measures.end(); ++iter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-07-29 17:46:21 +00:00
|
|
|
if (_wcsicmp((*iter)->GetName(), measureName.c_str()) == 0)
|
2011-07-29 17:18:21 +00:00
|
|
|
{
|
2011-07-29 17:46:21 +00:00
|
|
|
std::wstring value = (*iter)->GetStringValue(AUTOSCALE_OFF, 1, -1, false);
|
|
|
|
strCommand.replace(start, (end - start) + 1, value);
|
|
|
|
start += value.length();
|
|
|
|
break;
|
2011-07-29 17:18:21 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-07-29 17:46:21 +00:00
|
|
|
if (iter == measures.end())
|
|
|
|
{
|
|
|
|
//LogWithArgs(LOG_WARNING, L"No such measure [%s] for execute string: %s", measureName.c_str(), command);
|
|
|
|
start = end + 1;
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-07-29 17:46:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
start = end + 1;
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return strCommand;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** ExecuteCommand
|
|
|
|
**
|
|
|
|
** Runs the given command or bang
|
|
|
|
**
|
|
|
|
*/
|
2011-03-29 19:21:57 +00:00
|
|
|
void CRainmeter::ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
if (command == NULL) return;
|
|
|
|
|
|
|
|
std::wstring strCommand = ParseCommand(command, meterWindow);
|
|
|
|
|
|
|
|
if (!strCommand.empty())
|
|
|
|
{
|
2011-08-18 02:27:52 +00:00
|
|
|
command = strCommand.c_str();
|
2010-09-02 16:03:15 +00:00
|
|
|
|
2011-08-17 05:56:46 +00:00
|
|
|
if (command[0] == L'!' && Rainmeter->GetDummyLitestep()) // Bangs
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-03-29 19:21:57 +00:00
|
|
|
if (meterWindow)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-08-17 05:56:46 +00:00
|
|
|
// Fake WM_COPYDATA to deliver bangs
|
|
|
|
COPYDATASTRUCT cds;
|
|
|
|
cds.cbData = (DWORD)((wcslen(command) + 1) * sizeof(WCHAR));
|
|
|
|
cds.dwData = 1;
|
|
|
|
cds.lpData = (void*)command;
|
|
|
|
meterWindow->OnCopyData(WM_COPYDATA, NULL, (LPARAM)&cds);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::wstring bang, arg;
|
|
|
|
size_t pos = strCommand.find(L' ');
|
2011-03-29 19:21:57 +00:00
|
|
|
if (pos != std::wstring::npos)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-07-14 00:26:53 +00:00
|
|
|
bang.assign(strCommand, 0, pos);
|
2009-02-10 18:37:48 +00:00
|
|
|
strCommand.erase(0, pos + 1);
|
|
|
|
arg = strCommand;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bang = strCommand;
|
|
|
|
}
|
|
|
|
ExecuteBang(bang, arg, meterWindow);
|
|
|
|
}
|
|
|
|
}
|
2011-08-18 04:05:54 +00:00
|
|
|
else
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
2011-08-18 04:05:54 +00:00
|
|
|
// Check for built-ins
|
|
|
|
if (_wcsnicmp(L"PLAY", command, 4) == 0)
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
2011-08-18 04:05:54 +00:00
|
|
|
if (command[4] == L' ' || // PLAY
|
|
|
|
_wcsnicmp(L"LOOP ", &command[4], 5) == 0) // PLAYLOOP
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
2011-08-18 04:05:54 +00:00
|
|
|
command += 4; // Skip PLAY
|
2011-08-17 05:56:46 +00:00
|
|
|
|
2011-08-18 04:05:54 +00:00
|
|
|
DWORD flags = SND_FILENAME | SND_ASYNC;
|
|
|
|
|
|
|
|
if (command[0] != L' ')
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
2011-08-18 04:05:54 +00:00
|
|
|
flags |= SND_LOOP | SND_NODEFAULT;
|
|
|
|
command += 4; // Skip LOOP
|
|
|
|
}
|
|
|
|
|
|
|
|
++command; // Skip the space
|
|
|
|
if (command[0] != L'\0')
|
|
|
|
{
|
|
|
|
strCommand = command;
|
|
|
|
|
2011-08-17 05:56:46 +00:00
|
|
|
// 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);
|
|
|
|
}
|
|
|
|
|
2011-09-08 14:39:25 +00:00
|
|
|
if (meterWindow)
|
|
|
|
{
|
|
|
|
meterWindow->MakePathAbsolute(strCommand);
|
|
|
|
}
|
|
|
|
|
2011-08-17 05:56:46 +00:00
|
|
|
PlaySound(strCommand.c_str(), NULL, flags);
|
|
|
|
}
|
2011-08-18 04:05:54 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else if (_wcsnicmp(L"STOP", &command[4], 4) == 0) // PLAYSTOP
|
|
|
|
{
|
|
|
|
PlaySound(NULL, NULL, SND_PURGE);
|
|
|
|
return;
|
2011-08-17 05:56:46 +00:00
|
|
|
}
|
|
|
|
}
|
2011-08-18 04:05:54 +00:00
|
|
|
|
|
|
|
// Run command
|
2011-08-17 05:56:46 +00:00
|
|
|
LSExecute(NULL, command, SW_SHOWNORMAL);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** ReadGeneralSettings
|
2011-03-29 19:21:57 +00:00
|
|
|
**
|
2009-02-10 18:37:48 +00:00
|
|
|
** Reads the general settings from the Rainmeter.ini file
|
|
|
|
**
|
|
|
|
*/
|
2010-11-11 20:24:59 +00:00
|
|
|
void CRainmeter::ReadGeneralSettings(const std::wstring& iniFile)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-12-21 04:49:01 +00:00
|
|
|
WCHAR buffer[MAX_PATH];
|
|
|
|
|
2010-07-10 12:56:37 +00:00
|
|
|
// Clear old settings
|
|
|
|
m_DesktopWorkAreas.clear();
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
CConfigParser parser;
|
2009-07-26 21:08:46 +00:00
|
|
|
parser.Initialize(iniFile.c_str(), this);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-07-07 23:46:44 +00:00
|
|
|
// Read Logging settings
|
|
|
|
m_Logging = 0!=parser.ReadInt(L"Rainmeter", L"Logging", 0);
|
|
|
|
c_Debug = 0!=parser.ReadInt(L"Rainmeter", L"Debug", 0);
|
|
|
|
|
2010-07-08 10:59:06 +00:00
|
|
|
if (m_Logging)
|
|
|
|
{
|
|
|
|
StartLogging();
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
if (m_TrayWindow)
|
|
|
|
{
|
|
|
|
m_TrayWindow->ReadConfig(parser);
|
|
|
|
}
|
|
|
|
|
2010-05-30 07:02:46 +00:00
|
|
|
c_GlobalConfig.netInSpeed = parser.ReadFloat(L"Rainmeter", L"NetInSpeed", 0.0);
|
|
|
|
c_GlobalConfig.netOutSpeed = parser.ReadFloat(L"Rainmeter", L"NetOutSpeed", 0.0);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-11-27 10:57:59 +00:00
|
|
|
m_DisableDragging = 0!=parser.ReadInt(L"Rainmeter", L"DisableDragging", 0);
|
2010-11-25 22:00:34 +00:00
|
|
|
m_DisableRDP = 0!=parser.ReadInt(L"Rainmeter", L"DisableRDP", 0);
|
|
|
|
|
2010-06-23 12:36:39 +00:00
|
|
|
m_ConfigEditor = parser.ReadString(L"Rainmeter", L"ConfigEditor", L"");
|
|
|
|
if (m_ConfigEditor.empty())
|
|
|
|
{
|
|
|
|
// Get the program path associated with .ini files
|
|
|
|
DWORD cchOut = MAX_PATH;
|
2010-12-21 04:49:01 +00:00
|
|
|
buffer[0] = L'\0';
|
2010-06-23 12:36:39 +00:00
|
|
|
|
|
|
|
HRESULT hr = AssocQueryString(ASSOCF_NOTRUNCATE, ASSOCSTR_EXECUTABLE, L".ini", L"open", buffer, &cchOut);
|
|
|
|
if (SUCCEEDED(hr) && cchOut > 0)
|
|
|
|
{
|
|
|
|
m_ConfigEditor = buffer;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_ConfigEditor = L"Notepad";
|
|
|
|
}
|
|
|
|
}
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
if (!m_ConfigEditor.empty() && m_ConfigEditor[0] != L'\"')
|
2009-09-30 03:24:29 +00:00
|
|
|
{
|
2010-06-23 12:36:39 +00:00
|
|
|
m_ConfigEditor.insert(0, L"\"");
|
2009-09-30 03:24:29 +00:00
|
|
|
m_ConfigEditor.append(L"\"");
|
|
|
|
}
|
2010-07-07 23:46:44 +00:00
|
|
|
|
|
|
|
m_LogViewer = parser.ReadString(L"Rainmeter", L"LogViewer", L"");
|
|
|
|
if (m_LogViewer.empty())
|
|
|
|
{
|
|
|
|
// Get the program path associated with .log files
|
|
|
|
DWORD cchOut = MAX_PATH;
|
2010-12-21 04:49:01 +00:00
|
|
|
buffer[0] = L'\0';
|
2010-07-07 23:46:44 +00:00
|
|
|
|
|
|
|
HRESULT hr = AssocQueryString(ASSOCF_NOTRUNCATE, ASSOCSTR_EXECUTABLE, L".log", L"open", buffer, &cchOut);
|
|
|
|
if (SUCCEEDED(hr) && cchOut > 0)
|
|
|
|
{
|
|
|
|
m_LogViewer = buffer;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_LogViewer = L"Notepad";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!m_LogViewer.empty() && m_LogViewer[0] != L'\"')
|
|
|
|
{
|
|
|
|
m_LogViewer.insert(0, L"\"");
|
|
|
|
m_LogViewer.append(L"\"");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c_Debug)
|
|
|
|
{
|
2010-12-19 23:06:13 +00:00
|
|
|
LogWithArgs(LOG_NOTICE, L"ConfigEditor: %s", m_ConfigEditor.c_str());
|
|
|
|
LogWithArgs(LOG_NOTICE, L"LogViewer: %s", m_LogViewer.c_str());
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
2010-06-23 12:36:39 +00:00
|
|
|
|
2010-05-30 07:02:46 +00:00
|
|
|
m_TrayExecuteL = parser.ReadString(L"Rainmeter", L"TrayExecuteL", L"", false);
|
|
|
|
m_TrayExecuteR = parser.ReadString(L"Rainmeter", L"TrayExecuteR", L"", false);
|
|
|
|
m_TrayExecuteM = parser.ReadString(L"Rainmeter", L"TrayExecuteM", L"", false);
|
|
|
|
m_TrayExecuteDL = parser.ReadString(L"Rainmeter", L"TrayExecuteDL", L"", false);
|
|
|
|
m_TrayExecuteDR = parser.ReadString(L"Rainmeter", L"TrayExecuteDR", L"", false);
|
|
|
|
m_TrayExecuteDM = parser.ReadString(L"Rainmeter", L"TrayExecuteDM", L"", false);
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
m_DisableVersionCheck = 0!=parser.ReadInt(L"Rainmeter", L"DisableVersionCheck", 0);
|
2010-07-10 12:56:37 +00:00
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
std::wstring area = parser.ReadString(L"Rainmeter", L"DesktopWorkArea", L"");
|
|
|
|
if (!area.empty())
|
|
|
|
{
|
2010-12-04 15:07:28 +00:00
|
|
|
m_DesktopWorkAreas[0] = parser.ParseRECT(area.c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
m_DesktopWorkAreaChanged = true;
|
|
|
|
}
|
|
|
|
|
2010-07-10 12:56:37 +00:00
|
|
|
for (UINT i = 1; i <= CSystem::GetMonitorCount(); ++i)
|
|
|
|
{
|
2010-12-16 20:35:44 +00:00
|
|
|
_snwprintf_s(buffer, _TRUNCATE, L"DesktopWorkArea@%i", i);
|
2010-07-10 12:56:37 +00:00
|
|
|
area = parser.ReadString(L"Rainmeter", buffer, L"");
|
|
|
|
if (!area.empty())
|
|
|
|
{
|
2010-12-04 15:07:28 +00:00
|
|
|
m_DesktopWorkAreas[i] = parser.ParseRECT(area.c_str());
|
2010-07-10 12:56:37 +00:00
|
|
|
m_DesktopWorkAreaChanged = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
m_DesktopWorkAreaType = 0!=parser.ReadInt(L"Rainmeter", L"DesktopWorkAreaType", 0);
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
// Check which configs are active
|
|
|
|
if (!c_DummyLitestep)
|
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
char* tmpSz = new char[MAX_LINE_LENGTH];
|
2009-02-10 18:37:48 +00:00
|
|
|
std::wstring skinName;
|
|
|
|
std::wstring skinIni = L"Rainmeter.ini";
|
|
|
|
|
|
|
|
// Check if step.rc has overrides these values
|
|
|
|
if (GetRCString("RainmeterCurrentConfig", tmpSz, "", MAX_LINE_LENGTH - 1))
|
|
|
|
{
|
|
|
|
skinName = ConvertToWide(tmpSz);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetRCString("RainmeterCurrentConfigIni", tmpSz, "Rainmeter.ini", MAX_LINE_LENGTH - 1))
|
|
|
|
{
|
|
|
|
skinIni = ConvertToWide(tmpSz);
|
|
|
|
}
|
2011-02-15 13:22:19 +00:00
|
|
|
|
|
|
|
delete [] tmpSz;
|
2011-03-29 19:21:57 +00:00
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
if (!skinName.empty())
|
|
|
|
{
|
|
|
|
if (!SetActiveConfig(skinName, skinIni))
|
|
|
|
{
|
2010-11-25 22:00:34 +00:00
|
|
|
std::wstring error = L"The selected skin (L" + skinName;
|
|
|
|
error += L"\\";
|
|
|
|
error += skinIni;
|
|
|
|
error += L") cannot be found.";
|
2010-09-21 11:09:36 +00:00
|
|
|
MessageBox(NULL, error.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
for (int i = 0, isize = (int)m_ConfigStrings.size(); i < isize; ++i)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
int active = parser.ReadInt(m_ConfigStrings[i].config.c_str(), L"Active", 0);
|
|
|
|
|
|
|
|
// Make sure there is a ini file available
|
2009-07-24 07:56:37 +00:00
|
|
|
if (active > 0 && active <= (int)m_ConfigStrings[i].iniFiles.size())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
m_ConfigStrings[i].active = active;
|
|
|
|
}
|
2010-07-17 13:02:34 +00:00
|
|
|
|
2011-07-15 16:54:47 +00:00
|
|
|
int order;
|
|
|
|
if (parser.IsSectionDefined(m_ConfigStrings[i].config.c_str()))
|
|
|
|
{
|
|
|
|
std::wstring orderStr = parser.ReadString(m_ConfigStrings[i].config.c_str(), L"LoadOrder", L"", false);
|
|
|
|
if (orderStr.empty())
|
|
|
|
{
|
|
|
|
order = 0;
|
|
|
|
}
|
|
|
|
else if (_wcsicmp(orderStr.c_str(), L"LAST") == 0)
|
|
|
|
{
|
|
|
|
order = INT_MAX;
|
|
|
|
}
|
|
|
|
else if (_wcsicmp(orderStr.c_str(), L"FIRST") == 0)
|
|
|
|
{
|
|
|
|
order = INT_MIN;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
order = _wtoi(orderStr.c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
order = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SetLoadOrder(i, order);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2009-02-10 18:37:48 +00:00
|
|
|
** SetActiveConfig
|
|
|
|
**
|
|
|
|
** Makes the given config active. If the config cannot be found this returns false.
|
|
|
|
*/
|
2010-11-11 20:24:59 +00:00
|
|
|
bool CRainmeter::SetActiveConfig(const std::wstring& skinName, const std::wstring& skinIni)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
for (int i = 0, isize = (int)m_ConfigStrings.size(); i < isize; ++i)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
m_ConfigStrings[i].active = 0; // Disable all other configs
|
|
|
|
|
|
|
|
if (skinName == m_ConfigStrings[i].config)
|
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
for (int j = 0, jsize = (int)m_ConfigStrings[i].iniFiles.size(); j < jsize; ++j)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
if (skinIni == m_ConfigStrings[i].iniFiles[j])
|
|
|
|
{
|
|
|
|
m_ConfigStrings[i].active = j + 1;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2010-03-29 21:50:05 +00:00
|
|
|
** RefreshAll
|
|
|
|
**
|
|
|
|
** Refreshes all active meter windows.
|
|
|
|
** Note: This function calls CMeterWindow::Refresh() directly for synchronization. Be careful about crash.
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
|
|
|
*/
|
2010-03-29 21:50:05 +00:00
|
|
|
void CRainmeter::RefreshAll()
|
|
|
|
{
|
|
|
|
// Read skins and settings
|
|
|
|
ReloadSettings();
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
// Change the work area if necessary
|
|
|
|
if (m_DesktopWorkAreaChanged)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
UpdateDesktopWorkArea(false);
|
2010-03-29 21:50:05 +00:00
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
// Make the sending order by using LoadOrder
|
|
|
|
std::multimap<int, CMeterWindow*> windows;
|
|
|
|
GetMeterWindowsByLoadOrder(windows);
|
|
|
|
|
2010-03-29 21:50:05 +00:00
|
|
|
// Prepare the helper window
|
2011-08-13 10:03:16 +00:00
|
|
|
CSystem::PrepareHelperWindow();
|
2010-03-29 21:50:05 +00:00
|
|
|
|
|
|
|
// Refresh all
|
2010-07-17 13:02:34 +00:00
|
|
|
std::multimap<int, CMeterWindow*>::const_iterator iter = windows.begin();
|
|
|
|
for ( ; iter != windows.end(); ++iter)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2010-07-22 00:31:59 +00:00
|
|
|
CMeterWindow* mw = (*iter).second;
|
|
|
|
if (mw)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2010-07-22 00:31:59 +00:00
|
|
|
// Verify whether the cached information is valid
|
|
|
|
int found = 0;
|
2011-09-08 14:39:25 +00:00
|
|
|
const std::wstring& skinConfig = mw->GetSkinName();
|
2011-02-15 13:22:19 +00:00
|
|
|
for (int i = 0, isize = (int)m_ConfigStrings.size(); i < isize; ++i)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
2010-09-17 08:47:22 +00:00
|
|
|
if (_wcsicmp(skinConfig.c_str(), m_ConfigStrings[i].config.c_str()) == 0)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
|
|
|
found = 1;
|
2011-09-08 14:39:25 +00:00
|
|
|
const std::wstring& skinIniFile = mw->GetSkinIniFile();
|
2011-02-15 13:22:19 +00:00
|
|
|
for (int j = 0, jsize = (int)m_ConfigStrings[i].iniFiles.size(); j < jsize; ++j)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
2010-09-17 08:47:22 +00:00
|
|
|
if (_wcsicmp(skinIniFile.c_str(), m_ConfigStrings[i].iniFiles[j].c_str()) == 0)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
|
|
|
found = 2;
|
|
|
|
if (m_ConfigStrings[i].active != j + 1)
|
|
|
|
{
|
|
|
|
// Switch to new ini-file order
|
|
|
|
m_ConfigStrings[i].active = j + 1;
|
|
|
|
WriteActive(skinConfig, j);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (found == 1) // Not found in ini-files
|
|
|
|
{
|
|
|
|
DeactivateConfig(mw, i);
|
|
|
|
|
2010-11-25 22:00:34 +00:00
|
|
|
std::wstring message = L"Unable to refresh skin \"" + skinConfig;
|
2010-09-21 08:32:41 +00:00
|
|
|
message += L"\\";
|
2010-11-11 20:24:59 +00:00
|
|
|
message += skinIniFile;
|
2011-09-09 16:31:55 +00:00
|
|
|
message += L"\": File not found.";
|
2010-07-22 00:31:59 +00:00
|
|
|
MessageBox(NULL, message.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (found != 2)
|
|
|
|
{
|
|
|
|
if (found == 0) // Not found in configs
|
|
|
|
{
|
|
|
|
DeactivateConfig(mw, -2); // -2 = Deactivate the config forcibly
|
|
|
|
|
2010-11-25 22:00:34 +00:00
|
|
|
std::wstring message = L"Unable to refresh config \"" + skinConfig;
|
2010-09-21 08:32:41 +00:00
|
|
|
message += L"\": Config not found.";
|
2010-07-22 00:31:59 +00:00
|
|
|
MessageBox(NULL, message.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2010-03-29 21:50:05 +00:00
|
|
|
try
|
|
|
|
{
|
2010-07-22 00:31:59 +00:00
|
|
|
mw->Refresh(false, true);
|
2010-03-29 21:50:05 +00:00
|
|
|
}
|
|
|
|
catch (CError& error)
|
|
|
|
{
|
2011-09-08 17:05:48 +00:00
|
|
|
LogError(error);
|
2010-03-29 21:50:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-08-28 12:28:00 +00:00
|
|
|
|
2011-09-04 07:40:12 +00:00
|
|
|
CDialogAbout::UpdateSkins();
|
2011-08-28 12:28:00 +00:00
|
|
|
CDialogManage::UpdateSkins(NULL);
|
2010-03-29 21:50:05 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-09-04 07:40:12 +00:00
|
|
|
void CRainmeter::LoadTheme(const std::wstring& name)
|
|
|
|
{
|
|
|
|
// Delete all meter windows
|
|
|
|
DeleteMeterWindow(NULL, false);
|
|
|
|
|
|
|
|
// Make a copy of current Rainmeter.ini
|
|
|
|
std::wstring backup = GetSettingsPath() + L"Themes\\Backup";
|
|
|
|
CreateDirectory(backup.c_str(), NULL);
|
|
|
|
backup += L"\\Rainmeter.thm";
|
|
|
|
CSystem::CopyFiles(m_IniFile, backup);
|
|
|
|
|
|
|
|
// Replace Rainmeter.ini with theme
|
|
|
|
std::wstring theme = Rainmeter->GetSettingsPath() + L"Themes\\";
|
|
|
|
theme += name;
|
|
|
|
std::wstring wallpaper = theme + L"\\RainThemes.bmp";
|
|
|
|
theme += L"\\Rainmeter.thm";
|
|
|
|
CSystem::CopyFiles(theme, Rainmeter->GetIniFile());
|
|
|
|
|
|
|
|
PreserveSetting(backup, L"SkinPath");
|
|
|
|
PreserveSetting(backup, L"ConfigEditor");
|
|
|
|
PreserveSetting(backup, L"LogViewer");
|
|
|
|
PreserveSetting(backup, L"Logging");
|
|
|
|
PreserveSetting(backup, L"DisableVersionCheck");
|
|
|
|
PreserveSetting(backup, L"TrayExecuteL", false);
|
|
|
|
PreserveSetting(backup, L"TrayExecuteM", false);
|
|
|
|
PreserveSetting(backup, L"TrayExecuteR", false);
|
|
|
|
PreserveSetting(backup, L"TrayExecuteDM", false);
|
|
|
|
PreserveSetting(backup, L"TrayExecuteDR", false);
|
|
|
|
|
|
|
|
// Set wallpaper if it exists
|
|
|
|
if (_waccess(wallpaper.c_str(), 0) != -1)
|
|
|
|
{
|
|
|
|
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)wallpaper.c_str(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
ReloadSettings();
|
|
|
|
|
|
|
|
// Create meter windows for active configs
|
2011-09-04 18:06:19 +00:00
|
|
|
ActivateActiveConfigs();
|
2011-09-04 07:40:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CRainmeter::PreserveSetting(const std::wstring& from, LPCTSTR key, bool replace)
|
|
|
|
{
|
|
|
|
WCHAR* buffer = new WCHAR[MAX_LINE_LENGTH];
|
|
|
|
|
|
|
|
if ((replace || GetPrivateProfileString(L"Rainmeter", key, L"", buffer, 4, m_IniFile.c_str()) == 0) &&
|
|
|
|
GetPrivateProfileString(L"Rainmeter", key, L"", buffer, MAX_LINE_LENGTH, from.c_str()) > 0)
|
|
|
|
{
|
|
|
|
WritePrivateProfileString(L"Rainmeter", key, buffer, m_IniFile.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
delete [] buffer;
|
|
|
|
}
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2010-07-10 12:56:37 +00:00
|
|
|
** UpdateDesktopWorkArea
|
|
|
|
**
|
|
|
|
** Applies given DesktopWorkArea and DesktopWorkArea@n.
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void CRainmeter::UpdateDesktopWorkArea(bool reset)
|
|
|
|
{
|
|
|
|
bool changed = false;
|
|
|
|
|
|
|
|
if (reset)
|
|
|
|
{
|
|
|
|
if (!m_OldDesktopWorkAreas.empty())
|
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
for (size_t i = 0, isize = m_OldDesktopWorkAreas.size(); i < isize; ++i)
|
2010-07-10 12:56:37 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
RECT r = m_OldDesktopWorkAreas[i];
|
|
|
|
|
|
|
|
BOOL result = SystemParametersInfo(SPI_SETWORKAREA, 0, &r, 0);
|
|
|
|
|
|
|
|
if (c_Debug)
|
|
|
|
{
|
|
|
|
std::wstring format = L"Resetting WorkArea@%i: L=%i, T=%i, R=%i, B=%i (W=%i, H=%i)";
|
|
|
|
if (!result)
|
|
|
|
{
|
2011-09-08 14:39:25 +00:00
|
|
|
format += L" => FAIL";
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_DEBUG, format.c_str(), (int)i + 1, r.left, r.top, r.right, r.bottom, r.right - r.left, r.bottom - r.top);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2010-07-10 12:56:37 +00:00
|
|
|
}
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
const MULTIMONITOR_INFO& multimonInfo = CSystem::GetMultiMonitorInfo();
|
|
|
|
const std::vector<MONITOR_INFO>& monitors = multimonInfo.monitors;
|
|
|
|
|
2010-07-10 12:56:37 +00:00
|
|
|
if (m_OldDesktopWorkAreas.empty())
|
|
|
|
{
|
|
|
|
// Store old work areas for changing them back
|
2010-12-16 20:35:44 +00:00
|
|
|
for (size_t i = 0; i < CSystem::GetMonitorCount(); ++i)
|
2010-07-10 12:56:37 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
m_OldDesktopWorkAreas.push_back(monitors[i].work);
|
2010-07-10 12:56:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
if (c_Debug)
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_DEBUG, L"DesktopWorkAreaType: %s", m_DesktopWorkAreaType ? L"Margin" : L"Default");
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
|
2010-07-10 12:56:37 +00:00
|
|
|
for (UINT i = 0; i <= CSystem::GetMonitorCount(); ++i)
|
|
|
|
{
|
|
|
|
std::map<UINT, RECT>::const_iterator it = m_DesktopWorkAreas.find(i);
|
|
|
|
if (it != m_DesktopWorkAreas.end())
|
|
|
|
{
|
|
|
|
RECT r = it->second;
|
2010-07-17 13:02:34 +00:00
|
|
|
|
|
|
|
// Move rect to correct offset
|
|
|
|
if (m_DesktopWorkAreaType)
|
|
|
|
{
|
|
|
|
RECT margin = r;
|
|
|
|
r = (i == 0) ? monitors[multimonInfo.primary - 1].screen : monitors[i - 1].screen;
|
|
|
|
r.left += margin.left;
|
|
|
|
r.top += margin.top;
|
|
|
|
r.right -= margin.right;
|
|
|
|
r.bottom -= margin.bottom;
|
|
|
|
}
|
|
|
|
else
|
2010-07-10 12:56:37 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
if (i != 0)
|
|
|
|
{
|
|
|
|
const RECT screenRect = monitors[i - 1].screen;
|
|
|
|
r.left += screenRect.left;
|
|
|
|
r.top += screenRect.top;
|
|
|
|
r.right += screenRect.left;
|
|
|
|
r.bottom += screenRect.top;
|
|
|
|
}
|
2010-07-10 12:56:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BOOL result = SystemParametersInfo(SPI_SETWORKAREA, 0, &r, 0);
|
|
|
|
if (result)
|
|
|
|
{
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (c_Debug)
|
|
|
|
{
|
|
|
|
std::wstring format = L"Applying DesktopWorkArea";
|
|
|
|
if (i != 0)
|
|
|
|
{
|
2010-09-13 20:06:52 +00:00
|
|
|
WCHAR buffer[64];
|
2010-12-16 20:35:44 +00:00
|
|
|
_snwprintf_s(buffer, _TRUNCATE, L"@%i", i);
|
2010-07-10 12:56:37 +00:00
|
|
|
format += buffer;
|
|
|
|
}
|
2010-07-17 13:02:34 +00:00
|
|
|
format += L": L=%i, T=%i, R=%i, B=%i (W=%i, H=%i)";
|
2010-07-10 12:56:37 +00:00
|
|
|
if (!result)
|
|
|
|
{
|
2011-09-08 14:39:25 +00:00
|
|
|
format += L" => FAIL";
|
2010-07-10 12:56:37 +00:00
|
|
|
}
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_DEBUG, format.c_str(), r.left, r.top, r.right, r.bottom, r.right - r.left, r.bottom - r.top);
|
2010-07-10 12:56:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-17 13:02:34 +00:00
|
|
|
if (changed && CSystem::GetWindow())
|
2010-07-10 12:56:37 +00:00
|
|
|
{
|
2010-07-17 13:02:34 +00:00
|
|
|
// Update CSystem::MULTIMONITOR_INFO for for work area variables
|
|
|
|
SendMessageTimeout(CSystem::GetWindow(), WM_SETTINGCHANGE, SPI_SETWORKAREA, 0, SMTO_ABORTIFHUNG, 1000, NULL);
|
2010-07-10 12:56:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
/*
|
|
|
|
** ReadStats
|
|
|
|
**
|
|
|
|
** Reads the statistics from the ini-file
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void CRainmeter::ReadStats()
|
|
|
|
{
|
2011-04-16 20:05:14 +00:00
|
|
|
// If m_StatsFile doesn't exist, create it and copy the stats section from m_IniFile
|
|
|
|
if (_waccess(m_StatsFile.c_str(), 0) == -1)
|
|
|
|
{
|
|
|
|
WCHAR* tmpSz = new WCHAR[SHRT_MAX]; // Max size returned by GetPrivateProfileSection()
|
|
|
|
|
|
|
|
if (GetPrivateProfileSection(L"Statistics", tmpSz, SHRT_MAX, m_IniFile.c_str()) > 0)
|
|
|
|
{
|
|
|
|
WritePrivateProfileSection(L"Statistics", tmpSz, m_StatsFile.c_str());
|
|
|
|
WritePrivateProfileString(L"Statistics", NULL, NULL, m_IniFile.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
delete [] tmpSz;
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
// Only Net measure has stats at the moment
|
2011-08-03 19:44:40 +00:00
|
|
|
CMeasureNet::ReadStats(m_StatsFile.c_str(), m_StatsDate);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** WriteStats
|
|
|
|
**
|
2009-07-27 12:30:28 +00:00
|
|
|
** Writes the statistics to the ini-file. If bForce is false the stats are written only once per minute.
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
|
|
|
*/
|
2009-07-27 12:30:28 +00:00
|
|
|
void CRainmeter::WriteStats(bool bForce)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-06-05 12:32:18 +00:00
|
|
|
static ULONGLONG lastWrite = 0;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-06-05 12:32:18 +00:00
|
|
|
ULONGLONG ticks = CSystem::GetTickCount64();
|
|
|
|
|
|
|
|
if (bForce || (lastWrite + 1000 * 60 < ticks))
|
2009-07-27 12:30:28 +00:00
|
|
|
{
|
2011-06-05 12:32:18 +00:00
|
|
|
lastWrite = ticks;
|
2009-07-27 12:30:28 +00:00
|
|
|
|
|
|
|
// Only Net measure has stats at the moment
|
2011-08-03 19:44:40 +00:00
|
|
|
CMeasureNet::WriteStats(m_StatsFile.c_str(), m_StatsDate.c_str());
|
2009-07-27 12:30:28 +00:00
|
|
|
|
2011-04-16 20:05:14 +00:00
|
|
|
WritePrivateProfileString(NULL, NULL, NULL, m_StatsFile.c_str());
|
2009-07-27 12:30:28 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** ResetStats
|
|
|
|
**
|
|
|
|
** Clears the statistics
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void CRainmeter::ResetStats()
|
|
|
|
{
|
|
|
|
// Set the stats-date string
|
|
|
|
struct tm *newtime;
|
2011-03-29 19:21:57 +00:00
|
|
|
time_t long_time;
|
|
|
|
time(&long_time);
|
|
|
|
newtime = localtime(&long_time);
|
2009-02-10 18:37:48 +00:00
|
|
|
m_StatsDate = _wasctime(newtime);
|
2011-07-14 00:26:53 +00:00
|
|
|
m_StatsDate.erase(m_StatsDate.size() - 1);
|
2011-03-29 19:21:57 +00:00
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
// Only Net measure has stats at the moment
|
|
|
|
CMeasureNet::ResetStats();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** ShowContextMenu
|
|
|
|
**
|
|
|
|
** Opens the context menu in given coordinates.
|
|
|
|
**
|
|
|
|
*/
|
2011-03-29 19:21:57 +00:00
|
|
|
void CRainmeter::ShowContextMenu(POINT pos, CMeterWindow* meterWindow)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-08-03 15:10:42 +00:00
|
|
|
if (!m_MenuActive)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-08-03 15:10:42 +00:00
|
|
|
m_MenuActive = true;
|
2010-07-18 21:35:52 +00:00
|
|
|
|
|
|
|
// Show context menu, if no actions were executed
|
|
|
|
HMENU menu = LoadMenu(m_Instance, MAKEINTRESOURCE(IDR_CONTEXT_MENU));
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
if (menu)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-07-18 21:35:52 +00:00
|
|
|
HMENU subMenu = GetSubMenu(menu, 0);
|
2011-03-29 19:21:57 +00:00
|
|
|
if (subMenu)
|
2010-06-23 12:36:39 +00:00
|
|
|
{
|
2011-08-28 10:58:26 +00:00
|
|
|
SetMenuDefaultItem(subMenu, ID_CONTEXT_MANAGE, MF_BYCOMMAND);
|
|
|
|
|
2010-07-18 21:35:52 +00:00
|
|
|
if (!GetDummyLitestep())
|
|
|
|
{
|
2010-07-20 07:15:39 +00:00
|
|
|
// Disable Quit/Logging if ran as a Litestep plugin
|
2010-07-18 21:35:52 +00:00
|
|
|
EnableMenuItem(subMenu, ID_CONTEXT_QUIT, MF_BYCOMMAND | MF_GRAYED);
|
2011-08-19 03:12:01 +00:00
|
|
|
EnableMenuItem(subMenu, 10, MF_BYPOSITION | MF_GRAYED); // "Logging" menu
|
2010-07-08 10:59:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-07-20 07:15:39 +00:00
|
|
|
if (_waccess(m_LogFile.c_str(), 0) == -1)
|
2010-07-18 21:35:52 +00:00
|
|
|
{
|
2010-07-20 07:15:39 +00:00
|
|
|
EnableMenuItem(subMenu, ID_CONTEXT_SHOWLOGFILE, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
EnableMenuItem(subMenu, ID_CONTEXT_DELETELOGFILE, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
EnableMenuItem(subMenu, ID_CONTEXT_STOPLOG, MF_BYCOMMAND | MF_GRAYED);
|
2010-07-18 21:35:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-06-09 18:59:16 +00:00
|
|
|
EnableMenuItem(subMenu, (m_Logging) ? ID_CONTEXT_STARTLOG : ID_CONTEXT_STOPLOG, MF_BYCOMMAND | MF_GRAYED);
|
2010-07-18 21:35:52 +00:00
|
|
|
}
|
2010-07-07 23:46:44 +00:00
|
|
|
|
2010-07-20 07:15:39 +00:00
|
|
|
if (c_Debug)
|
|
|
|
{
|
|
|
|
CheckMenuItem(subMenu, ID_CONTEXT_DEBUGLOG, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
}
|
2010-07-18 21:35:52 +00:00
|
|
|
}
|
2009-08-12 17:11:52 +00:00
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
HMENU configMenu = GetSubMenu(subMenu, 4);
|
2010-07-18 21:35:52 +00:00
|
|
|
if (configMenu)
|
|
|
|
{
|
2011-08-20 04:55:29 +00:00
|
|
|
if (!m_ConfigMenu.empty())
|
2011-08-19 03:12:01 +00:00
|
|
|
{
|
2011-08-29 21:57:36 +00:00
|
|
|
DeleteMenu(configMenu, 0, MF_BYPOSITION); // "No skins available" menuitem
|
2011-08-20 04:55:29 +00:00
|
|
|
CreateConfigMenu(configMenu, m_ConfigMenu);
|
2011-08-19 03:12:01 +00:00
|
|
|
}
|
2010-06-21 16:00:19 +00:00
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
if (m_DisableDragging)
|
|
|
|
{
|
|
|
|
CheckMenuItem(configMenu, ID_CONTEXT_DISABLEDRAG, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
}
|
2010-07-18 21:35:52 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
HMENU themeMenu = GetSubMenu(subMenu, 5);
|
2010-07-18 21:35:52 +00:00
|
|
|
if (themeMenu)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-08-29 19:35:18 +00:00
|
|
|
if (!m_Themes.empty())
|
|
|
|
{
|
2011-08-29 21:57:36 +00:00
|
|
|
DeleteMenu(themeMenu, 0, MF_BYPOSITION); // "No themes available" menuitem
|
2011-08-29 19:35:18 +00:00
|
|
|
CreateThemeMenu(themeMenu);
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2010-06-23 12:36:39 +00:00
|
|
|
|
2010-07-18 21:35:52 +00:00
|
|
|
if (meterWindow)
|
2010-06-23 12:36:39 +00:00
|
|
|
{
|
2010-07-18 21:35:52 +00:00
|
|
|
HMENU rainmeterMenu = subMenu;
|
|
|
|
subMenu = CreateSkinMenu(meterWindow, 0, configMenu);
|
2011-08-19 03:12:01 +00:00
|
|
|
|
2011-08-20 04:55:29 +00:00
|
|
|
WCHAR buffer[256];
|
|
|
|
GetMenuString(menu, 0, buffer, 256, MF_BYPOSITION);
|
2011-08-28 10:58:26 +00:00
|
|
|
InsertMenu(subMenu, 11, MF_BYPOSITION | MF_POPUP, (UINT_PTR)rainmeterMenu, buffer);
|
|
|
|
InsertMenu(subMenu, 12, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
2010-06-23 12:36:39 +00:00
|
|
|
}
|
2010-07-18 21:35:52 +00:00
|
|
|
else
|
|
|
|
{
|
2011-08-19 03:12:01 +00:00
|
|
|
InsertMenu(subMenu, 12, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-07-18 21:35:52 +00:00
|
|
|
// Create a menu for all active configs
|
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = Rainmeter->GetAllMeterWindows().begin();
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-07-18 21:35:52 +00:00
|
|
|
int index = 0;
|
|
|
|
for (; iter != Rainmeter->GetAllMeterWindows().end(); ++iter)
|
|
|
|
{
|
|
|
|
CMeterWindow* mw = ((*iter).second);
|
|
|
|
HMENU skinMenu = CreateSkinMenu(mw, index, configMenu);
|
2011-08-19 03:12:01 +00:00
|
|
|
InsertMenu(subMenu, 12, MF_BYPOSITION | MF_POPUP, (UINT_PTR)skinMenu, mw->GetSkinName().c_str());
|
2010-07-18 21:35:52 +00:00
|
|
|
++index;
|
|
|
|
}
|
2010-06-23 12:36:39 +00:00
|
|
|
|
2010-07-18 21:35:52 +00:00
|
|
|
// Put Update notifications in the Tray menu
|
|
|
|
if (m_NewVersion)
|
|
|
|
{
|
2011-08-28 10:58:26 +00:00
|
|
|
InsertMenu(subMenu, 0, MF_BYPOSITION, ID_CONTEXT_NEW_VERSION, L"Update available");
|
|
|
|
HiliteMenuItem(Rainmeter->GetTrayWindow()->GetWindow(), subMenu, 0, MF_BYPOSITION | MF_HILITE);
|
2010-07-18 21:35:52 +00:00
|
|
|
InsertMenu(subMenu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-08-03 15:10:42 +00:00
|
|
|
HWND hWnd = WindowFromPoint(pos);
|
|
|
|
if (hWnd != NULL)
|
|
|
|
{
|
|
|
|
CMeterWindow* mw = GetMeterWindow(hWnd);
|
|
|
|
if (mw)
|
|
|
|
{
|
|
|
|
// Cancel the mouse event beforehand
|
|
|
|
mw->SetMouseLeaveEvent(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set the window to foreground
|
|
|
|
hWnd = meterWindow ? meterWindow->GetWindow() : m_TrayWindow->GetWindow();
|
2010-07-20 07:15:39 +00:00
|
|
|
HWND hWndForeground = GetForegroundWindow();
|
|
|
|
if (hWndForeground != hWnd)
|
|
|
|
{
|
|
|
|
DWORD foregroundThreadID = GetWindowThreadProcessId(hWndForeground, NULL);
|
|
|
|
DWORD currentThreadID = GetCurrentThreadId();
|
|
|
|
AttachThreadInput(currentThreadID, foregroundThreadID, TRUE);
|
|
|
|
SetForegroundWindow(hWnd);
|
|
|
|
AttachThreadInput(currentThreadID, foregroundThreadID, FALSE);
|
|
|
|
}
|
2010-08-03 15:10:42 +00:00
|
|
|
|
|
|
|
// Show context menu
|
2010-07-18 21:35:52 +00:00
|
|
|
TrackPopupMenu(
|
|
|
|
subMenu,
|
2011-03-29 19:21:57 +00:00
|
|
|
TPM_RIGHTBUTTON | TPM_LEFTALIGN,
|
2010-07-18 21:35:52 +00:00
|
|
|
pos.x,
|
|
|
|
pos.y,
|
|
|
|
0,
|
2010-07-20 07:15:39 +00:00
|
|
|
hWnd,
|
2010-07-18 21:35:52 +00:00
|
|
|
NULL
|
|
|
|
);
|
|
|
|
|
|
|
|
if (meterWindow)
|
|
|
|
{
|
|
|
|
DestroyMenu(subMenu);
|
|
|
|
}
|
2010-06-23 12:36:39 +00:00
|
|
|
}
|
2010-07-18 21:35:52 +00:00
|
|
|
|
|
|
|
DestroyMenu(menu);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2010-08-03 15:10:42 +00:00
|
|
|
m_MenuActive = false;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
HMENU CRainmeter::CreateConfigMenu(HMENU configMenu, std::vector<CONFIGMENU>& configMenuData)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-02-15 13:22:19 +00:00
|
|
|
if (!configMenuData.empty())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-08-19 03:12:01 +00:00
|
|
|
if (!configMenu)
|
|
|
|
{
|
|
|
|
configMenu = CreatePopupMenu();
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-08-20 04:55:29 +00:00
|
|
|
bool separator = false;
|
2011-06-09 18:59:16 +00:00
|
|
|
for (int i = 0, j = 0, isize = (int)configMenuData.size(); i < isize; ++i)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
if (configMenuData[i].index == -1)
|
|
|
|
{
|
2011-08-19 03:12:01 +00:00
|
|
|
HMENU submenu = CreateConfigMenu(NULL, configMenuData[i].children);
|
2009-02-10 18:37:48 +00:00
|
|
|
if (submenu)
|
|
|
|
{
|
2011-08-20 04:55:29 +00:00
|
|
|
if (separator)
|
|
|
|
{
|
|
|
|
// Insert a separator
|
|
|
|
InsertMenu(configMenu, i, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
|
|
|
|
++j;
|
|
|
|
separator = false;
|
|
|
|
}
|
2011-06-09 18:59:16 +00:00
|
|
|
InsertMenu(configMenu, i + j, MF_BYPOSITION | MF_POPUP, (UINT_PTR)submenu, configMenuData[i].name.c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CONFIG& config = m_ConfigStrings[configMenuData[i].index];
|
2011-06-09 18:59:16 +00:00
|
|
|
InsertMenu(configMenu, i, MF_BYPOSITION | ((config.active == i + 1) ? MF_CHECKED : MF_UNCHECKED), config.commands[i], configMenuData[i].name.c_str());
|
2011-08-20 04:55:29 +00:00
|
|
|
separator = true;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
2011-08-19 03:12:01 +00:00
|
|
|
|
|
|
|
return configMenu;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-08-19 03:12:01 +00:00
|
|
|
|
|
|
|
return NULL;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
void CRainmeter::CreateThemeMenu(HMENU themeMenu)
|
2009-08-12 17:11:52 +00:00
|
|
|
{
|
2011-08-29 21:57:36 +00:00
|
|
|
for (size_t i = 0, isize = m_Themes.size(); i < isize; ++i)
|
2009-08-12 17:11:52 +00:00
|
|
|
{
|
2011-08-29 21:57:36 +00:00
|
|
|
InsertMenu(themeMenu, i, MF_BYPOSITION, ID_THEME_FIRST + i, m_Themes[i].c_str());
|
2011-08-19 03:12:01 +00:00
|
|
|
}
|
2009-08-12 17:11:52 +00:00
|
|
|
}
|
|
|
|
|
2010-07-18 21:35:52 +00:00
|
|
|
HMENU CRainmeter::CreateSkinMenu(CMeterWindow* meterWindow, int index, HMENU configMenu)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
HMENU skinMenu = LoadMenu(m_Instance, MAKEINTRESOURCE(IDR_SKIN_MENU));
|
|
|
|
|
|
|
|
if (skinMenu)
|
|
|
|
{
|
|
|
|
HMENU subSkinMenu = GetSubMenu(skinMenu, 0);
|
|
|
|
RemoveMenu(skinMenu, 0, MF_BYPOSITION);
|
|
|
|
DestroyMenu(skinMenu);
|
|
|
|
skinMenu = subSkinMenu;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (skinMenu)
|
|
|
|
{
|
|
|
|
// Tick the position
|
2011-08-19 03:12:01 +00:00
|
|
|
HMENU settingsMenu = GetSubMenu(skinMenu, 4);
|
2010-06-23 12:36:39 +00:00
|
|
|
if (settingsMenu)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-06-23 12:36:39 +00:00
|
|
|
HMENU posMenu = GetSubMenu(settingsMenu, 0);
|
|
|
|
if (posMenu)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-08-28 10:58:26 +00:00
|
|
|
switch (meterWindow->GetWindowZPosition())
|
2010-06-23 12:36:39 +00:00
|
|
|
{
|
|
|
|
case ZPOSITION_ONDESKTOP:
|
|
|
|
CheckMenuItem(posMenu, ID_CONTEXT_SKINMENU_ONDESKTOP, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
break;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-06-23 12:36:39 +00:00
|
|
|
case ZPOSITION_ONBOTTOM:
|
|
|
|
CheckMenuItem(posMenu, ID_CONTEXT_SKINMENU_BOTTOM, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
break;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-06-23 12:36:39 +00:00
|
|
|
case ZPOSITION_ONTOP:
|
|
|
|
CheckMenuItem(posMenu, ID_CONTEXT_SKINMENU_TOPMOST, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
break;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-06-23 12:36:39 +00:00
|
|
|
case ZPOSITION_ONTOPMOST:
|
|
|
|
CheckMenuItem(posMenu, ID_CONTEXT_SKINMENU_VERYTOPMOST, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
break;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-06-23 12:36:39 +00:00
|
|
|
default:
|
|
|
|
CheckMenuItem(posMenu, ID_CONTEXT_SKINMENU_NORMAL, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
if (meterWindow->GetXFromRight()) CheckMenuItem(posMenu, ID_CONTEXT_SKINMENU_FROMRIGHT, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
if (meterWindow->GetYFromBottom()) CheckMenuItem(posMenu, ID_CONTEXT_SKINMENU_FROMBOTTOM, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
if (meterWindow->GetXPercentage()) CheckMenuItem(posMenu, ID_CONTEXT_SKINMENU_XPERCENTAGE, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
if (meterWindow->GetYPercentage()) CheckMenuItem(posMenu, ID_CONTEXT_SKINMENU_YPERCENTAGE, MF_BYCOMMAND | MF_CHECKED);
|
2009-03-24 04:29:48 +00:00
|
|
|
|
2010-06-23 12:36:39 +00:00
|
|
|
if (!c_DummyLitestep)
|
|
|
|
{
|
|
|
|
EnableMenuItem(posMenu, ID_CONTEXT_SKINMENU_ONDESKTOP, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
}
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
|
2010-06-23 12:36:39 +00:00
|
|
|
HMENU monitorMenu = GetSubMenu(posMenu, 0);
|
|
|
|
if (monitorMenu)
|
|
|
|
{
|
|
|
|
CreateMonitorMenu(monitorMenu, meterWindow);
|
|
|
|
}
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
// Tick the transparency
|
|
|
|
if (!meterWindow->GetNativeTransparency())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-08-19 03:12:01 +00:00
|
|
|
EnableMenuItem(settingsMenu, 1, MF_BYPOSITION | MF_GRAYED); // "Transparency" menu
|
|
|
|
EnableMenuItem(settingsMenu, ID_CONTEXT_SKINMENU_CLICKTHROUGH, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
HMENU alphaMenu = GetSubMenu(settingsMenu, 1);
|
|
|
|
if (alphaMenu)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-08-19 03:12:01 +00:00
|
|
|
int value = (int)(10 - meterWindow->GetAlphaValue() / 25.5);
|
|
|
|
value = min(9, value);
|
|
|
|
value = max(0, value);
|
|
|
|
CheckMenuItem(alphaMenu, value, MF_BYPOSITION | MF_CHECKED);
|
|
|
|
|
2011-08-20 04:55:29 +00:00
|
|
|
switch (meterWindow->GetWindowHide())
|
2011-08-19 03:12:01 +00:00
|
|
|
{
|
2011-08-20 04:55:29 +00:00
|
|
|
case HIDEMODE_FADEIN:
|
2011-08-19 03:12:01 +00:00
|
|
|
CheckMenuItem(alphaMenu, ID_CONTEXT_SKINMENU_TRANSPARENCY_FADEIN, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
EnableMenuItem(alphaMenu, ID_CONTEXT_SKINMENU_TRANSPARENCY_FADEOUT, MF_BYCOMMAND | MF_GRAYED);
|
2011-08-20 04:55:29 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case HIDEMODE_FADEOUT:
|
2011-08-19 03:12:01 +00:00
|
|
|
CheckMenuItem(alphaMenu, ID_CONTEXT_SKINMENU_TRANSPARENCY_FADEOUT, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
EnableMenuItem(alphaMenu, ID_CONTEXT_SKINMENU_TRANSPARENCY_FADEIN, MF_BYCOMMAND | MF_GRAYED);
|
2011-08-20 04:55:29 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case HIDEMODE_HIDE:
|
2011-08-19 03:12:01 +00:00
|
|
|
EnableMenuItem(alphaMenu, ID_CONTEXT_SKINMENU_TRANSPARENCY_FADEIN, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
EnableMenuItem(alphaMenu, ID_CONTEXT_SKINMENU_TRANSPARENCY_FADEOUT, MF_BYCOMMAND | MF_GRAYED);
|
2011-08-20 04:55:29 +00:00
|
|
|
break;
|
2011-08-19 03:12:01 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
// Tick the configs
|
2011-08-20 04:55:29 +00:00
|
|
|
switch (meterWindow->GetWindowHide())
|
2011-08-19 03:12:01 +00:00
|
|
|
{
|
2011-08-20 04:55:29 +00:00
|
|
|
case HIDEMODE_HIDE:
|
2011-08-19 03:12:01 +00:00
|
|
|
CheckMenuItem(settingsMenu, ID_CONTEXT_SKINMENU_HIDEONMOUSE, MF_BYCOMMAND | MF_CHECKED);
|
2011-08-20 04:55:29 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case HIDEMODE_FADEIN:
|
|
|
|
case HIDEMODE_FADEOUT:
|
2011-08-19 03:12:01 +00:00
|
|
|
EnableMenuItem(settingsMenu, ID_CONTEXT_SKINMENU_HIDEONMOUSE, MF_BYCOMMAND | MF_GRAYED);
|
2011-08-20 04:55:29 +00:00
|
|
|
break;
|
2011-08-19 03:12:01 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
if (meterWindow->GetSnapEdges())
|
|
|
|
{
|
|
|
|
CheckMenuItem(settingsMenu, ID_CONTEXT_SKINMENU_SNAPTOEDGES, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
if (meterWindow->GetSavePosition())
|
|
|
|
{
|
|
|
|
CheckMenuItem(settingsMenu, ID_CONTEXT_SKINMENU_REMEMBERPOSITION, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
if (m_DisableDragging)
|
|
|
|
{
|
|
|
|
EnableMenuItem(settingsMenu, ID_CONTEXT_SKINMENU_DRAGGABLE, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
}
|
|
|
|
else if (meterWindow->GetWindowDraggable())
|
|
|
|
{
|
|
|
|
CheckMenuItem(settingsMenu, ID_CONTEXT_SKINMENU_DRAGGABLE, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
if (meterWindow->GetClickThrough())
|
|
|
|
{
|
|
|
|
CheckMenuItem(settingsMenu, ID_CONTEXT_SKINMENU_CLICKTHROUGH, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
if (meterWindow->GetKeepOnScreen())
|
|
|
|
{
|
|
|
|
CheckMenuItem(settingsMenu, ID_CONTEXT_SKINMENU_KEEPONSCREEN, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
// Add the name of the Skin to the menu
|
2010-06-23 12:36:39 +00:00
|
|
|
const std::wstring& skinName = meterWindow->GetSkinName();
|
2011-08-19 03:12:01 +00:00
|
|
|
ModifyMenu(skinMenu, ID_CONTEXT_SKINMENU_OPENSKINSFOLDER, MF_BYCOMMAND, ID_CONTEXT_SKINMENU_OPENSKINSFOLDER, skinName.c_str());
|
|
|
|
SetMenuDefaultItem(skinMenu, ID_CONTEXT_SKINMENU_OPENSKINSFOLDER, FALSE);
|
|
|
|
|
|
|
|
// Remove dummy menuitem from the variants menu
|
|
|
|
HMENU variantsMenu = GetSubMenu(skinMenu, 2);
|
|
|
|
if (variantsMenu)
|
|
|
|
{
|
2011-08-20 04:55:29 +00:00
|
|
|
DeleteMenu(variantsMenu, 0, MF_BYPOSITION);
|
2011-08-19 03:12:01 +00:00
|
|
|
}
|
2011-03-29 19:21:57 +00:00
|
|
|
|
2011-08-19 03:12:01 +00:00
|
|
|
// Give the menuitem the unique id that depends on the skin
|
2009-02-10 18:37:48 +00:00
|
|
|
ChangeSkinIndex(skinMenu, index);
|
2010-06-23 12:36:39 +00:00
|
|
|
|
|
|
|
// Add the variants menu
|
2011-08-19 03:12:01 +00:00
|
|
|
if (variantsMenu)
|
2010-06-23 12:36:39 +00:00
|
|
|
{
|
2011-08-19 03:12:01 +00:00
|
|
|
for (int i = 0, isize = (int)m_ConfigStrings.size(); i < isize; ++i)
|
2010-06-23 12:36:39 +00:00
|
|
|
{
|
2011-08-19 03:12:01 +00:00
|
|
|
const CONFIG& config = m_ConfigStrings[i];
|
|
|
|
if (_wcsicmp(config.config.c_str(), skinName.c_str()) == 0)
|
2010-06-23 12:36:39 +00:00
|
|
|
{
|
2011-08-19 03:12:01 +00:00
|
|
|
for (int j = 0, jsize = (int)config.iniFiles.size(); j < jsize; ++j)
|
|
|
|
{
|
|
|
|
InsertMenu(variantsMenu, j, MF_BYPOSITION | ((config.active == j + 1) ? MF_CHECKED : MF_UNCHECKED), config.commands[j], config.iniFiles[j].c_str());
|
|
|
|
}
|
|
|
|
break;
|
2010-06-23 12:36:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-07-18 21:35:52 +00:00
|
|
|
|
|
|
|
// Add config's root menu
|
2011-06-09 18:59:16 +00:00
|
|
|
int itemCount = GetMenuItemCount(configMenu);
|
2010-07-18 21:35:52 +00:00
|
|
|
if (itemCount > 0)
|
|
|
|
{
|
|
|
|
std::wstring root = meterWindow->GetSkinName();
|
|
|
|
std::wstring::size_type pos = root.find_first_of(L'\\');
|
|
|
|
if (pos != std::wstring::npos)
|
|
|
|
{
|
|
|
|
root.erase(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < itemCount; ++i)
|
|
|
|
{
|
2011-06-09 18:59:16 +00:00
|
|
|
UINT state = GetMenuState(configMenu, i, MF_BYPOSITION);
|
|
|
|
if (state == 0xFFFFFFFF || (state & MF_POPUP) == 0) break;
|
|
|
|
|
|
|
|
WCHAR buffer[MAX_PATH];
|
2010-12-21 04:49:01 +00:00
|
|
|
if (GetMenuString(configMenu, i, buffer, MAX_PATH, MF_BYPOSITION))
|
2010-07-18 21:35:52 +00:00
|
|
|
{
|
2010-09-17 08:47:22 +00:00
|
|
|
if (_wcsicmp(root.c_str(), buffer) == 0)
|
2010-07-18 21:35:52 +00:00
|
|
|
{
|
|
|
|
HMENU configRootMenu = GetSubMenu(configMenu, i);
|
|
|
|
if (configRootMenu)
|
|
|
|
{
|
|
|
|
InsertMenu(skinMenu, 3, MF_BYPOSITION | MF_POPUP, (UINT_PTR)configRootMenu, root.c_str());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return skinMenu;
|
|
|
|
}
|
|
|
|
|
2010-06-23 12:36:39 +00:00
|
|
|
void CRainmeter::CreateMonitorMenu(HMENU monitorMenu, CMeterWindow* meterWindow)
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
{
|
|
|
|
bool screenDefined = meterWindow->GetXScreenDefined();
|
|
|
|
int screenIndex = meterWindow->GetXScreen();
|
|
|
|
|
|
|
|
// for the "Specified monitor" (@n)
|
2010-03-20 19:40:30 +00:00
|
|
|
if (CSystem::GetMonitorCount() > 0)
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
{
|
2010-03-20 19:40:30 +00:00
|
|
|
const MULTIMONITOR_INFO& multimonInfo = CSystem::GetMultiMonitorInfo();
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
const std::vector<MONITOR_INFO>& monitors = multimonInfo.monitors;
|
|
|
|
|
2011-02-15 13:22:19 +00:00
|
|
|
for (int i = 0, isize = (int)monitors.size(); i < isize; ++i)
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
{
|
2010-09-13 20:06:52 +00:00
|
|
|
WCHAR buffer[64];
|
2010-12-16 20:35:44 +00:00
|
|
|
_snwprintf_s(buffer, _TRUNCATE, L"@%i: ", i + 1);
|
2010-06-23 12:36:39 +00:00
|
|
|
std::wstring item = buffer;
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
|
|
|
|
size_t len = wcslen(monitors[i].monitorName);
|
|
|
|
if (len > 32)
|
|
|
|
{
|
|
|
|
item += std::wstring(monitors[i].monitorName, 32);
|
|
|
|
item += L"...";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item += monitors[i].monitorName;
|
|
|
|
}
|
|
|
|
|
2011-06-09 18:59:16 +00:00
|
|
|
InsertMenu(monitorMenu,
|
|
|
|
i + 3,
|
|
|
|
MF_BYPOSITION | ((screenDefined && screenIndex == i + 1) ? MF_CHECKED : MF_UNCHECKED) | ((!monitors[i].active) ? MF_GRAYED : MF_ENABLED),
|
|
|
|
ID_MONITOR_FIRST + i + 1,
|
|
|
|
item.c_str());
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-23 12:36:39 +00:00
|
|
|
// Tick the configs
|
|
|
|
if (!screenDefined)
|
|
|
|
{
|
|
|
|
CheckMenuItem(monitorMenu, ID_CONTEXT_SKINMENU_MONITOR_PRIMARY, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
}
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
|
2010-06-23 12:36:39 +00:00
|
|
|
if (screenDefined && screenIndex == 0)
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
{
|
2010-06-23 12:36:39 +00:00
|
|
|
CheckMenuItem(monitorMenu, ID_MONITOR_FIRST, MF_BYCOMMAND | MF_CHECKED);
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
}
|
|
|
|
|
2010-06-23 12:36:39 +00:00
|
|
|
if (meterWindow->GetAutoSelectScreen())
|
|
|
|
{
|
|
|
|
CheckMenuItem(monitorMenu, ID_CONTEXT_SKINMENU_MONITOR_AUTOSELECT, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
}
|
* Changed the way to get the information of the multiple display monitors.
This change brings the order of monitors close to the order of "Display Properties" due to using EnumDisplayDevices and EnumDisplaySettings instead of EnumDisplayMonitors. (If EnumDisplayDevices failed, EnumDisplayMonitors is used as before.)
-----
* Added the "Display Monitor" submenu in [Skins Menu]-[Position].
These menus convert the present position to the relative position from the specified monitor.
(But the meter window doesn't move to the specified monitor area immediately. Only converts.)
- "Use default: Primary monitor" removes the @-directive from WindowX/Y.
- @0(@1, @2, ...) adds the specified monitor number to WindowX/Y. @0 means "The Virtual Screen". (http://msdn.microsoft.com/en-us/library/dd145136%28VS.85%29.aspx)
- If "Auto-select based on window position" is checked, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this menu is unchecked. This setting can be manually made in either the [Rainmeter] (all configs) or individual config sections of Rainmeter.ini.
AutoSelectScreen
If set to 1, the WindowX and WindowY "@n" settings are made automatically based on the position of the meter's window. If a monitor is selected directly using "Display Monitor" in the Rainmeter / skin context menu, this setting is reset to 0.
-----
* Added the variables for multiple display monitors and the virtual screen.
All X/Y positions are represented in the virtual screen coordinates.
The following variables are for the virtual screen.
#VSCREENAREAX# is the X-position of the left-side of the virtual screen.
#VSCREENAREAY# is the Y-position of the top-side of the virtual screen.
#VSCREENAREAWIDTH# is the width of the virtual screen.
#VSCREENAREAHEIGHT# is the height of the virtual screen.
The following variables are for the PRESENT monitor.
Note that these variables automatically change by the WindowX and WindowY "@n" settings. If "@n" is not set, these variables return the value of the primary monitor.
#WORKAREAX# is the X-position of the left-side of the work area.
#WORKAREAY# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH# is the width of the work area.
#WORKAREAHEIGHT# is the height of the work area.
#SCREENAREAX# is the X-position of the left-side of the monitor screen.
#SCREENAREAY# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH# is the width of the display resolution.
#SCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the PRIMARY monitor.
#PWORKAREAX# is the X-position of the left-side of the work area.
#PWORKAREAY# is the Y-position of the top-side of the work area.
#PWORKAREAWIDTH# is the width of the work area.
#PWORKAREAHEIGHT# is the height of the work area.
#PSCREENAREAX# is the X-position of the left-side of the monitor screen. (maybe, always 0)
#PSCREENAREAY# is the Y-position of the top-side of the monitor screen. (maybe, always 0)
#PSCREENAREAWIDTH# is the width of the display resolution.
#PSCREENAREAHEIGHT# is the height of the display resolution.
The following variables are for the SPECIFIED monitor. (@n = @1, @2, ...)
#WORKAREAX@n# is the X-position of the left-side of the work area.
#WORKAREAY@n# is the Y-position of the top-side of the work area.
#WORKAREAWIDTH@n# is the width of the work area.
#WORKAREAHEIGHT@n# is the height of the work area.
#SCREENAREAX@n# is the X-position of the left-side of the monitor screen.
#SCREENAREAY@n# is the Y-position of the top-side of the monitor screen.
#SCREENAREAWIDTH@n# is the width of the display resolution.
#SCREENAREAHEIGHT@n# is the height of the display resolution.
-----
* Other related changes:
- Fixed the problem that the primary monitor isn't recognized correctly.
- Fixed the problem that the information of the multiple display monitors is refreshed excessively.
- For DynamicVariables, when display setting or workarea size has been changed, all variables are now updated to apply changed WORKAREA/SCREENAREA variables.
- Fixed the problem that the "On Desktop" window isn't dragged correctly when the top-left corner of the virtual screen has negative coordinates.
- Changed the way to stick the "On Desktop" window. ("SysListView32/FolderView" is used instead of "Progman/Program Manager".)
-----
* Other changes:
- When the meter window is draggable and isn't dragged, LeftMouseUpAction is now executed.
- Added MouseDoubleClickAction (LeftMouseDoubleClickAction, RightMouseDoubleClickAction, MiddleMouseDoubleClickAction). If MouseDoubleClickAction is empty when mouse button is double-clicked, MouseDownAction is executed instead.
- Fixed the problem that the Meter's hit-test code checks outside the area.
- Changed the way to set the #CURRENTCONFIG#. (CMeterWindow::GetSkinName() is now used instead of parsing the path.)
2009-12-18 05:58:37 +00:00
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
void CRainmeter::ChangeSkinIndex(HMENU menu, int index)
|
|
|
|
{
|
|
|
|
int count = GetMenuItemCount(menu);
|
|
|
|
|
2010-03-30 22:37:05 +00:00
|
|
|
for (int i = 0; i < count; ++i)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
HMENU subMenu = GetSubMenu(menu, i);
|
|
|
|
if (subMenu)
|
|
|
|
{
|
|
|
|
ChangeSkinIndex(subMenu, index);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WCHAR buffer[256];
|
|
|
|
GetMenuString(menu, i, buffer, 256, MF_BYPOSITION);
|
|
|
|
UINT id = GetMenuItemID(menu, i);
|
|
|
|
UINT flags = GetMenuState(menu, i, MF_BYPOSITION);
|
|
|
|
ModifyMenu(menu, i, MF_BYPOSITION | flags, id | (index << 16), buffer);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-08 10:59:06 +00:00
|
|
|
void CRainmeter::StartLogging()
|
|
|
|
{
|
|
|
|
// Check if the file exists
|
|
|
|
if (_waccess(m_LogFile.c_str(), 0) == -1)
|
|
|
|
{
|
|
|
|
// Create log file
|
|
|
|
HANDLE file = CreateFile(m_LogFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if (file != INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
CloseHandle(file);
|
|
|
|
ResetLoggingFlag(); // Re-enable logging
|
|
|
|
SetLogging(true);
|
|
|
|
|
2010-11-25 22:00:34 +00:00
|
|
|
std::wstring message = L"Log file created at: " + m_LogFile;
|
2010-09-21 11:09:36 +00:00
|
|
|
MessageBox(NULL, message.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONINFORMATION);
|
2010-07-08 10:59:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Disable logging
|
|
|
|
SetLogging(false);
|
|
|
|
ResetLoggingFlag();
|
|
|
|
|
2010-11-25 22:00:34 +00:00
|
|
|
std::wstring message = L"Unable to create log file: " + m_LogFile;
|
2010-09-21 11:09:36 +00:00
|
|
|
MessageBox(NULL, message.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONERROR);
|
2010-07-08 10:59:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SetLogging(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRainmeter::StopLogging()
|
|
|
|
{
|
|
|
|
SetLogging(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRainmeter::DeleteLogFile()
|
|
|
|
{
|
|
|
|
// Check if the file exists
|
|
|
|
if (_waccess(m_LogFile.c_str(), 0) != -1)
|
|
|
|
{
|
2010-11-25 22:00:34 +00:00
|
|
|
std::wstring message = L"Do you want to delete the following log file?\n" + m_LogFile;
|
|
|
|
int res = MessageBox(NULL, message.c_str(), APPNAME, MB_YESNO | MB_TOPMOST | MB_ICONQUESTION);
|
2010-07-08 10:59:06 +00:00
|
|
|
if (res == IDYES)
|
|
|
|
{
|
|
|
|
// Disable logging
|
|
|
|
SetLogging(false);
|
|
|
|
ResetLoggingFlag();
|
|
|
|
|
2010-08-03 15:10:42 +00:00
|
|
|
CSystem::RemoveFile(m_LogFile);
|
2010-07-08 10:59:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-28 10:58:26 +00:00
|
|
|
void CRainmeter::AddAboutLogInfo(int level, LPCWSTR time, LPCWSTR message)
|
2010-09-19 09:21:25 +00:00
|
|
|
{
|
2011-09-03 16:45:29 +00:00
|
|
|
// Store 20 last items
|
|
|
|
LOG_INFO logInfo = {level, time, message};
|
|
|
|
m_LogData.push_back(logInfo);
|
|
|
|
if (m_LogData.size() > 20)
|
|
|
|
{
|
|
|
|
m_LogData.pop_front();
|
|
|
|
}
|
2010-09-19 09:21:25 +00:00
|
|
|
|
2011-08-28 10:58:26 +00:00
|
|
|
CDialogAbout::AddLogItem(level, time, message);
|
2010-09-19 09:21:25 +00:00
|
|
|
}
|
|
|
|
|
2010-07-07 23:46:44 +00:00
|
|
|
void CRainmeter::SetLogging(bool logging)
|
|
|
|
{
|
|
|
|
m_Logging = logging;
|
|
|
|
WritePrivateProfileString(L"Rainmeter", L"Logging", logging ? L"1" : L"0", m_IniFile.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRainmeter::SetDebug(bool debug)
|
|
|
|
{
|
|
|
|
c_Debug = debug;
|
|
|
|
WritePrivateProfileString(L"Rainmeter", L"Debug", debug ? L"1" : L"0", m_IniFile.c_str());
|
|
|
|
}
|
|
|
|
|
2010-11-27 10:57:59 +00:00
|
|
|
void CRainmeter::SetDisableDragging(bool dragging)
|
2010-11-24 15:34:07 +00:00
|
|
|
{
|
2010-11-27 10:57:59 +00:00
|
|
|
m_DisableDragging = dragging;
|
|
|
|
WritePrivateProfileString(L"Rainmeter", L"DisableDragging", dragging ? L"1" : L"0", m_IniFile.c_str());
|
2010-11-24 15:34:07 +00:00
|
|
|
}
|
|
|
|
|
2011-08-28 10:58:26 +00:00
|
|
|
void CRainmeter::SetDisableVersionCheck(bool check)
|
|
|
|
{
|
|
|
|
m_DisableVersionCheck = check;
|
|
|
|
WritePrivateProfileString(L"Rainmeter", L"DisableVersionCheck", check ? L"1" : L"0" , m_IniFile.c_str());
|
|
|
|
}
|
|
|
|
|
2011-05-02 11:58:02 +00:00
|
|
|
void CRainmeter::TestSettingsFile(bool bDefaultIniLocation)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2009-07-24 07:56:37 +00:00
|
|
|
WritePrivateProfileString(L"Rainmeter", L"WriteTest", L"TRUE", m_IniFile.c_str());
|
|
|
|
WritePrivateProfileString(NULL, NULL, NULL, m_IniFile.c_str()); // FLUSH
|
|
|
|
|
|
|
|
WCHAR tmpSz[5];
|
|
|
|
bool bSuccess = (GetPrivateProfileString(L"Rainmeter", L"WriteTest", L"", tmpSz, 5, m_IniFile.c_str()) > 0);
|
|
|
|
if (bSuccess)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2009-07-24 07:56:37 +00:00
|
|
|
bSuccess = (wcscmp(L"TRUE", tmpSz) == 0);
|
2011-03-29 19:21:57 +00:00
|
|
|
WritePrivateProfileString(L"Rainmeter", L"WriteTest", NULL, m_IniFile.c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2009-07-24 07:56:37 +00:00
|
|
|
if (!bSuccess)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-09-08 14:39:25 +00:00
|
|
|
std::wstring error = L"Rainmeter.ini is not writable. Rainmeter will not\n"
|
|
|
|
L"be able to save any settings permanently.\n\n";
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-05-02 11:58:02 +00:00
|
|
|
if (!bDefaultIniLocation)
|
2009-07-24 07:56:37 +00:00
|
|
|
{
|
2009-08-26 17:37:15 +00:00
|
|
|
std::wstring strTarget = L"%APPDATA%\\Rainmeter\\";
|
|
|
|
ExpandEnvironmentVariables(strTarget);
|
2009-07-24 07:56:37 +00:00
|
|
|
|
2011-09-08 14:39:25 +00:00
|
|
|
error += L"You should quit Rainmeter and move the settings file from\n";
|
2009-07-24 07:56:37 +00:00
|
|
|
error += m_IniFile;
|
2011-09-08 14:39:25 +00:00
|
|
|
error += L"\n\nto\n";
|
2009-07-26 21:08:46 +00:00
|
|
|
error += strTarget;
|
2011-09-08 14:39:25 +00:00
|
|
|
error += L"\n\nAlternatively, simply remove the file and it will\n"
|
|
|
|
L"be automatically recreated in the correct location on\n"
|
|
|
|
L"next launch (current settings will be lost).";
|
2009-07-24 07:56:37 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-08 14:39:25 +00:00
|
|
|
error += L"Make sure that the settings file is not set as read-only and that\n"
|
|
|
|
L"the folder is writable. The file is located at:\n";
|
2009-07-24 07:56:37 +00:00
|
|
|
error += m_IniFile;
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-09-21 08:32:41 +00:00
|
|
|
MessageBox(NULL, error.c_str(), APPNAME, MB_OK | MB_ICONERROR);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2009-07-26 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::wstring CRainmeter::ExtractPath(const std::wstring& strFilePath)
|
|
|
|
{
|
2010-08-06 07:40:43 +00:00
|
|
|
std::wstring::size_type pos = strFilePath.find_last_of(L"\\/");
|
2009-07-26 21:08:46 +00:00
|
|
|
if (pos != std::wstring::npos)
|
|
|
|
{
|
|
|
|
return strFilePath.substr(0, pos + 1);
|
|
|
|
}
|
2010-08-06 07:40:43 +00:00
|
|
|
return L".\\";
|
2009-07-26 21:08:46 +00:00
|
|
|
}
|
|
|
|
|
2009-08-26 17:37:15 +00:00
|
|
|
void CRainmeter::ExpandEnvironmentVariables(std::wstring& strPath)
|
2009-07-26 21:08:46 +00:00
|
|
|
{
|
2010-07-22 00:31:59 +00:00
|
|
|
if (strPath.find(L'%') != std::wstring::npos)
|
2009-07-26 21:08:46 +00:00
|
|
|
{
|
2011-02-15 16:26:54 +00:00
|
|
|
DWORD bufSize = 4096;
|
2011-02-15 13:22:19 +00:00
|
|
|
WCHAR* buffer = new WCHAR[bufSize]; // lets hope the buffer is large enough...
|
2009-07-26 21:08:46 +00:00
|
|
|
|
2010-07-22 00:31:59 +00:00
|
|
|
// %APPDATA% is a special case
|
|
|
|
std::wstring::size_type pos = strPath.find(L"%APPDATA%");
|
|
|
|
if (pos != std::wstring::npos)
|
2009-07-26 21:08:46 +00:00
|
|
|
{
|
2010-07-22 00:31:59 +00:00
|
|
|
HRESULT hr = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, buffer);
|
|
|
|
if (SUCCEEDED(hr))
|
|
|
|
{
|
2010-07-22 01:50:22 +00:00
|
|
|
std::wstring path = buffer;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
strPath.replace(pos, 9, path);
|
|
|
|
}
|
|
|
|
while ((pos = strPath.find(L"%APPDATA%", pos + path.length())) != std::wstring::npos);
|
2010-07-22 00:31:59 +00:00
|
|
|
}
|
2009-07-26 21:08:46 +00:00
|
|
|
}
|
2010-07-22 00:31:59 +00:00
|
|
|
|
|
|
|
if (strPath.find(L'%') != std::wstring::npos)
|
2009-07-26 21:08:46 +00:00
|
|
|
{
|
2010-07-22 00:31:59 +00:00
|
|
|
// Expand the environment variables
|
2011-02-15 13:22:19 +00:00
|
|
|
DWORD ret = ExpandEnvironmentStrings(strPath.c_str(), buffer, bufSize);
|
|
|
|
if (ret != 0 && ret < bufSize)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
|
|
|
strPath = buffer;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-09-09 16:31:55 +00:00
|
|
|
LogWithArgs(LOG_WARNING, L"Unable to expand environment strings in: %s", strPath.c_str());
|
2010-07-22 00:31:59 +00:00
|
|
|
}
|
2009-07-26 21:08:46 +00:00
|
|
|
}
|
2011-02-15 13:22:19 +00:00
|
|
|
|
|
|
|
delete [] buffer;
|
2009-07-26 21:08:46 +00:00
|
|
|
}
|
|
|
|
}
|