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
|
2012-01-23 06:36:15 +00:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-02-10 18:37:48 +00:00
|
|
|
*/
|
|
|
|
|
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;
|
|
|
|
|
2012-02-15 02:51:27 +00:00
|
|
|
enum TIMER
|
|
|
|
{
|
|
|
|
TIMER_NETSTATS = 1
|
|
|
|
};
|
|
|
|
enum INTERVAL
|
|
|
|
{
|
|
|
|
INTERVAL_NETSTATS = 120000
|
|
|
|
};
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
CRainmeter* Rainmeter; // The module
|
|
|
|
|
2011-09-29 06:04:20 +00:00
|
|
|
/*
|
2012-02-14 17:00:07 +00:00
|
|
|
** Initializes Rainmeter.
|
2011-09-29 06:04:20 +00:00
|
|
|
**
|
|
|
|
*/
|
2012-02-16 17:38:45 +00:00
|
|
|
int RainmeterMain(LPWSTR cmdLine)
|
2011-09-29 06:04:20 +00:00
|
|
|
{
|
2012-05-24 06:19:52 +00:00
|
|
|
if (cmdLine[0] == L'!' || cmdLine[0] == L'[')
|
2011-09-29 06:04:20 +00:00
|
|
|
{
|
2012-05-24 06:19:52 +00:00
|
|
|
HWND wnd = FindWindow(RAINMETER_CLASS_NAME, RAINMETER_WINDOW_NAME);
|
|
|
|
if (wnd)
|
2012-02-14 17:00:07 +00:00
|
|
|
{
|
|
|
|
// Deliver bang to existing Rainmeter instance
|
2012-05-24 06:19:52 +00:00
|
|
|
COPYDATASTRUCT cds;
|
2012-02-14 17:00:07 +00:00
|
|
|
cds.dwData = 1;
|
|
|
|
cds.cbData = (DWORD)((wcslen(cmdLine) + 1) * sizeof(WCHAR));
|
|
|
|
cds.lpData = (PVOID)cmdLine;
|
|
|
|
SendMessage(wnd, WM_COPYDATA, NULL, (LPARAM)&cds);
|
|
|
|
return 0;
|
|
|
|
}
|
2012-05-24 09:19:32 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else if (cmdLine[0] == L'"')
|
|
|
|
{
|
|
|
|
// Strip quotes
|
|
|
|
++cmdLine;
|
|
|
|
WCHAR* pos = wcsrchr(cmdLine, L'"');
|
|
|
|
if (pos)
|
2011-09-29 06:04:20 +00:00
|
|
|
{
|
2012-05-24 09:19:32 +00:00
|
|
|
*pos = L'\0';
|
2011-09-29 06:04:20 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-14 17:00:07 +00:00
|
|
|
|
|
|
|
// Avoid loading a dll from current directory
|
|
|
|
SetDllDirectory(L"");
|
2012-05-24 09:19:32 +00:00
|
|
|
|
2012-02-14 17:00:07 +00:00
|
|
|
int ret = 1;
|
2012-05-24 09:19:32 +00:00
|
|
|
|
2012-05-24 11:15:03 +00:00
|
|
|
Rainmeter = new CRainmeter;
|
|
|
|
if (Rainmeter)
|
2011-09-29 06:04:20 +00:00
|
|
|
{
|
2012-05-24 11:15:03 +00:00
|
|
|
ret = Rainmeter->Initialize(cmdLine);
|
|
|
|
if (ret == 0)
|
2012-02-14 17:00:07 +00:00
|
|
|
{
|
2012-05-24 11:15:03 +00:00
|
|
|
ret = Rainmeter->MessagePump();
|
2012-02-14 17:00:07 +00:00
|
|
|
}
|
|
|
|
|
2012-05-24 11:15:03 +00:00
|
|
|
delete Rainmeter;
|
|
|
|
Rainmeter = NULL;
|
2011-09-29 06:04:20 +00:00
|
|
|
}
|
|
|
|
|
2012-02-14 17:00:07 +00:00
|
|
|
return ret;
|
2010-12-11 16:30:49 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2010-12-17 00:09:37 +00:00
|
|
|
/*
|
2011-10-29 10:36:07 +00:00
|
|
|
** Splits the given string into substrings
|
2010-12-17 00:09:37 +00:00
|
|
|
**
|
|
|
|
*/
|
2012-05-08 13:53:24 +00:00
|
|
|
std::vector<std::wstring> CRainmeter::ParseString(LPCTSTR str, CConfigParser* parser)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
std::vector<std::wstring> result;
|
|
|
|
|
|
|
|
if (str)
|
2011-09-28 18:28:35 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
std::wstring arg = str;
|
2011-09-28 18:28:35 +00:00
|
|
|
|
2011-10-29 10:36:07 +00:00
|
|
|
// Split the argument between first space.
|
|
|
|
// Or if string is in quotes, the after the second quote.
|
2011-09-28 18:28:35 +00:00
|
|
|
|
2012-05-08 13:53:24 +00:00
|
|
|
auto addResult = [&](std::wstring& string, bool stripQuotes)
|
2012-02-08 01:52:54 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
if (stripQuotes)
|
2012-02-08 01:52:54 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
size_t pos = 0;
|
|
|
|
do
|
2012-02-08 01:52:54 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
pos = string.find(L'"', pos);
|
|
|
|
if (pos != std::wstring::npos)
|
|
|
|
{
|
|
|
|
string.erase(pos, 1);
|
|
|
|
}
|
2012-02-08 01:52:54 +00:00
|
|
|
}
|
2012-05-08 13:53:24 +00:00
|
|
|
while (pos != std::wstring::npos);
|
2012-02-08 01:52:54 +00:00
|
|
|
}
|
2012-05-08 13:53:24 +00:00
|
|
|
|
|
|
|
if (parser)
|
|
|
|
{
|
|
|
|
parser->ReplaceMeasures(string);
|
|
|
|
}
|
|
|
|
|
|
|
|
result.push_back(string);
|
2012-02-08 01:52:54 +00:00
|
|
|
};
|
|
|
|
|
2011-10-29 10:36:07 +00:00
|
|
|
size_t pos;
|
|
|
|
std::wstring newStr;
|
|
|
|
while ((pos = arg.find_first_not_of(L' ')) != std::wstring::npos)
|
2011-09-28 18:28:35 +00:00
|
|
|
{
|
2012-02-08 01:52:54 +00:00
|
|
|
size_t extra = 1;
|
2011-10-29 10:36:07 +00:00
|
|
|
if (arg[pos] == L'"')
|
2011-09-28 18:28:35 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
if (arg.size() > (pos + 2) &&
|
|
|
|
arg[pos + 1] == L'"' && arg[pos + 2] == L'"')
|
|
|
|
{
|
|
|
|
// Eat found quotes and finding ending """
|
|
|
|
arg.erase(0, pos + 3);
|
2011-09-28 18:28:35 +00:00
|
|
|
|
2012-02-08 01:52:54 +00:00
|
|
|
extra = 4;
|
2011-10-29 10:36:07 +00:00
|
|
|
if ((pos = arg.find(L"\"\"\" ")) == std::wstring::npos)
|
|
|
|
{
|
|
|
|
extra = 3;
|
2012-02-08 01:52:54 +00:00
|
|
|
pos = arg.rfind(L"\"\"\""); // search backward
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
2011-09-28 18:28:35 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
// Eat found quote and find ending quote
|
|
|
|
arg.erase(0, pos + 1);
|
|
|
|
pos = arg.find_first_of(L'"');
|
2011-09-28 18:28:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
if (pos > 0)
|
2011-09-28 18:28:35 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
// Eat everything until non-space (and non-quote) char
|
|
|
|
arg.erase(0, pos);
|
2011-09-28 18:28:35 +00:00
|
|
|
}
|
2010-12-17 00:09:37 +00:00
|
|
|
|
2011-10-29 10:36:07 +00:00
|
|
|
// Find the second quote
|
|
|
|
pos = arg.find_first_of(L' ');
|
|
|
|
}
|
2010-12-17 00:09:37 +00:00
|
|
|
|
2011-10-29 10:36:07 +00:00
|
|
|
if (pos != std::wstring::npos)
|
2011-09-28 18:28:35 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
newStr.assign(arg, 0, pos);
|
2012-02-08 01:52:54 +00:00
|
|
|
arg.erase(0, pos + extra);
|
2011-10-29 10:36:07 +00:00
|
|
|
|
2012-05-08 13:53:24 +00:00
|
|
|
addResult(newStr, extra == 1);
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
|
|
|
else // quote or space not found
|
|
|
|
{
|
2012-05-12 12:08:47 +00:00
|
|
|
addResult(arg, extra == 1);
|
2012-02-08 01:52:54 +00:00
|
|
|
arg.clear();
|
2011-10-29 10:36:07 +00:00
|
|
|
break;
|
2011-09-28 18:28:35 +00:00
|
|
|
}
|
|
|
|
}
|
2011-10-29 10:36:07 +00:00
|
|
|
|
2012-02-08 01:52:54 +00:00
|
|
|
if (!arg.empty() && result.empty())
|
2011-09-28 18:28:35 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
addResult(arg, true);
|
2011-09-28 18:28:35 +00:00
|
|
|
}
|
|
|
|
}
|
2011-10-29 10:36:07 +00:00
|
|
|
|
|
|
|
return result;
|
2011-09-28 18:28:35 +00:00
|
|
|
}
|
2010-12-17 00:09:37 +00:00
|
|
|
|
|
|
|
/*
|
2011-10-29 10:36:07 +00:00
|
|
|
** Parses Bang args
|
2010-12-17 00:09:37 +00:00
|
|
|
**
|
|
|
|
*/
|
2012-05-08 13:53:24 +00:00
|
|
|
void CRainmeter::BangWithArgs(BANGCOMMAND bang, std::vector<std::wstring>& args, size_t numOfArgs, CMeterWindow* meterWindow)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
const size_t argsCount = args.size();
|
2010-12-17 00:09:37 +00:00
|
|
|
|
2012-05-08 13:53:24 +00:00
|
|
|
if (argsCount >= numOfArgs)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
if (argsCount == numOfArgs && meterWindow)
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
meterWindow->RunBang(bang, args);
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
2012-02-15 07:07:50 +00:00
|
|
|
else
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2012-02-15 05:05:13 +00:00
|
|
|
// Use the specified window instead of meterWindow parameter
|
2012-05-08 13:53:24 +00:00
|
|
|
if (argsCount > numOfArgs)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
const std::wstring& folderPath = args[numOfArgs];
|
|
|
|
if (!folderPath.empty() && (folderPath.length() != 1 || folderPath[0] != L'*'))
|
2012-02-01 15:55:29 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
CMeterWindow* meterWindow = GetMeterWindow(folderPath);
|
2012-02-15 07:07:50 +00:00
|
|
|
if (meterWindow)
|
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
meterWindow->RunBang(bang, args);
|
2012-02-15 07:07:50 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"Bang: Skin \"%s\" not found", folderPath.c_str());
|
2012-02-15 07:07:50 +00:00
|
|
|
}
|
|
|
|
return;
|
2012-02-01 15:55:29 +00:00
|
|
|
}
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
2012-02-15 07:07:50 +00:00
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
// No skin defined -> apply to all.
|
2012-02-15 07:07:50 +00:00
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_MeterWindows.begin();
|
|
|
|
for (; iter != m_MeterWindows.end(); ++iter)
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
((*iter).second)->RunBang(bang, args);
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
}
|
2011-10-29 10:36:07 +00:00
|
|
|
else
|
|
|
|
{
|
2012-02-18 13:12:01 +00:00
|
|
|
// For backwards compatibility
|
2012-05-08 13:53:24 +00:00
|
|
|
if (bang == BANG_COMMANDMEASURE && argsCount >= 1)
|
2012-02-18 13:12:01 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
std::wstring& firstArg = args[0];
|
|
|
|
std::wstring::size_type pos = firstArg.find_first_of(L' ');
|
2012-02-18 13:12:01 +00:00
|
|
|
if (pos != std::wstring::npos)
|
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
std::wstring newArg = firstArg.substr(0, pos);
|
|
|
|
firstArg.erase(0, pos + 1);
|
|
|
|
args.insert(args.begin(), newArg);
|
|
|
|
|
2012-02-18 13:12:01 +00:00
|
|
|
Log(LOG_WARNING, L"!CommandMeasure: Two parameters required, only one given");
|
2012-05-08 13:53:24 +00:00
|
|
|
BangWithArgs(bang, args, numOfArgs, meterWindow);
|
2012-02-18 13:12:01 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-24 21:53:08 +00:00
|
|
|
Log(LOG_ERROR, L"Bang: Incorrect number of arguments");
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2011-10-29 10:36:07 +00:00
|
|
|
** Parses Bang args for Group
|
2010-12-17 00:09:37 +00:00
|
|
|
**
|
|
|
|
*/
|
2012-05-08 13:53:24 +00:00
|
|
|
void CRainmeter::BangGroupWithArgs(BANGCOMMAND bang, std::vector<std::wstring>& args, size_t numOfArgs, CMeterWindow* meterWindow)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
if (args.size() > numOfArgs)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
std::multimap<int, CMeterWindow*> windows;
|
2012-05-08 13:53:24 +00:00
|
|
|
GetMeterWindowsByLoadOrder(windows, args[numOfArgs]);
|
2010-12-17 00:09:37 +00:00
|
|
|
|
2012-05-12 11:45:11 +00:00
|
|
|
args.resize(numOfArgs); // Remove extra parameters (including group)
|
|
|
|
|
2011-10-29 10:36:07 +00:00
|
|
|
std::multimap<int, CMeterWindow*>::const_iterator iter = windows.begin();
|
|
|
|
for (; iter != windows.end(); ++iter)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2012-05-12 11:45:11 +00:00
|
|
|
BangWithArgs(bang, args, numOfArgs, (*iter).second);
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
}
|
2011-10-29 10:36:07 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
Log(LOG_ERROR, L"BangGroup: Incorrect number of arguments");
|
|
|
|
}
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-01-30 08:34:56 +00:00
|
|
|
** !ActivateConfig bang
|
2010-12-17 00:09:37 +00:00
|
|
|
**
|
|
|
|
*/
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::Bang_ActivateSkin(std::vector<std::wstring>& args)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
if (args.size() > 1)
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
std::pair<int, int> indexes = GetMeterWindowIndex(args[0], args[1]);
|
2011-10-29 10:36:07 +00:00
|
|
|
if (indexes.first != -1 && indexes.second != -1)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
ActivateSkin(indexes.first, indexes.second);
|
2011-10-29 10:36:07 +00:00
|
|
|
return;
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
2012-05-08 13:53:24 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"!ActivateConfig: \"%s\\%s\" not found", args[0].c_str(), args[1].c_str());
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
2011-10-29 10:36:07 +00:00
|
|
|
else
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
// If we got this far, something went wrong
|
|
|
|
Log(LOG_ERROR, L"!ActivateConfig: Invalid parameters");
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-01-30 08:34:56 +00:00
|
|
|
** !DeactivateConfig bang
|
2010-12-17 00:09:37 +00:00
|
|
|
**
|
|
|
|
*/
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::Bang_DeactivateSkin(std::vector<std::wstring>& args, CMeterWindow* meterWindow)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
if (!args.empty())
|
2010-08-25 14:36:20 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
meterWindow = GetMeterWindow(args[0]);
|
2012-02-07 19:13:59 +00:00
|
|
|
if (!meterWindow)
|
2011-08-28 10:58:26 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
LogWithArgs(LOG_WARNING, L"!DeactivateConfig: \"%s\" not active", args[0].c_str());
|
2011-10-29 10:36:07 +00:00
|
|
|
return;
|
2011-08-28 10:58:26 +00:00
|
|
|
}
|
2012-02-07 19:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (meterWindow)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
DeactivateSkin(meterWindow, -1);
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Log(LOG_ERROR, L"!DeactivateConfig: Invalid parameters");
|
2011-08-28 10:58:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-01-30 08:34:56 +00:00
|
|
|
** !ToggleConfig bang
|
2011-08-28 10:58:26 +00:00
|
|
|
**
|
|
|
|
*/
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::Bang_ToggleSkin(std::vector<std::wstring>& args)
|
2011-08-28 10:58:26 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
if (args.size() >= 2)
|
2011-08-28 10:58:26 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
CMeterWindow* mw = GetMeterWindow(args[0]);
|
2011-10-29 10:36:07 +00:00
|
|
|
if (mw)
|
2011-08-28 10:58:26 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
DeactivateSkin(mw, -1);
|
2011-10-29 10:36:07 +00:00
|
|
|
return;
|
2011-08-28 10:58:26 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
// If the skin wasn't active, activate it
|
|
|
|
Bang_ActivateSkin(args);
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Log(LOG_ERROR, L"!ToggleConfig: Invalid parameters");
|
2010-08-25 14:36:20 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2010-03-20 19:40:30 +00:00
|
|
|
/*
|
2012-01-30 08:34:56 +00:00
|
|
|
** !DeactivateConfigGroup bang
|
2010-03-20 19:40:30 +00:00
|
|
|
**
|
|
|
|
*/
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::Bang_DeactivateSkinGroup(std::vector<std::wstring>& args)
|
2010-03-20 19:40:30 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
if (!args.empty())
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
std::multimap<int, CMeterWindow*> windows;
|
2012-05-08 13:53:24 +00:00
|
|
|
GetMeterWindowsByLoadOrder(windows, args[0]);
|
2010-03-20 19:40:30 +00:00
|
|
|
|
2011-10-29 10:36:07 +00:00
|
|
|
std::multimap<int, CMeterWindow*>::const_iterator iter = windows.begin();
|
|
|
|
for (; iter != windows.end(); ++iter)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
DeactivateSkin((*iter).second, -1);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
|
|
|
}
|
2011-10-29 10:36:07 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
Log(LOG_ERROR, L"!DeactivateConfigGroup: Invalid parameters");
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-01-30 08:34:56 +00:00
|
|
|
** !SetClip bang
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
|
|
|
*/
|
2012-05-08 13:53:24 +00:00
|
|
|
void CRainmeter::Bang_SetClip(std::vector<std::wstring>& args)
|
2012-01-30 08:34:56 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
if (!args.empty())
|
2012-01-30 08:34:56 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
CSystem::SetClipboardText(args[0]);
|
2012-01-30 08:34:56 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Log(LOG_ERROR, L"!SetClip: Invalid parameter");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-04 15:54:30 +00:00
|
|
|
/*
|
|
|
|
** !SetWallpaper bang
|
|
|
|
**
|
|
|
|
*/
|
2012-05-21 09:08:31 +00:00
|
|
|
void CRainmeter::Bang_SetWallpaper(std::vector<std::wstring>& args, CMeterWindow* meterWindow)
|
2012-02-04 15:54:30 +00:00
|
|
|
{
|
2012-05-21 09:08:31 +00:00
|
|
|
const size_t argsSize = args.size();
|
|
|
|
if (argsSize >= 1 && argsSize <= 2)
|
2012-02-04 15:54:30 +00:00
|
|
|
{
|
2012-05-21 09:08:31 +00:00
|
|
|
std::wstring& file = args[0];
|
|
|
|
const std::wstring& style = (argsSize == 2) ? args[1] : L"";
|
|
|
|
|
|
|
|
if (meterWindow)
|
|
|
|
{
|
|
|
|
meterWindow->MakePathAbsolute(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
CSystem::SetWallpaper(file, style);
|
2012-02-04 15:54:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Log(LOG_ERROR, L"!SetWallpaper: Invalid parameters");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-30 08:34:56 +00:00
|
|
|
/*
|
|
|
|
** !SkinMenu bang
|
|
|
|
**
|
|
|
|
*/
|
2012-05-08 13:53:24 +00:00
|
|
|
void CRainmeter::Bang_SkinMenu(std::vector<std::wstring>& args, CMeterWindow* meterWindow)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
if (!args.empty())
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
meterWindow = GetMeterWindow(args[0]);
|
2012-02-07 19:13:59 +00:00
|
|
|
if (!meterWindow)
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
LogWithArgs(LOG_WARNING, L"!SkinMenu: \"%s\" not active", args[0].c_str());
|
2011-10-29 10:36:07 +00:00
|
|
|
return;
|
|
|
|
}
|
2012-02-07 19:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (meterWindow)
|
|
|
|
{
|
|
|
|
POINT pos;
|
|
|
|
GetCursorPos(&pos);
|
|
|
|
ShowContextMenu(pos, meterWindow);
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
|
|
|
else
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +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
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-01-30 08:34:56 +00:00
|
|
|
** !TrayMenu bang
|
2009-02-10 18:37:48 +00:00
|
|
|
**
|
|
|
|
*/
|
2012-01-30 08:34:56 +00:00
|
|
|
void CRainmeter::Bang_TrayMenu()
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
POINT pos;
|
|
|
|
GetCursorPos(&pos);
|
|
|
|
ShowContextMenu(pos, NULL);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-01-30 08:34:56 +00:00
|
|
|
** !WriteKeyValue bang
|
2010-08-03 15:10:42 +00:00
|
|
|
**
|
|
|
|
*/
|
2012-05-08 13:53:24 +00:00
|
|
|
void CRainmeter::Bang_WriteKeyValue(std::vector<std::wstring>& args, CMeterWindow* meterWindow)
|
2010-08-03 15:10:42 +00:00
|
|
|
{
|
2012-05-21 09:07:50 +00:00
|
|
|
if (args.size() == 3 && meterWindow)
|
2012-02-01 15:55:29 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
// Add the skin file path to the args
|
|
|
|
args.push_back(meterWindow->GetFilePath());
|
2012-02-01 15:55:29 +00:00
|
|
|
}
|
2012-05-21 09:07:50 +00:00
|
|
|
else if (args.size() < 4)
|
|
|
|
{
|
|
|
|
Log(LOG_ERROR, L"!WriteKeyValue: Invalid parameters");
|
|
|
|
return;
|
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
std::wstring& strIniFile = args[3];
|
|
|
|
if (meterWindow)
|
2010-08-03 15:10:42 +00:00
|
|
|
{
|
2012-05-21 09:07:50 +00:00
|
|
|
meterWindow->MakePathAbsolute(strIniFile);
|
|
|
|
}
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
const WCHAR* iniFile = strIniFile.c_str();
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
if (strIniFile.find(L"..\\") != std::wstring::npos || strIniFile.find(L"../") != std::wstring::npos)
|
|
|
|
{
|
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: Illegal path: %s", iniFile);
|
|
|
|
return;
|
|
|
|
}
|
2010-12-16 20:35:44 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
const std::wstring& skinPath = GetSkinPath();
|
|
|
|
const std::wstring settingsPath = GetSettingsPath();
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
if (_wcsnicmp(iniFile, skinPath.c_str(), skinPath.size()) != 0 &&
|
|
|
|
_wcsnicmp(iniFile, settingsPath.c_str(), settingsPath.size()) != 0)
|
|
|
|
{
|
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: Illegal path: %s", iniFile);
|
|
|
|
return;
|
|
|
|
}
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
// Verify whether the file exists
|
|
|
|
if (_waccess(iniFile, 0) == -1)
|
|
|
|
{
|
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: File not found: %s", iniFile);
|
|
|
|
return;
|
|
|
|
}
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
// Verify whether the file is read-only
|
|
|
|
DWORD attr = GetFileAttributes(iniFile);
|
|
|
|
if (attr == -1 || (attr & FILE_ATTRIBUTE_READONLY))
|
|
|
|
{
|
|
|
|
LogWithArgs(LOG_WARNING, L"!WriteKeyValue: File is read-only: %s", iniFile);
|
|
|
|
return;
|
|
|
|
}
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
// Avoid "IniFileMapping"
|
|
|
|
CSystem::UpdateIniFileMappingList();
|
|
|
|
std::wstring strIniWrite = CSystem::GetTemporaryFile(strIniFile);
|
|
|
|
if (strIniWrite.size() == 1 && strIniWrite[0] == L'?') // error occurred
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
bool temporary = !strIniWrite.empty();
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
if (temporary)
|
|
|
|
{
|
|
|
|
if (GetDebug()) LogWithArgs(LOG_DEBUG, L"!WriteKeyValue: Writing to: %s (Temp: %s)", iniFile, strIniWrite.c_str());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (GetDebug()) LogWithArgs(LOG_DEBUG, L"!WriteKeyValue: Writing to: %s", iniFile);
|
|
|
|
strIniWrite = strIniFile;
|
|
|
|
}
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
const WCHAR* iniWrite = strIniWrite.c_str();
|
|
|
|
const WCHAR* section = args[0].c_str();
|
|
|
|
const WCHAR* key = args[1].c_str();
|
|
|
|
const std::wstring& strValue = args[2];
|
2011-03-29 19:21:57 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
bool formula = false;
|
|
|
|
BOOL write = 0;
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
if (meterWindow)
|
|
|
|
{
|
|
|
|
double value;
|
|
|
|
formula = meterWindow->GetParser().ParseFormula(strValue, &value);
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
// Formula read fine
|
|
|
|
if (formula)
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-05-21 09:07:50 +00:00
|
|
|
WCHAR buffer[256];
|
|
|
|
int len = _snwprintf_s(buffer, _TRUNCATE, L"%.5f", value);
|
|
|
|
CMeasure::RemoveTrailingZero(buffer, len);
|
|
|
|
|
|
|
|
write = WritePrivateProfileString(section, key, buffer, iniWrite);
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
2012-05-21 09:07:50 +00:00
|
|
|
}
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
if (!formula)
|
|
|
|
{
|
|
|
|
write = WritePrivateProfileString(section, key, strValue.c_str(), iniWrite);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (temporary)
|
|
|
|
{
|
|
|
|
if (write != 0)
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-05-21 09:07:50 +00:00
|
|
|
WritePrivateProfileString(NULL, NULL, NULL, iniWrite); // FLUSH
|
2010-08-03 15:10:42 +00:00
|
|
|
|
2012-05-21 09:07:50 +00:00
|
|
|
// Copy the file back
|
|
|
|
if (!CSystem::CopyFiles(strIniWrite, strIniFile))
|
2010-08-03 15:10:42 +00:00
|
|
|
{
|
2012-05-21 09:07:50 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: Failed to copy temporary file to original filepath: %s (Temp: %s)", iniFile, iniWrite);
|
2010-08-03 15:10:42 +00:00
|
|
|
}
|
|
|
|
}
|
2012-05-21 09:07:50 +00:00
|
|
|
else // failed
|
2010-08-03 15:10:42 +00:00
|
|
|
{
|
2012-05-21 09:07:50 +00:00
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: Failed to write to: %s (Temp: %s)", iniFile, iniWrite);
|
2010-08-03 15:10:42 +00:00
|
|
|
}
|
2012-05-21 09:07:50 +00:00
|
|
|
|
|
|
|
// Remove a temporary file
|
|
|
|
CSystem::RemoveFile(strIniWrite);
|
2010-08-03 15:10:42 +00:00
|
|
|
}
|
2011-10-29 10:36:07 +00:00
|
|
|
else
|
2010-04-02 01:35:53 +00:00
|
|
|
{
|
2012-05-21 09:07:50 +00:00
|
|
|
if (write == 0) // failed
|
|
|
|
{
|
|
|
|
LogWithArgs(LOG_ERROR, L"!WriteKeyValue: Failed to write to: %s", iniFile);
|
|
|
|
}
|
2010-04-02 01:35:53 +00:00
|
|
|
}
|
2009-08-04 09:48:03 +00:00
|
|
|
}
|
|
|
|
|
2012-04-02 14:47:13 +00:00
|
|
|
/*
|
|
|
|
** !Log bang
|
|
|
|
**
|
|
|
|
*/
|
2012-05-08 13:53:24 +00:00
|
|
|
void CRainmeter::Bang_Log(std::vector<std::wstring>& args)
|
2012-04-02 14:47:13 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
if (!args.empty())
|
2012-04-02 14:47:13 +00:00
|
|
|
{
|
|
|
|
int level = LOG_NOTICE;
|
|
|
|
|
2012-05-08 13:53:24 +00:00
|
|
|
if (args.size() > 1)
|
2012-04-02 14:47:13 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
const WCHAR* type = args[1].c_str();
|
2012-04-02 14:47:13 +00:00
|
|
|
if (_wcsicmp(type, L"ERROR") == 0)
|
|
|
|
{
|
|
|
|
level = LOG_ERROR;
|
|
|
|
}
|
|
|
|
else if (_wcsicmp(type, L"WARNING") == 0)
|
|
|
|
{
|
|
|
|
level = LOG_WARNING;
|
|
|
|
}
|
|
|
|
else if (_wcsicmp(type, L"DEBUG") == 0)
|
|
|
|
{
|
|
|
|
level = LOG_DEBUG;
|
|
|
|
}
|
|
|
|
else if (_wcsicmp(type, L"NOTICE") != 0)
|
|
|
|
{
|
|
|
|
Log(LOG_ERROR, L"!Log: Invalid type");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-08 13:53:24 +00:00
|
|
|
Log(level, args[0].c_str());
|
2012-04-02 14:47:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-26 17:37:15 +00:00
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// The class starts here
|
|
|
|
//
|
|
|
|
// -----------------------------------------------------------------------------------------------
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2009-02-10 18:37:48 +00:00
|
|
|
** Constructor
|
|
|
|
**
|
|
|
|
*/
|
2011-01-29 00:11:01 +00:00
|
|
|
CRainmeter::CRainmeter() :
|
|
|
|
m_TrayWindow(),
|
2011-09-28 18:28:35 +00:00
|
|
|
m_Debug(false),
|
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),
|
2011-11-10 11:50:47 +00:00
|
|
|
m_NormalStayDesktop(true),
|
2011-01-29 00:11:01 +00:00
|
|
|
m_MenuActive(false),
|
|
|
|
m_DisableRDP(false),
|
|
|
|
m_DisableDragging(false),
|
|
|
|
m_Logging(false),
|
|
|
|
m_CurrentParser(),
|
2012-02-22 10:03:51 +00:00
|
|
|
m_Window(),
|
2012-05-24 11:15:03 +00:00
|
|
|
m_Mutex(),
|
2011-01-29 00:11:01 +00:00
|
|
|
m_Instance(),
|
2011-09-23 16:28:38 +00:00
|
|
|
m_ResourceInstance(),
|
2012-02-22 10:03:51 +00:00
|
|
|
m_ResourceLCID(),
|
2011-09-28 18:28:35 +00:00
|
|
|
m_GDIplusToken(),
|
2012-06-01 13:06:36 +00:00
|
|
|
m_GlobalOptions()
|
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
|
|
|
** Destructor
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
CRainmeter::~CRainmeter()
|
|
|
|
{
|
2012-02-15 02:51:27 +00:00
|
|
|
KillTimer(m_Window, TIMER_NETSTATS);
|
|
|
|
|
2012-02-02 12:05:14 +00:00
|
|
|
DeleteMeterWindow(NULL);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-11-08 10:32:57 +00:00
|
|
|
delete m_TrayWindow;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
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-09-24 09:13:13 +00:00
|
|
|
if (m_ResourceInstance) FreeLibrary(m_ResourceInstance);
|
2012-05-24 11:15:03 +00:00
|
|
|
if (m_Mutex) ReleaseMutex(m_Mutex);
|
2011-09-24 09:13:13 +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
|
|
|
** The main initialization function for the module.
|
|
|
|
**
|
|
|
|
*/
|
2012-05-24 09:19:32 +00:00
|
|
|
int CRainmeter::Initialize(LPCWSTR iniPath)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-05-24 11:15:03 +00:00
|
|
|
InitalizeLitestep();
|
2012-02-14 17:00:07 +00:00
|
|
|
|
2012-03-22 21:16:41 +00:00
|
|
|
WCHAR* buffer = new WCHAR[MAX_LINE_LENGTH];
|
|
|
|
GetModuleFileName(m_Instance, buffer, MAX_LINE_LENGTH);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
// Remove the module's name from the path
|
2012-03-22 21:16:41 +00:00
|
|
|
WCHAR* pos = wcsrchr(buffer, L'\\');
|
|
|
|
m_Path.assign(buffer, pos ? pos - buffer + 1 : 0);
|
2010-09-11 19:39:45 +00:00
|
|
|
|
2011-05-02 11:58:02 +00:00
|
|
|
bool bDefaultIniLocation = false;
|
2012-05-24 09:19:32 +00:00
|
|
|
if (*iniPath)
|
2009-07-26 21:08:46 +00:00
|
|
|
{
|
|
|
|
// The command line defines the location of Rainmeter.ini (or whatever it calls it).
|
2012-05-24 09:19:32 +00:00
|
|
|
std::wstring iniFile = iniPath;
|
2009-08-26 17:37:15 +00:00
|
|
|
ExpandEnvironmentVariables(iniFile);
|
2009-07-26 21:08:46 +00:00
|
|
|
|
2011-11-05 09:01:06 +00:00
|
|
|
if (iniFile.empty() || CSystem::IsPathSeparator(iniFile[iniFile.length() - 1]))
|
2009-07-26 21:08:46 +00:00
|
|
|
{
|
|
|
|
iniFile += L"Rainmeter.ini";
|
|
|
|
}
|
2011-11-10 13:44:19 +00:00
|
|
|
else if (iniFile.length() <= 4 || _wcsicmp(iniFile.c_str() + (iniFile.length() - 4), L".ini") != 0)
|
2009-07-26 21:08:46 +00:00
|
|
|
{
|
|
|
|
iniFile += L"\\Rainmeter.ini";
|
|
|
|
}
|
|
|
|
|
2011-11-05 09:01:06 +00:00
|
|
|
if (!CSystem::IsPathSeparator(iniFile[0]) && iniFile.find_first_of(L':') == std::wstring::npos)
|
2010-08-05 10:46:04 +00:00
|
|
|
{
|
|
|
|
// Make absolute path
|
|
|
|
iniFile.insert(0, m_Path);
|
|
|
|
}
|
|
|
|
|
2009-07-26 21:08:46 +00:00
|
|
|
m_IniFile = iniFile;
|
2011-05-02 11:58:02 +00:00
|
|
|
bDefaultIniLocation = true;
|
2009-07-26 21:08:46 +00:00
|
|
|
}
|
2011-09-28 18:28:35 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
m_IniFile = m_Path;
|
|
|
|
m_IniFile += L"Rainmeter.ini";
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
{
|
|
|
|
m_IniFile = L"%APPDATA%\\Rainmeter\\Rainmeter.ini";
|
|
|
|
ExpandEnvironmentVariables(m_IniFile);
|
|
|
|
bDefaultIniLocation = true;
|
|
|
|
}
|
|
|
|
}
|
2009-07-26 21:08:46 +00:00
|
|
|
|
2012-05-24 11:15:03 +00:00
|
|
|
if (IsAlreadyRunning())
|
|
|
|
{
|
|
|
|
// Instance already running with same .ini file
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_Instance = GetModuleHandle(L"Rainmeter");
|
|
|
|
|
|
|
|
WNDCLASS wc = {0};
|
|
|
|
wc.lpfnWndProc = (WNDPROC)MainWndProc;
|
|
|
|
wc.hInstance = m_Instance;
|
|
|
|
wc.lpszClassName = RAINMETER_CLASS_NAME;
|
2012-06-01 13:21:25 +00:00
|
|
|
ATOM className = RegisterClass(&wc);
|
2012-05-24 11:15:03 +00:00
|
|
|
|
|
|
|
m_Window = CreateWindowEx(
|
|
|
|
WS_EX_TOOLWINDOW,
|
2012-06-01 13:21:25 +00:00
|
|
|
MAKEINTATOM(className),
|
2012-05-24 11:15:03 +00:00
|
|
|
RAINMETER_WINDOW_NAME,
|
|
|
|
WS_POPUP | WS_DISABLED,
|
|
|
|
CW_USEDEFAULT,
|
|
|
|
CW_USEDEFAULT,
|
|
|
|
CW_USEDEFAULT,
|
|
|
|
CW_USEDEFAULT,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
m_Instance,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if (!m_Window) return 1;
|
|
|
|
|
2012-05-05 11:45:34 +00:00
|
|
|
const WCHAR* iniFile = m_IniFile.c_str();
|
|
|
|
|
|
|
|
// Set file locations
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
2012-05-05 11:45:34 +00:00
|
|
|
size_t len = m_IniFile.length();
|
2012-05-29 16:02:20 +00:00
|
|
|
if (len > 4 && _wcsicmp(iniFile + (len - 4), L".ini") == 0)
|
2012-05-05 11:45:34 +00:00
|
|
|
{
|
|
|
|
len -= 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_LogFile.assign(m_IniFile, 0, len);
|
|
|
|
m_DataFile = m_StatsFile = m_LogFile;
|
|
|
|
m_LogFile += L".log";
|
|
|
|
m_StatsFile += L".stats";
|
|
|
|
m_DataFile += L".data";
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
2012-05-05 11:45:34 +00:00
|
|
|
|
|
|
|
bool dataFileCreated = false;
|
|
|
|
if (_waccess(m_DataFile.c_str(), 0) == -1)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
2012-05-05 11:45:34 +00:00
|
|
|
dataFileCreated = true;
|
|
|
|
CreateDataFile();
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
|
|
|
|
2011-10-01 17:39:09 +00:00
|
|
|
// Determine the language resource to load
|
|
|
|
std::wstring resource = m_Path + L"Languages\\";
|
2012-05-05 11:45:34 +00:00
|
|
|
if (GetPrivateProfileString(L"Rainmeter", L"Language", L"", buffer, MAX_LINE_LENGTH, iniFile) == 0)
|
2011-10-01 17:39:09 +00:00
|
|
|
{
|
|
|
|
// Use whatever the user selected for the installer
|
2011-10-14 14:53:02 +00:00
|
|
|
DWORD size = MAX_LINE_LENGTH;
|
|
|
|
HKEY hKey;
|
|
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Rainmeter", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &hKey) == ERROR_SUCCESS)
|
2011-10-01 17:39:09 +00:00
|
|
|
{
|
2011-10-14 14:53:02 +00:00
|
|
|
DWORD type = 0;
|
2012-03-22 21:16:41 +00:00
|
|
|
if (RegQueryValueEx(hKey, L"Language", NULL, &type, (LPBYTE)buffer, (LPDWORD)&size) != ERROR_SUCCESS ||
|
2011-10-14 14:53:02 +00:00
|
|
|
type != REG_SZ)
|
|
|
|
{
|
2012-03-22 21:16:41 +00:00
|
|
|
buffer[0] = L'\0';
|
2011-10-14 14:53:02 +00:00
|
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
2011-10-01 17:39:09 +00:00
|
|
|
}
|
|
|
|
}
|
2012-03-22 21:16:41 +00:00
|
|
|
if (buffer[0] != L'\0')
|
2011-10-29 11:15:58 +00:00
|
|
|
{
|
|
|
|
// Try selected language
|
2012-03-22 21:16:41 +00:00
|
|
|
m_ResourceLCID = wcstoul(buffer, NULL, 10);
|
|
|
|
resource += buffer;
|
2011-10-29 11:15:58 +00:00
|
|
|
resource += L".dll";
|
2011-10-01 17:39:09 +00:00
|
|
|
|
2011-10-29 11:15:58 +00:00
|
|
|
m_ResourceInstance = LoadLibraryEx(resource.c_str(), NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
|
|
|
|
}
|
2011-10-01 17:39:09 +00:00
|
|
|
if (!m_ResourceInstance)
|
|
|
|
{
|
|
|
|
// Try English
|
2011-10-29 11:15:58 +00:00
|
|
|
resource = m_Path;
|
|
|
|
resource += L"Languages\\1033.dll";
|
2011-10-01 17:39:09 +00:00
|
|
|
m_ResourceInstance = LoadLibraryEx(resource.c_str(), NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
|
|
|
|
m_ResourceLCID = 1033;
|
|
|
|
if (!m_ResourceInstance)
|
|
|
|
{
|
2012-05-24 09:19:32 +00:00
|
|
|
MessageBox(NULL, L"Unable to load language library", APPNAME, MB_OK | MB_TOPMOST | MB_ICONERROR);
|
|
|
|
return 1;
|
2011-10-01 17:39:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-14 17:58:03 +00:00
|
|
|
// Reset log file
|
|
|
|
CSystem::RemoveFile(m_LogFile);
|
|
|
|
|
2012-05-30 05:33:32 +00:00
|
|
|
m_Debug = 0!=GetPrivateProfileInt(L"Rainmeter", L"Debug", 0, iniFile);
|
|
|
|
m_Logging = 0!=GetPrivateProfileInt(L"Rainmeter", L"Logging", 0, iniFile);
|
|
|
|
|
2012-02-14 17:58:03 +00:00
|
|
|
if (m_Logging)
|
|
|
|
{
|
|
|
|
StartLogging();
|
|
|
|
}
|
|
|
|
|
2012-05-30 05:33:32 +00:00
|
|
|
// Get skin folder path
|
2012-05-05 11:45:34 +00:00
|
|
|
size_t len = GetPrivateProfileString(L"Rainmeter", L"SkinPath", L"", buffer, MAX_LINE_LENGTH, iniFile);
|
2012-03-22 21:16:41 +00:00
|
|
|
if (len > 0)
|
2009-07-24 07:56:37 +00:00
|
|
|
{
|
2012-05-30 05:33:32 +00:00
|
|
|
// Try Rainmeter.ini first
|
2012-03-22 21:16:41 +00:00
|
|
|
m_SkinPath.assign(buffer, len);
|
2011-05-02 11:58:02 +00:00
|
|
|
ExpandEnvironmentVariables(m_SkinPath);
|
|
|
|
|
|
|
|
if (!m_SkinPath.empty())
|
|
|
|
{
|
2012-03-22 21:16:41 +00:00
|
|
|
if (!CSystem::IsPathSeparator(m_SkinPath[m_SkinPath.length() - 1]))
|
2011-05-02 11:58:02 +00:00
|
|
|
{
|
2011-12-04 22:18:40 +00:00
|
|
|
m_SkinPath += L'\\';
|
2011-05-02 11:58:02 +00:00
|
|
|
}
|
|
|
|
}
|
2011-05-01 17:10:49 +00:00
|
|
|
}
|
2012-05-30 05:33:32 +00:00
|
|
|
else if (bDefaultIniLocation &&
|
|
|
|
SUCCEEDED(SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, buffer)))
|
2011-05-01 17:10:49 +00:00
|
|
|
{
|
2012-05-30 05:33:32 +00:00
|
|
|
// Use My Documents/Rainmeter/Skins
|
|
|
|
m_SkinPath = buffer;
|
|
|
|
m_SkinPath += L"\\Rainmeter\\";
|
|
|
|
CreateDirectory(m_SkinPath.c_str(), NULL);
|
|
|
|
m_SkinPath += L"Skins\\";
|
|
|
|
DWORD result = CreateDirectory(m_SkinPath.c_str(), NULL);
|
|
|
|
if (result)
|
2009-07-24 07:56:37 +00:00
|
|
|
{
|
2012-05-30 05:33:32 +00:00
|
|
|
// Folder just created, so copy default skins there
|
|
|
|
std::wstring from = GetDefaultSkinPath();
|
|
|
|
from += L"*.*";
|
|
|
|
CSystem::CopyFiles(from, m_SkinPath);
|
2009-07-24 07:56:37 +00:00
|
|
|
}
|
2012-05-30 05:33:32 +00:00
|
|
|
|
|
|
|
std::wstring themesPath = GetSettingsPath();
|
|
|
|
themesPath += L"Themes\\";
|
|
|
|
result = CreateDirectory(themesPath.c_str(), NULL);
|
|
|
|
if (result)
|
2009-07-24 07:56:37 +00:00
|
|
|
{
|
2012-05-30 05:33:32 +00:00
|
|
|
// Copy themes to %APPDATA%
|
|
|
|
std::wstring from = GetDefaultThemePath();
|
|
|
|
from += L"*.*";
|
|
|
|
CSystem::CopyFiles(from, themesPath);
|
2009-07-24 07:56:37 +00:00
|
|
|
}
|
2011-05-02 11:58:02 +00:00
|
|
|
|
2012-05-05 11:45:34 +00:00
|
|
|
WritePrivateProfileString(L"Rainmeter", L"SkinPath", m_SkinPath.c_str(), iniFile);
|
2009-07-24 07:56:37 +00:00
|
|
|
}
|
2012-05-30 05:33:32 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
m_SkinPath = m_Path + L"Skins\\";
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a default Rainmeter.ini file if needed
|
|
|
|
if (_waccess(iniFile, 0) == -1)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
CreateOptionsFile();
|
2012-05-30 05:33:32 +00:00
|
|
|
}
|
2009-07-24 07:56:37 +00:00
|
|
|
|
2012-03-22 21:16:41 +00:00
|
|
|
delete [] buffer;
|
|
|
|
buffer = NULL;
|
2011-02-15 13:22:19 +00:00
|
|
|
|
2010-12-19 23:06:13 +00:00
|
|
|
LogWithArgs(LOG_NOTICE, L"Path: %s", m_Path.c_str());
|
2012-05-05 11:45:34 +00:00
|
|
|
LogWithArgs(LOG_NOTICE, L"IniFile: %s", iniFile);
|
2010-12-19 23:06:13 +00:00
|
|
|
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
|
|
|
}
|
2011-11-05 09:01:06 +00:00
|
|
|
else if (CSystem::IsUNCPath(m_Path))
|
2010-11-25 22:00:34 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
|
2012-02-16 17:38:45 +00:00
|
|
|
CSystem::Initialize(m_Instance);
|
2010-03-20 19:40:30 +00:00
|
|
|
CMeasureNet::InitializeNewApi();
|
|
|
|
|
2011-09-28 18:28:35 +00:00
|
|
|
if (m_Debug)
|
2010-03-20 19:40:30 +00:00
|
|
|
{
|
2012-04-06 17:54:45 +00:00
|
|
|
Log(LOG_DEBUG, L"Enumerating font families...");
|
2010-03-20 19:40:30 +00:00
|
|
|
CMeterString::EnumerateInstalledFontFamilies();
|
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
// Tray must exist before skins are read
|
2012-05-05 12:59:35 +00:00
|
|
|
m_TrayWindow = new CTrayWindow();
|
|
|
|
m_TrayWindow->Initialize();
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2011-11-09 08:52:32 +00:00
|
|
|
ReloadSettings();
|
2009-07-24 07:56:37 +00:00
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
if (m_SkinFolders.empty())
|
2009-07-24 07:56:37 +00:00
|
|
|
{
|
2011-09-23 16:28:38 +00:00
|
|
|
std::wstring error = GetFormattedString(ID_STR_NOAVAILABLESKINS, m_SkinPath.c_str());
|
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
|
|
|
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
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
// Create meter windows for active skins
|
|
|
|
ActivateActiveSkins();
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-05-05 11:45:34 +00:00
|
|
|
if (dataFileCreated)
|
|
|
|
{
|
|
|
|
m_TrayWindow->ShowWelcomeNotification();
|
|
|
|
}
|
|
|
|
else if (!m_DisableVersionCheck)
|
2011-11-09 08:52:32 +00:00
|
|
|
{
|
|
|
|
CheckUpdate();
|
|
|
|
}
|
|
|
|
|
2012-05-24 09:19:32 +00:00
|
|
|
return 0; // All is OK
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2012-05-24 11:15:03 +00:00
|
|
|
bool CRainmeter::IsAlreadyRunning()
|
2012-05-24 06:19:52 +00:00
|
|
|
{
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
ULONG i[2];
|
|
|
|
ULONG buf[4];
|
|
|
|
unsigned char in[64];
|
|
|
|
unsigned char digest[16];
|
|
|
|
} MD5_CTX;
|
|
|
|
|
|
|
|
typedef void (WINAPI * FPMD5INIT)(MD5_CTX* context);
|
|
|
|
typedef void (WINAPI * FPMD5UPDATE)(MD5_CTX* context, const unsigned char* input, unsigned int inlen);
|
|
|
|
typedef void (WINAPI * FPMD5FINAL)(MD5_CTX* context);
|
|
|
|
|
2012-05-24 11:15:03 +00:00
|
|
|
bool alreadyRunning = false;
|
|
|
|
|
2012-05-24 06:19:52 +00:00
|
|
|
// Create MD5 digest from command line
|
|
|
|
HMODULE cryptDll = CSystem::RmLoadLibrary(L"cryptdll.dll");
|
|
|
|
if (cryptDll)
|
|
|
|
{
|
|
|
|
FPMD5INIT MD5Init = (FPMD5INIT)GetProcAddress(cryptDll, "MD5Init");
|
|
|
|
FPMD5UPDATE MD5Update = (FPMD5UPDATE)GetProcAddress(cryptDll, "MD5Update");
|
|
|
|
FPMD5FINAL MD5Final = (FPMD5FINAL)GetProcAddress(cryptDll, "MD5Final");
|
|
|
|
if (MD5Init && MD5Update && MD5Final)
|
|
|
|
{
|
2012-05-24 11:15:03 +00:00
|
|
|
std::wstring data = m_IniFile;
|
|
|
|
_wcsupr(&data[0]);
|
2012-05-24 06:19:52 +00:00
|
|
|
|
|
|
|
MD5_CTX ctx = {0};
|
|
|
|
MD5Init(&ctx);
|
2012-05-24 11:15:03 +00:00
|
|
|
MD5Update(&ctx, (LPBYTE)&data[0], data.length() * sizeof(WCHAR));
|
2012-05-24 06:19:52 +00:00
|
|
|
MD5Final(&ctx);
|
|
|
|
FreeLibrary(cryptDll);
|
|
|
|
|
|
|
|
// Convert MD5 digest to mutex string (e.g. "Rainmeter0123456789abcdef0123456789abcdef")
|
|
|
|
const WCHAR hexChars[] = L"0123456789abcdef";
|
|
|
|
WCHAR mutexName[64] = L"Rainmeter";
|
|
|
|
WCHAR* pos = mutexName + (_countof(L"Rainmeter") - 1);
|
|
|
|
for (size_t i = 0; i < 16; ++i)
|
|
|
|
{
|
|
|
|
*(pos++) = hexChars[ctx.digest[i] >> 4];
|
|
|
|
*(pos++) = hexChars[ctx.digest[i] & 0xF];
|
|
|
|
}
|
|
|
|
*pos = L'\0';
|
|
|
|
|
2012-05-24 11:15:03 +00:00
|
|
|
m_Mutex = CreateMutex(NULL, FALSE, mutexName);
|
|
|
|
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
2012-05-24 06:19:52 +00:00
|
|
|
{
|
2012-05-24 11:15:03 +00:00
|
|
|
alreadyRunning = true;
|
|
|
|
m_Mutex = NULL;
|
2012-05-24 06:19:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FreeLibrary(cryptDll);
|
|
|
|
}
|
|
|
|
|
2012-05-24 11:15:03 +00:00
|
|
|
return alreadyRunning;
|
2012-05-24 06:19:52 +00:00
|
|
|
}
|
|
|
|
|
2012-02-14 17:00:07 +00:00
|
|
|
int CRainmeter::MessagePump()
|
|
|
|
{
|
|
|
|
MSG msg;
|
|
|
|
BOOL ret;
|
|
|
|
|
2012-02-21 09:03:16 +00:00
|
|
|
HACCEL hAccel = LoadAccelerators(m_Instance, MAKEINTRESOURCE(IDR_DIALOG_ACCELERATORS));
|
|
|
|
|
2012-02-14 17:00:07 +00:00
|
|
|
// Run the standard window message loop
|
|
|
|
while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0)
|
|
|
|
{
|
|
|
|
if (ret == -1)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2012-02-21 09:03:16 +00:00
|
|
|
else if (!CDialog::GetActiveDialogWindow() ||
|
|
|
|
!TranslateAccelerator(CDialog::GetActiveTabWindow(), hAccel, &msg) ||
|
|
|
|
!IsDialogMessage(CDialog::GetActiveDialogWindow(), &msg))
|
2012-02-14 17:00:07 +00:00
|
|
|
{
|
|
|
|
TranslateMessage(&msg);
|
|
|
|
DispatchMessage(&msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return (int)msg.wParam;
|
|
|
|
}
|
|
|
|
|
|
|
|
LRESULT CALLBACK CRainmeter::MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
|
|
{
|
|
|
|
switch (uMsg)
|
|
|
|
{
|
|
|
|
case WM_DESTROY:
|
|
|
|
PostQuitMessage(0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_COPYDATA:
|
|
|
|
{
|
|
|
|
COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam;
|
|
|
|
if (cds)
|
|
|
|
{
|
|
|
|
const WCHAR* data = (const WCHAR*)cds->lpData;
|
|
|
|
if (cds->dwData == 1 && (cds->cbData > 0))
|
|
|
|
{
|
|
|
|
Rainmeter->DelayedExecuteCommand(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2012-02-15 02:51:27 +00:00
|
|
|
case WM_TIMER:
|
|
|
|
if (wParam == TIMER_NETSTATS)
|
|
|
|
{
|
|
|
|
CMeasureNet::UpdateIFTable();
|
|
|
|
CMeasureNet::UpdateStats();
|
|
|
|
Rainmeter->WriteStats(false);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2012-02-14 17:58:03 +00:00
|
|
|
case WM_RAINMETER_DELAYED_REFRESH_ALL:
|
|
|
|
Rainmeter->RefreshAll();
|
2012-02-15 02:51:27 +00:00
|
|
|
break;
|
2012-02-14 17:58:03 +00:00
|
|
|
|
|
|
|
case WM_RAINMETER_DELAYED_EXECUTE:
|
|
|
|
if (lParam)
|
|
|
|
{
|
|
|
|
// Execute bang
|
|
|
|
WCHAR* bang = (WCHAR*)lParam;
|
|
|
|
Rainmeter->ExecuteCommand(bang, NULL);
|
|
|
|
free(bang); // _wcsdup()
|
|
|
|
}
|
2012-02-15 02:51:27 +00:00
|
|
|
break;
|
2012-02-14 17:58:03 +00:00
|
|
|
|
2012-02-22 06:42:52 +00:00
|
|
|
case WM_RAINMETER_EXECUTE:
|
|
|
|
Rainmeter->ExecuteCommand((const WCHAR*)lParam, (CMeterWindow*)wParam);
|
|
|
|
break;
|
|
|
|
|
2012-02-14 17:00:07 +00:00
|
|
|
default:
|
|
|
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-02-15 02:51:27 +00:00
|
|
|
void CRainmeter::SetNetworkStatisticsTimer()
|
|
|
|
{
|
|
|
|
static bool set = SetTimer(m_Window, TIMER_NETSTATS, INTERVAL_NETSTATS, NULL);
|
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::CreateOptionsFile()
|
2009-07-21 12:26:50 +00:00
|
|
|
{
|
2012-02-22 10:03:51 +00:00
|
|
|
size_t pos = m_IniFile.find_last_of(L'\\');
|
2009-07-21 12:26:50 +00:00
|
|
|
if (pos != std::wstring::npos)
|
|
|
|
{
|
2012-02-22 10:03:51 +00:00
|
|
|
std::wstring strPath(m_IniFile, 0, pos);
|
2009-07-21 12:26:50 +00:00
|
|
|
CreateDirectory(strPath.c_str(), NULL);
|
|
|
|
}
|
|
|
|
|
2012-05-30 05:33:32 +00:00
|
|
|
std::wstring defaultIni = GetDefaultThemePath();
|
|
|
|
defaultIni += L"illustro default\\Rainmeter.thm";
|
|
|
|
CSystem::CopyFiles(defaultIni, m_IniFile);
|
2009-07-21 12:26:50 +00:00
|
|
|
}
|
|
|
|
|
2012-05-05 11:45:34 +00:00
|
|
|
void CRainmeter::CreateDataFile()
|
|
|
|
{
|
|
|
|
std::wstring tmpSz = GetSettingsPath();
|
|
|
|
tmpSz += L"Plugins.ini";
|
|
|
|
|
|
|
|
const WCHAR* pluginsFile = tmpSz.c_str();
|
|
|
|
const WCHAR* dataFile = m_DataFile.c_str();
|
|
|
|
|
|
|
|
if (_waccess(pluginsFile, 0) == 0)
|
|
|
|
{
|
2012-05-13 09:30:20 +00:00
|
|
|
MoveFile(pluginsFile, dataFile);
|
2012-05-05 11:45:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Create empty file
|
|
|
|
HANDLE file = CreateFile(dataFile, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if (file != INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
CloseHandle(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
void CRainmeter::ReloadSettings()
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
ScanForSkins(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);
|
|
|
|
}
|
|
|
|
|
2012-02-21 19:15:10 +00:00
|
|
|
void CRainmeter::EditSettings()
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
RunFile(m_SkinEditor.c_str(), m_IniFile.c_str());
|
2012-02-21 19:15:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CRainmeter::EditSkinFile(const std::wstring& name, const std::wstring& iniFile)
|
|
|
|
{
|
2012-05-29 16:02:20 +00:00
|
|
|
std::wstring args = m_SkinPath + name;
|
|
|
|
args += L'\\';
|
|
|
|
args += iniFile;
|
|
|
|
bool writable = CSystem::IsFileWritable(args.c_str());
|
2012-02-21 19:15:10 +00:00
|
|
|
|
|
|
|
// Execute as admin if in protected location
|
2012-06-01 13:06:36 +00:00
|
|
|
RunFile(m_SkinEditor.c_str(), args.c_str(), !writable);
|
2012-02-21 19:15:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CRainmeter::OpenSkinFolder(const std::wstring& name)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
std::wstring folderPath = m_SkinPath + name;
|
|
|
|
RunFile(folderPath.c_str());
|
2012-02-21 19:15:10 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::ActivateActiveSkins()
|
2011-09-04 18:06:19 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
std::multimap<int, int>::const_iterator iter = m_SkinOrders.begin();
|
|
|
|
for ( ; iter != m_SkinOrders.end(); ++iter)
|
2011-09-04 18:06:19 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
const SkinFolder& skinFolder = m_SkinFolders[(*iter).second];
|
|
|
|
if (skinFolder.active > 0 && skinFolder.active <= (int)skinFolder.files.size())
|
2011-09-04 18:06:19 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
ActivateSkin((*iter).second, skinFolder.active - 1);
|
2011-09-04 18:06:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::ActivateSkin(int folderIndex, int fileIndex)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
if (folderIndex >= 0 && folderIndex < (int)m_SkinFolders.size() &&
|
|
|
|
fileIndex >= 0 && fileIndex < (int)m_SkinFolders[folderIndex].files.size())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
const SkinFolder& skinFolder = m_SkinFolders[folderIndex];
|
|
|
|
const std::wstring& file = skinFolder.files[fileIndex];
|
|
|
|
const WCHAR* fileSz = file.c_str();
|
2012-06-01 10:05:25 +00:00
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
std::wstring folderPath = GetFolderPath(folderIndex);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
// Verify that the skin is not already active
|
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_MeterWindows.find(folderPath);
|
2012-02-03 10:15:18 +00:00
|
|
|
if (iter != m_MeterWindows.end())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
if (wcscmp(((*iter).second)->GetFileName().c_str(), fileSz) == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
LogWithArgs(LOG_WARNING, L"!ActivateConfig: \"%s\" already active", folderPath.c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
// Deactivate the existing skin
|
|
|
|
DeactivateSkin((*iter).second, folderIndex);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-22 00:31:59 +00:00
|
|
|
// Verify whether the ini-file exists
|
2012-06-01 13:06:36 +00:00
|
|
|
std::wstring skinIniPath = m_SkinPath + folderPath;
|
2011-12-04 22:18:40 +00:00
|
|
|
skinIniPath += L'\\';
|
2012-06-01 13:06:36 +00:00
|
|
|
skinIniPath += file;
|
2010-07-22 00:31:59 +00:00
|
|
|
|
|
|
|
if (_waccess(skinIniPath.c_str(), 0) == -1)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
std::wstring message = GetFormattedString(ID_STR_UNABLETOACTIVATESKIN, folderPath.c_str(), fileSz);
|
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
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
m_SkinFolders[folderIndex].active = fileIndex + 1;
|
2012-06-01 13:06:36 +00:00
|
|
|
WriteActive(folderPath, fileIndex);
|
2009-10-18 13:31:55 +00:00
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
CreateMeterWindow(folderPath, file);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::DeactivateSkin(CMeterWindow* meterWindow, int folderIndex, bool save)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
if (folderIndex >= 0 && folderIndex < (int)m_SkinFolders.size())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
m_SkinFolders[folderIndex].active = 0; // Deactivate the skin
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-06-01 10:05:25 +00:00
|
|
|
else if (folderIndex == -1 && meterWindow)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
folderIndex = FindSkinFolderIndex(meterWindow->GetFolderPath());
|
2012-06-01 10:05:25 +00:00
|
|
|
if (folderIndex != -1)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
m_SkinFolders[folderIndex].active = 0;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (meterWindow)
|
|
|
|
{
|
2011-08-28 10:58:26 +00:00
|
|
|
if (save)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
// Disable the skin in the ini-file
|
|
|
|
WriteActive(meterWindow->GetFolderPath(), -1);
|
2011-08-28 10:58:26 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-02-02 12:05:14 +00:00
|
|
|
meterWindow->Deactivate();
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::ToggleSkin(int folderIndex, int fileIndex)
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
if (folderIndex >= 0 && folderIndex < (int)m_SkinFolders.size() &&
|
|
|
|
fileIndex >= 0 && fileIndex < (int)m_SkinFolders[folderIndex].files.size())
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
if (m_SkinFolders[folderIndex].active == fileIndex + 1)
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
CMeterWindow* meterWindow = Rainmeter->GetMeterWindow(GetFolderPath(folderIndex));
|
|
|
|
DeactivateSkin(meterWindow, folderIndex);
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
ActivateSkin(folderIndex, fileIndex);
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::WriteActive(const std::wstring& folderPath, int fileIndex)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
2010-12-13 09:00:02 +00:00
|
|
|
WCHAR buffer[32];
|
2012-06-01 10:05:25 +00:00
|
|
|
_itow_s(fileIndex + 1, buffer, 10);
|
2012-06-01 13:06:36 +00:00
|
|
|
WritePrivateProfileString(folderPath.c_str(), L"Active", buffer, m_IniFile.c_str());
|
2010-07-22 00:31:59 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::CreateMeterWindow(const std::wstring& folderPath, const std::wstring& file)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
CMeterWindow* mw = new CMeterWindow(folderPath, file);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
if (mw)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
m_MeterWindows.insert(std::make_pair(folderPath, mw));
|
2010-08-30 22:51:58 +00:00
|
|
|
|
2011-09-10 22:04:51 +00:00
|
|
|
try
|
|
|
|
{
|
2012-04-06 17:01:45 +00:00
|
|
|
mw->Initialize();
|
2011-09-10 22:04:51 +00:00
|
|
|
|
2011-09-10 23:01:24 +00:00
|
|
|
CDialogAbout::UpdateSkins();
|
2011-09-10 22:04:51 +00:00
|
|
|
CDialogManage::UpdateSkins(mw);
|
|
|
|
}
|
|
|
|
catch (CError& error)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
DeactivateSkin(mw, -1);
|
2011-09-10 22:04:51 +00:00
|
|
|
LogError(error);
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-03 10:15:18 +00:00
|
|
|
void CRainmeter::DeleteMeterWindow(CMeterWindow* meterWindow, bool force)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-03 10:15:18 +00:00
|
|
|
std::map<std::wstring, CMeterWindow*>::iterator iter = m_MeterWindows.begin();
|
|
|
|
for (; iter != m_MeterWindows.end(); ++iter)
|
2009-10-17 06:43:18 +00:00
|
|
|
{
|
2012-02-02 12:05:14 +00:00
|
|
|
if (meterWindow == NULL)
|
2011-02-15 13:22:19 +00:00
|
|
|
{
|
2012-02-02 12:05:14 +00:00
|
|
|
// Delete all meter windows
|
|
|
|
CDialogManage::UpdateSkins((*iter).second, true);
|
|
|
|
delete (*iter).second;
|
2011-02-15 13:22:19 +00:00
|
|
|
}
|
2012-02-02 12:05:14 +00:00
|
|
|
else if ((*iter).second == meterWindow)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-03 10:15:18 +00:00
|
|
|
m_MeterWindows.erase(iter);
|
2012-02-03 10:37:26 +00:00
|
|
|
force = true;
|
|
|
|
break;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-02 12:05:14 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-02-02 12:05:14 +00:00
|
|
|
if (meterWindow == NULL)
|
|
|
|
{
|
2012-02-03 10:15:18 +00:00
|
|
|
m_MeterWindows.clear();
|
|
|
|
}
|
|
|
|
else if (force)
|
|
|
|
{
|
2012-02-03 10:37:26 +00:00
|
|
|
CDialogManage::UpdateSkins(meterWindow, true);
|
2012-02-03 10:15:18 +00:00
|
|
|
delete meterWindow;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-08 00:53:43 +00:00
|
|
|
|
|
|
|
CDialogAbout::UpdateSkins();
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
CMeterWindow* CRainmeter::GetMeterWindow(const std::wstring& folderPath)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
const WCHAR* folderSz = folderPath.c_str();
|
2012-02-03 10:15:18 +00:00
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_MeterWindows.begin();
|
|
|
|
for (; iter != m_MeterWindows.end(); ++iter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
if (_wcsicmp((*iter).first.c_str(), folderSz) == 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
|
|
|
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
|
|
|
|
2012-02-03 10:15:18 +00:00
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_MeterWindows.begin();
|
|
|
|
for (; iter != m_MeterWindows.end(); ++iter)
|
2010-12-16 17:04:14 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
std::wstring config_current = (*iter).second->GetFolderPath() + L'\\';
|
|
|
|
config_current += (*iter).second->GetFileName();
|
2011-02-15 13:22:19 +00:00
|
|
|
|
|
|
|
if (_wcsicmp(config_current.c_str(), config_searching.c_str()) == 0)
|
|
|
|
{
|
|
|
|
return (*iter).second;
|
|
|
|
}
|
2010-12-16 17:04:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
std::pair<int, int> CRainmeter::GetMeterWindowIndex(const std::wstring& folderPath, const std::wstring& file)
|
2011-09-08 14:39:25 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
int index = FindSkinFolderIndex(folderPath);
|
2012-06-01 10:05:25 +00:00
|
|
|
if (index != -1)
|
2011-09-08 14:39:25 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
const SkinFolder& skinFolder = m_SkinFolders[index];
|
2012-06-01 10:05:25 +00:00
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
const WCHAR* fileSz = file.c_str();
|
|
|
|
for (int i = 0, isize = (int)skinFolder.files.size(); i < isize; ++i)
|
2011-09-08 14:39:25 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
if (_wcsicmp(skinFolder.files[i].c_str(), fileSz) == 0)
|
2011-09-08 14:39:25 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
return std::make_pair(index, i);
|
2011-09-08 14:39:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
return std::make_pair(-1, -1); // Error
|
2011-09-08 14:39:25 +00:00
|
|
|
}
|
|
|
|
|
2011-10-29 10:36:07 +00:00
|
|
|
std::pair<int, int> CRainmeter::GetMeterWindowIndex(UINT menuCommand)
|
|
|
|
{
|
|
|
|
std::pair<int, int> indexes;
|
|
|
|
|
|
|
|
if (menuCommand >= ID_CONFIG_FIRST && menuCommand <= ID_CONFIG_LAST)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
// Check which skin was selected
|
2012-06-01 10:05:25 +00:00
|
|
|
for (size_t i = 0, isize = m_SkinFolders.size(); i < isize; ++i)
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
const SkinFolder& skinFolder = m_SkinFolders[i];
|
|
|
|
if (menuCommand >= skinFolder.commandBase &&
|
|
|
|
menuCommand < (skinFolder.commandBase + skinFolder.files.size()))
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
indexes = std::make_pair(i, menuCommand - skinFolder.commandBase);
|
2011-10-29 10:36:07 +00:00
|
|
|
return indexes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
indexes = std::make_pair(-1, -1); // error
|
|
|
|
return indexes;
|
|
|
|
}
|
|
|
|
|
2010-03-23 16:15:07 +00:00
|
|
|
CMeterWindow* CRainmeter::GetMeterWindow(HWND hwnd)
|
|
|
|
{
|
2012-02-03 10:15:18 +00:00
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_MeterWindows.begin();
|
|
|
|
for (; iter != m_MeterWindows.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)
|
|
|
|
{
|
2012-02-03 10:15:18 +00:00
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_MeterWindows.begin();
|
|
|
|
for (; iter != m_MeterWindows.end(); ++iter)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
|
|
|
CMeterWindow* mw = (*iter).second;
|
|
|
|
if (mw && (group.empty() || mw->BelongsToGroup(group)))
|
|
|
|
{
|
|
|
|
windows.insert(std::pair<int, CMeterWindow*>(GetLoadOrder((*iter).first), mw));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
/*
|
|
|
|
** Returns the skin folder path relative to the skin folder (e.g. illustro\Clock).
|
|
|
|
**
|
|
|
|
*/
|
2012-06-01 13:06:36 +00:00
|
|
|
std::wstring CRainmeter::GetFolderPath(int folderIndex)
|
2012-06-01 10:05:25 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
const SkinFolder& skinFolder = m_SkinFolders[folderIndex];
|
|
|
|
std::wstring path = skinFolder.name;
|
|
|
|
for (int i = skinFolder.level - 1, index = folderIndex; i >= 1; --i)
|
2012-06-01 10:05:25 +00:00
|
|
|
{
|
|
|
|
while (m_SkinFolders[index].level != i)
|
|
|
|
{
|
|
|
|
--index;
|
|
|
|
}
|
|
|
|
|
|
|
|
path.insert(0, L"\\");
|
|
|
|
path.insert(0, m_SkinFolders[index].name);
|
|
|
|
}
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
int CRainmeter::FindSkinFolderIndex(const std::wstring& folderPath)
|
|
|
|
{
|
|
|
|
if (!folderPath.empty())
|
|
|
|
{
|
|
|
|
const WCHAR* path = folderPath.c_str();
|
|
|
|
int len = 0;
|
|
|
|
while (path[len] && path[len] != L'\\') ++len;
|
|
|
|
|
|
|
|
int level = 1;
|
|
|
|
for (int i = 0, isize = (int)m_SkinFolders.size(); i < isize; ++i)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
const SkinFolder& skinFolder = m_SkinFolders[i];
|
|
|
|
if (skinFolder.level == level)
|
2012-06-01 10:05:25 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
if (skinFolder.name.length() == len && _wcsnicmp(skinFolder.name.c_str(), path, len) == 0)
|
2012-06-01 10:05:25 +00:00
|
|
|
{
|
|
|
|
path += len;
|
|
|
|
if (*path)
|
|
|
|
{
|
|
|
|
++path; // Skip backslash
|
|
|
|
len = 0;
|
|
|
|
while (path[len] && path[len] != L'\\') ++len;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Match found
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
++level;
|
|
|
|
}
|
|
|
|
}
|
2012-06-01 13:06:36 +00:00
|
|
|
else if (skinFolder.level < level)
|
2012-06-01 10:05:25 +00:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRainmeter::SetLoadOrder(int folderIndex, int order)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
std::multimap<int, int>::iterator iter = m_SkinOrders.begin();
|
|
|
|
for ( ; iter != m_SkinOrders.end(); ++iter)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
if ((*iter).second == folderIndex) // 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
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
m_SkinOrders.erase(iter);
|
2010-03-29 21:50:05 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
m_SkinOrders.insert(std::pair<int, int>(order, folderIndex));
|
2010-03-29 21:50:05 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
int CRainmeter::GetLoadOrder(const std::wstring& folderPath)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
int index = FindSkinFolderIndex(folderPath);
|
2012-06-01 10:05:25 +00:00
|
|
|
if (index != -1)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
std::multimap<int, int>::const_iterator iter = m_SkinOrders.begin();
|
|
|
|
for ( ; iter != m_SkinOrders.end(); ++iter)
|
2010-03-29 21:50:05 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
if ((*iter).second == index)
|
|
|
|
{
|
|
|
|
return (*iter).first;
|
|
|
|
}
|
2010-03-29 21:50:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
** Scans all the subfolders and locates the ini-files.
|
|
|
|
*/
|
2012-06-01 13:06:36 +00:00
|
|
|
void CRainmeter::ScanForSkins(const std::wstring& path)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
m_SkinFolders.clear();
|
2012-06-01 13:06:36 +00:00
|
|
|
m_SkinOrders.clear();
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
ScanForSkinsRecursive(path, L"", 0, 0);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
int CRainmeter::ScanForSkinsRecursive(const std::wstring& path, std::wstring base, int index, UINT level)
|
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
|
2012-06-01 10:05:25 +00:00
|
|
|
std::list<std::wstring> subfolders;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
// Find all .ini files and subfolders
|
2011-07-15 11:48:50 +00:00
|
|
|
std::wstring filter = path + base;
|
|
|
|
filter += L"\\*";
|
|
|
|
|
|
|
|
hSearch = FindFirstFileEx(
|
|
|
|
filter.c_str(),
|
|
|
|
(CSystem::GetOSPlatform() >= OSPLATFORM_7) ? FindExInfoBasic : FindExInfoStandard,
|
|
|
|
&fileData,
|
|
|
|
FindExSearchNameMatch,
|
|
|
|
NULL,
|
|
|
|
0);
|
|
|
|
|
2012-06-01 10:47:35 +00:00
|
|
|
bool foundFiles = false;
|
2011-07-15 11:48:50 +00:00
|
|
|
if (hSearch != INVALID_HANDLE_VALUE)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
SkinFolder skinFolder;
|
|
|
|
skinFolder.commandBase = ID_CONFIG_FIRST + index;
|
|
|
|
skinFolder.active = 0;
|
|
|
|
skinFolder.level = level;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
2011-11-19 23:09:41 +00:00
|
|
|
const std::wstring filename = fileData.cFileName;
|
|
|
|
|
2011-07-15 11:48:50 +00:00
|
|
|
if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
|
|
{
|
2011-11-19 23:09:41 +00:00
|
|
|
if (wcscmp(L".", fileData.cFileName) != 0 &&
|
|
|
|
wcscmp(L"..", fileData.cFileName) != 0 &&
|
2012-06-01 10:05:25 +00:00
|
|
|
!(level == 0 && wcscmp(L"Backup", fileData.cFileName) == 0) &&
|
|
|
|
!(level == 1 && wcscmp(L"@Resources", fileData.cFileName) == 0))
|
2011-07-15 11:48:50 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
subfolders.push_back(filename);
|
2011-07-15 11:48:50 +00:00
|
|
|
}
|
|
|
|
}
|
2012-06-01 10:05:25 +00:00
|
|
|
else if (level != 0)
|
2010-07-18 21:35:52 +00:00
|
|
|
{
|
2011-07-15 11:48:50 +00:00
|
|
|
// Check whether the extension is ".ini"
|
2011-11-19 23:09:41 +00:00
|
|
|
size_t filenameLen = filename.size();
|
2011-07-15 11:48:50 +00:00
|
|
|
if (filenameLen >= 4 && _wcsicmp(fileData.cFileName + (filenameLen - 4), L".ini") == 0)
|
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
foundFiles = true;
|
2012-06-01 13:06:36 +00:00
|
|
|
skinFolder.files.push_back(filename);
|
2011-10-29 10:36:07 +00:00
|
|
|
++index;
|
2011-07-15 11:48:50 +00:00
|
|
|
}
|
2010-07-18 21:35:52 +00:00
|
|
|
}
|
2011-11-08 10:32:57 +00:00
|
|
|
}
|
|
|
|
while (FindNextFile(hSearch, &fileData));
|
2011-07-15 11:48:50 +00:00
|
|
|
|
|
|
|
FindClose(hSearch);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
if (level > 0 && (foundFiles || !subfolders.empty()))
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
if (level == 1)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
skinFolder.name = base;
|
2012-06-01 10:05:25 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::wstring::size_type pos = base.rfind(L'\\') + 1;
|
2012-06-01 13:06:36 +00:00
|
|
|
skinFolder.name.assign(base, pos, base.length() - pos);
|
2012-06-01 10:05:25 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
m_SkinFolders.push_back(std::move(skinFolder));
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-07-15 11:48:50 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
if (level != 0)
|
2011-07-15 11:48:50 +00:00
|
|
|
{
|
2011-12-04 22:18:40 +00:00
|
|
|
base += L'\\';
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
if (!subfolders.empty())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 10:47:35 +00:00
|
|
|
bool popFolder = !foundFiles;
|
2012-06-01 10:05:25 +00:00
|
|
|
|
|
|
|
std::list<std::wstring>::const_iterator iter = subfolders.begin();
|
|
|
|
for ( ; iter != subfolders.end(); ++iter)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
int newIndex = ScanForSkinsRecursive(path, base + (*iter), index, level + 1);
|
2012-06-01 10:05:25 +00:00
|
|
|
if (newIndex != index)
|
|
|
|
{
|
2012-06-01 10:47:35 +00:00
|
|
|
popFolder = false;
|
2012-06-01 10:05:25 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
index = newIndex;
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-06-01 10:47:35 +00:00
|
|
|
if (popFolder)
|
2012-05-20 13:12:13 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
m_SkinFolders.pop_back();
|
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
|
|
|
** 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);
|
|
|
|
}
|
2011-11-08 10:32:57 +00:00
|
|
|
}
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2012-05-08 13:53:24 +00:00
|
|
|
void CRainmeter::ExecuteBang(const WCHAR* bang, std::vector<std::wstring>& args, CMeterWindow* meterWindow)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
if (_wcsicmp(bang, L"Refresh") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_REFRESH, args, 0, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"RefreshApp") == 0)
|
2009-12-01 01:35:43 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
// Refresh needs to be delayed since it crashes if done during Update()
|
2012-02-14 17:58:03 +00:00
|
|
|
PostMessage(m_Window, WM_RAINMETER_DELAYED_REFRESH_ALL, (WPARAM)NULL, (LPARAM)NULL);
|
2009-12-01 01:35:43 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"Redraw") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_REDRAW, args, 0, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"Update") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_UPDATE, args, 0, meterWindow);
|
2010-12-28 13:31:17 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"Hide") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_HIDE, args, 0, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"Show") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_SHOW, args, 0, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"Toggle") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_TOGGLE, args, 0, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"HideFade") == 0)
|
2010-03-20 19:40:30 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_HIDEFADE, args, 0, meterWindow);
|
2010-03-20 19:40:30 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ShowFade") == 0)
|
2010-03-20 19:40:30 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_SHOWFADE, args, 0, meterWindow);
|
2010-03-20 19:40:30 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ToggleFade") == 0)
|
2010-03-20 19:40:30 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_TOGGLEFADE, args, 0, meterWindow);
|
2010-03-20 19:40:30 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"HideMeter") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_HIDEMETER, args, 1, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ShowMeter") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_SHOWMETER, args, 1, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ToggleMeter") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_TOGGLEMETER, args, 1, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"MoveMeter") == 0)
|
2010-12-17 00:09:37 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_MOVEMETER, args, 3, meterWindow);
|
2010-12-17 00:09:37 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"UpdateMeter") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_UPDATEMETER, args, 1, meterWindow);
|
2010-12-28 13:31:17 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"DisableMeasure") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_DISABLEMEASURE, args, 1, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"EnableMeasure") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_ENABLEMEASURE, args, 1, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ToggleMeasure") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_TOGGLEMEASURE, args, 1, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"UpdateMeasure") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_UPDATEMEASURE, args, 1, meterWindow);
|
2010-12-28 13:31:17 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"CommandMeasure") == 0)
|
2011-07-09 09:23:28 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_COMMANDMEASURE, args, 2, meterWindow);
|
2011-07-09 09:23:28 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ShowBlur") == 0)
|
2011-04-08 18:14:32 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_SHOWBLUR, args, 0, meterWindow);
|
2011-04-08 18:14:32 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"HideBlur") == 0)
|
2011-04-08 18:14:32 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_HIDEBLUR, args, 0, meterWindow);
|
2011-04-08 18:14:32 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ToggleBlur") == 0)
|
2011-04-08 18:14:32 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_TOGGLEBLUR, args, 0, meterWindow);
|
2011-04-08 18:14:32 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"AddBlur") == 0)
|
2011-04-08 18:14:32 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_ADDBLUR, args, 1, meterWindow);
|
2011-04-08 18:14:32 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"RemoveBlur") == 0)
|
2011-04-08 18:14:32 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_REMOVEBLUR, args, 1, meterWindow);
|
2011-04-08 18:14:32 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ActivateConfig") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
Bang_ActivateSkin(args);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"DeactivateConfig") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
Bang_DeactivateSkin(args, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ToggleConfig") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
Bang_ToggleSkin(args);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"Move") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_MOVE, args, 2, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ZPos") == 0 || _wcsicmp(bang, L"ChangeZPos") == 0) // For backwards compatibility
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_ZPOS, args, 1, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ClickThrough") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_CLICKTHROUGH, args, 1, meterWindow);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"Draggable") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_DRAGGABLE, args, 1, meterWindow);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"SnapEdges") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_SNAPEDGES, args, 1, meterWindow);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"KeepOnScreen") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_KEEPONSCREEN, args, 1, meterWindow);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"SetTransparency") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_SETTRANSPARENCY, args, 1, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"SetVariable") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_SETVARIABLE, args, 2, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"SetOption") == 0)
|
2011-07-27 10:42:35 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_SETOPTION, args, 3, meterWindow);
|
2011-07-27 10:42:35 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"RefreshGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_REFRESH, args, 0, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"UpdateGroup") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_UPDATE, args, 0, meterWindow);
|
2010-12-28 13:31:17 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"RedrawGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_REDRAW, args, 0, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"HideGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_HIDE, args, 0, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ShowGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_SHOW, args, 0, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ToggleGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_TOGGLE, args, 0, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"HideFadeGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_HIDEFADE, args, 0, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ShowFadeGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_SHOWFADE, args, 0, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ToggleFadeGroup") == 0)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_TOGGLEFADE, args, 0, meterWindow);
|
2010-07-17 13:02:34 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"HideMeterGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_HIDEMETERGROUP, args, 1, meterWindow);
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ShowMeterGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_SHOWMETERGROUP, args, 1, meterWindow);
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ToggleMeterGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_TOGGLEMETERGROUP, args, 1, meterWindow);
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"UpdateMeterGroup") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_UPDATEMETERGROUP, args, 1, meterWindow);
|
2010-12-28 13:31:17 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"DisableMeasureGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_DISABLEMEASUREGROUP, args, 1, meterWindow);
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"EnableMeasureGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_ENABLEMEASUREGROUP, args, 1, meterWindow);
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ToggleMeasureGroup") == 0)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_TOGGLEMEASUREGROUP, args, 1, meterWindow);
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"UpdateMeasureGroup") == 0)
|
2010-12-28 13:31:17 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_UPDATEMEASUREGROUP, args, 1, meterWindow);
|
2010-12-28 13:31:17 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"DeactivateConfigGroup") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
Bang_DeactivateSkinGroup(args);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ZPosGroup") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_ZPOS, args, 1, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ClickThroughGroup") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_CLICKTHROUGH, args, 1, meterWindow);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"DraggableGroup") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_DRAGGABLE, args, 1, meterWindow);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"SnapEdgesGroup") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_SNAPEDGES, args, 1, meterWindow);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"KeepOnScreenGroup") == 0)
|
2010-08-22 12:08:38 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_KEEPONSCREEN, args, 1, meterWindow);
|
2010-08-22 12:08:38 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"SetTransparencyGroup") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_SETTRANSPARENCY, args, 1, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"SetVariableGroup") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangGroupWithArgs(BANG_SETVARIABLE, args, 2, meterWindow);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"SetOptionGroup") == 0)
|
2011-07-27 10:42:35 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_SETOPTIONGROUP, args, 3, meterWindow);
|
2011-07-27 10:42:35 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"WriteKeyValue") == 0)
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
Bang_WriteKeyValue(args, meterWindow);
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"PluginBang") == 0)
|
2011-10-29 10:36:07 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
BangWithArgs(BANG_PLUGIN, args, 1, meterWindow);
|
2011-10-29 10:36:07 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"SetClip") == 0)
|
2012-01-30 08:34:56 +00:00
|
|
|
{
|
|
|
|
Bang_SetClip(args);
|
|
|
|
}
|
2012-02-04 15:54:30 +00:00
|
|
|
else if (_wcsicmp(bang, L"SetWallpaper") == 0)
|
|
|
|
{
|
2012-05-21 09:07:50 +00:00
|
|
|
Bang_SetWallpaper(args, meterWindow);
|
2012-02-04 15:54:30 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"About") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
CDialogAbout::Open(args.empty() ? L"" : args[0].c_str());
|
2011-08-28 10:58:26 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"Manage") == 0)
|
2011-08-28 10:58:26 +00:00
|
|
|
{
|
2012-05-08 13:53:24 +00:00
|
|
|
CDialogManage::Open(args.empty() ? L"" : args[0].c_str());
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"SkinMenu") == 0)
|
2010-03-20 19:40:30 +00:00
|
|
|
{
|
2012-02-07 19:13:59 +00:00
|
|
|
Bang_SkinMenu(args, meterWindow);
|
2010-03-20 19:40:30 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"TrayMenu") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-01-30 08:34:56 +00:00
|
|
|
Bang_TrayMenu();
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"ResetStats") == 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
ResetStats();
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-04-02 14:47:13 +00:00
|
|
|
else if (_wcsicmp(bang, L"Log") == 0)
|
|
|
|
{
|
|
|
|
Bang_Log(args);
|
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else if (_wcsicmp(bang, L"Quit") == 0)
|
2009-08-04 09:48:03 +00:00
|
|
|
{
|
2011-10-29 10:36:07 +00:00
|
|
|
// Quit needs to be delayed since it crashes if done during Update()
|
2012-02-21 09:03:16 +00:00
|
|
|
PostMessage(GetTrayWindow()->GetWindow(), WM_COMMAND, MAKEWPARAM(IDM_QUIT, 0), (LPARAM)NULL);
|
2009-08-04 09:48:03 +00:00
|
|
|
}
|
2012-05-06 19:27:59 +00:00
|
|
|
else if (_wcsicmp(bang, L"LsBoxHook") == 0)
|
|
|
|
{
|
|
|
|
// Deprecated.
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
LogWithArgs(LOG_ERROR, L"Invalid bang: !%s", bang);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Runs the given command or bang
|
|
|
|
**
|
|
|
|
*/
|
2012-05-14 15:27:43 +00:00
|
|
|
void CRainmeter::ExecuteCommand(const WCHAR* command, CMeterWindow* meterWindow, bool multi)
|
2012-05-06 19:27:59 +00:00
|
|
|
{
|
|
|
|
if (command[0] == L'!') // Bang
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-05-06 19:27:59 +00:00
|
|
|
++command; // Skip "!"
|
|
|
|
|
|
|
|
if (_wcsnicmp(L"Execute", command, 7) == 0)
|
|
|
|
{
|
|
|
|
command += 7;
|
|
|
|
command = wcschr(command, L'[');
|
|
|
|
if (!command) return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (_wcsnicmp(command, L"Rainmeter", 9) == 0)
|
|
|
|
{
|
|
|
|
// Skip "Rainmeter" for backwards compatibility
|
|
|
|
command += 9;
|
|
|
|
}
|
|
|
|
|
2012-05-08 13:53:24 +00:00
|
|
|
std::wstring bang;
|
|
|
|
std::vector<std::wstring> args;
|
|
|
|
|
2012-05-06 19:27:59 +00:00
|
|
|
// Find the first space
|
|
|
|
const WCHAR* pos = wcschr(command, L' ');
|
|
|
|
if (pos)
|
|
|
|
{
|
|
|
|
bang.assign(command, 0, pos - command);
|
2012-05-12 12:08:47 +00:00
|
|
|
args = ParseString(pos + 1, meterWindow ? &meterWindow->GetParser() : NULL);
|
2012-05-06 19:27:59 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bang = command;
|
|
|
|
}
|
|
|
|
|
2012-05-08 13:53:24 +00:00
|
|
|
ExecuteBang(bang.c_str(), args, meterWindow);
|
2012-05-06 19:27:59 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-14 15:27:43 +00:00
|
|
|
if (multi && command[0] == L'[') // Multi-bang
|
2012-05-06 19:27:59 +00:00
|
|
|
{
|
2012-05-07 10:59:18 +00:00
|
|
|
std::wstring bangs = command;
|
2012-05-08 13:53:24 +00:00
|
|
|
std::wstring::size_type start = std::wstring::npos;
|
2012-05-07 10:59:18 +00:00
|
|
|
int count = 0;
|
2012-05-06 19:27:59 +00:00
|
|
|
for (size_t i = 0, isize = bangs.size(); i < isize; ++i)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-05-06 19:27:59 +00:00
|
|
|
if (bangs[i] == L'[')
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
|
|
|
if (count == 0)
|
|
|
|
{
|
|
|
|
start = i;
|
|
|
|
}
|
2010-03-30 22:37:05 +00:00
|
|
|
++count;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-05-06 19:27:59 +00:00
|
|
|
else if (bangs[i] == L']')
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2010-03-30 22:37:05 +00:00
|
|
|
--count;
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
if (count == 0 && start != std::wstring::npos)
|
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
// Change ] to NULL
|
2012-05-06 19:27:59 +00:00
|
|
|
bangs[i] = L'\0';
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-02-01 15:55:29 +00:00
|
|
|
// Skip whitespace
|
2012-05-06 19:27:59 +00:00
|
|
|
start = bangs.find_first_not_of(L" \t\r\n", start + 1, 4);
|
2012-02-01 15:55:29 +00:00
|
|
|
|
2012-05-14 15:27:43 +00:00
|
|
|
ExecuteCommand(bangs.c_str() + start, meterWindow, false);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
2012-05-06 19:27:59 +00:00
|
|
|
else if (bangs[i] == L'"' && isize > (i + 2) && bangs[i + 1] == L'"' && bangs[i + 2] == L'"')
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
|
|
|
i += 3;
|
|
|
|
|
2012-05-06 19:27:59 +00:00
|
|
|
std::wstring::size_type pos = bangs.find(L"\"\"\"", i);
|
2011-11-19 11:44:04 +00:00
|
|
|
if (pos != std::wstring::npos)
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
2011-11-19 11:44:04 +00:00
|
|
|
i = pos + 2; // Skip "", loop will skip last "
|
2011-08-17 05:56:46 +00:00
|
|
|
}
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// Check for built-ins
|
|
|
|
if (_wcsnicmp(L"PLAY", command, 4) == 0)
|
|
|
|
{
|
|
|
|
if (command[4] == L' ' || // PLAY
|
|
|
|
_wcsnicmp(L"LOOP ", &command[4], 5) == 0) // PLAYLOOP
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
command += 4; // Skip PLAY
|
|
|
|
|
|
|
|
DWORD flags = SND_FILENAME | SND_ASYNC;
|
|
|
|
|
|
|
|
if (command[0] != L' ')
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
flags |= SND_LOOP | SND_NODEFAULT;
|
|
|
|
command += 4; // Skip LOOP
|
|
|
|
}
|
2011-08-17 05:56:46 +00:00
|
|
|
|
2012-02-01 15:55:29 +00:00
|
|
|
++command; // Skip the space
|
|
|
|
if (command[0] != L'\0')
|
|
|
|
{
|
|
|
|
std::wstring sound = command;
|
2011-08-18 04:05:54 +00:00
|
|
|
|
2012-02-01 15:55:29 +00:00
|
|
|
// Strip the quotes
|
|
|
|
std::wstring::size_type len = sound.length();
|
|
|
|
if (len >= 2 && sound[0] == L'"' && sound[len - 1] == L'"')
|
2011-08-17 05:56:46 +00:00
|
|
|
{
|
2012-02-01 15:55:29 +00:00
|
|
|
len -= 2;
|
|
|
|
sound.assign(sound, 1, len);
|
2011-08-18 04:05:54 +00:00
|
|
|
}
|
|
|
|
|
2012-02-01 15:55:29 +00:00
|
|
|
if (meterWindow)
|
2011-08-18 04:05:54 +00:00
|
|
|
{
|
2012-02-04 14:29:51 +00:00
|
|
|
meterWindow->GetParser().ReplaceMeasures(sound);
|
2012-02-01 15:55:29 +00:00
|
|
|
meterWindow->MakePathAbsolute(sound);
|
2011-08-17 05:56:46 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
|
|
|
|
PlaySound(sound.c_str(), NULL, flags);
|
2011-08-17 05:56:46 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +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
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-02-01 15:55:29 +00:00
|
|
|
|
|
|
|
// Run command
|
2012-05-29 16:02:20 +00:00
|
|
|
std::wstring tmpSz = command;
|
2012-02-04 14:29:51 +00:00
|
|
|
if (meterWindow)
|
|
|
|
{
|
|
|
|
meterWindow->GetParser().ReplaceMeasures(tmpSz);
|
|
|
|
}
|
2012-05-29 16:02:20 +00:00
|
|
|
RunCommand(tmpSz);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-14 17:00:07 +00:00
|
|
|
/*
|
|
|
|
** Executes command when current processing is done.
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void CRainmeter::DelayedExecuteCommand(const WCHAR* command)
|
|
|
|
{
|
|
|
|
WCHAR* bang = _wcsdup(command);
|
2012-02-14 17:58:03 +00:00
|
|
|
PostMessage(m_Window, WM_RAINMETER_DELAYED_EXECUTE, (WPARAM)NULL, (LPARAM)bang);
|
2012-02-14 17:00:07 +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;
|
2012-05-20 13:12:13 +00:00
|
|
|
parser.Initialize(iniFile, NULL, NULL);
|
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);
|
2011-09-28 18:28:35 +00:00
|
|
|
m_Debug = 0!=parser.ReadInt(L"Rainmeter", L"Debug", 0);
|
2010-07-07 23:46:44 +00:00
|
|
|
|
2010-07-08 10:59:06 +00:00
|
|
|
if (m_Logging)
|
|
|
|
{
|
|
|
|
StartLogging();
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
if (m_TrayWindow)
|
|
|
|
{
|
2012-05-30 18:53:44 +00:00
|
|
|
m_TrayWindow->ReadOptions(parser);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
m_GlobalOptions.netInSpeed = parser.ReadFloat(L"Rainmeter", L"NetInSpeed", 0.0);
|
|
|
|
m_GlobalOptions.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);
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
m_SkinEditor = parser.ReadString(L"Rainmeter", L"ConfigEditor", L"");
|
|
|
|
if (m_SkinEditor.empty())
|
2010-06-23 12:36:39 +00:00
|
|
|
{
|
|
|
|
// Get the program path associated with .ini files
|
|
|
|
DWORD cchOut = MAX_PATH;
|
|
|
|
HRESULT hr = AssocQueryString(ASSOCF_NOTRUNCATE, ASSOCSTR_EXECUTABLE, L".ini", L"open", buffer, &cchOut);
|
2012-06-01 13:06:36 +00:00
|
|
|
m_SkinEditor = (SUCCEEDED(hr) && cchOut > 0) ? buffer : L"Notepad";
|
2010-06-23 12:36:39 +00:00
|
|
|
}
|
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;
|
|
|
|
HRESULT hr = AssocQueryString(ASSOCF_NOTRUNCATE, ASSOCSTR_EXECUTABLE, L".log", L"open", buffer, &cchOut);
|
2011-12-04 22:18:40 +00:00
|
|
|
m_LogViewer = (SUCCEEDED(hr) && cchOut > 0) ? buffer : L"Notepad";
|
2010-07-07 23:46:44 +00:00
|
|
|
}
|
|
|
|
|
2011-09-28 18:28:35 +00:00
|
|
|
if (m_Debug)
|
2010-07-07 23:46:44 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
LogWithArgs(LOG_NOTICE, L"ConfigEditor: %s", m_SkinEditor.c_str());
|
2010-12-19 23:06:13 +00:00
|
|
|
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_TrayExecuteR = parser.ReadString(L"Rainmeter", L"TrayExecuteR", L"", false);
|
|
|
|
m_TrayExecuteM = parser.ReadString(L"Rainmeter", L"TrayExecuteM", 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
|
|
|
|
2011-11-16 16:47:20 +00:00
|
|
|
const std::wstring& area = parser.ReadString(L"Rainmeter", L"DesktopWorkArea", L"");
|
2009-02-10 18:37:48 +00:00
|
|
|
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);
|
2011-11-16 16:47:20 +00:00
|
|
|
const std::wstring& area = parser.ReadString(L"Rainmeter", buffer, L"");
|
2010-07-10 12:56:37 +00:00
|
|
|
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);
|
|
|
|
|
2011-11-10 11:50:47 +00:00
|
|
|
m_NormalStayDesktop = 0!=parser.ReadInt(L"Rainmeter", L"NormalStayDesktop", 1);
|
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
for (auto iter = parser.GetSections().cbegin(); iter != parser.GetSections().end(); ++iter)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
const WCHAR* section = (*iter).c_str();
|
|
|
|
|
|
|
|
if (wcscmp(section, L"Rainmeter") == 0 ||
|
|
|
|
wcscmp(section, L"TrayMeasure") == 0)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int index = FindSkinFolderIndex(*iter);
|
|
|
|
if (index == -1)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
SkinFolder& skinFolder = m_SkinFolders[index];
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
// Make sure there is a ini file available
|
2012-06-01 10:05:25 +00:00
|
|
|
int active = parser.ReadInt(section, L"Active", 0);
|
2012-06-01 13:06:36 +00:00
|
|
|
if (active > 0 && active <= (int)skinFolder.files.size())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
skinFolder.active = active;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2010-07-17 13:02:34 +00:00
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
int order = parser.ReadInt(section, L"LoadOrder", 0);
|
|
|
|
SetLoadOrder(index, order);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-03-29 19:21:57 +00:00
|
|
|
/*
|
2010-03-29 21:50:05 +00:00
|
|
|
** 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
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
const WCHAR* skinFolder = mw->GetFolderPath().c_str();
|
2012-06-01 10:05:25 +00:00
|
|
|
|
2010-07-22 00:31:59 +00:00
|
|
|
// Verify whether the cached information is valid
|
2012-06-01 13:06:36 +00:00
|
|
|
int index = FindSkinFolderIndex(mw->GetFolderPath());
|
2012-06-01 10:05:25 +00:00
|
|
|
if (index != -1)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
SkinFolder& skinFolder = m_SkinFolders[index];
|
2012-06-01 10:05:25 +00:00
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
const WCHAR* skinIniFile = mw->GetFileName().c_str();
|
2012-06-01 10:05:25 +00:00
|
|
|
|
|
|
|
bool found = false;
|
2012-06-01 13:06:36 +00:00
|
|
|
for (int i = 0, isize = (int)skinFolder.files.size(); i < isize; ++i)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
if (_wcsicmp(skinIniFile, skinFolder.files[i].c_str()) == 0)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
found = true;
|
2012-06-01 13:06:36 +00:00
|
|
|
if (skinFolder.active != i + 1)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
// Switch to new ini-file order
|
2012-06-01 13:06:36 +00:00
|
|
|
skinFolder.active = i + 1;
|
|
|
|
WriteActive(mw->GetFolderPath(), i);
|
2010-07-22 00:31:59 +00:00
|
|
|
}
|
2012-06-01 10:05:25 +00:00
|
|
|
break;
|
2010-07-22 00:31:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
if (!found)
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
DeactivateSkin(mw, index);
|
2010-07-22 00:31:59 +00:00
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
std::wstring error = GetFormattedString(ID_STR_UNABLETOREFRESHSKIN, skinFolder, skinIniFile);
|
2011-09-23 16:28:38 +00:00
|
|
|
MessageBox(NULL, error.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION);
|
2010-07-22 00:31:59 +00:00
|
|
|
}
|
2012-06-01 10:05:25 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
DeactivateSkin(mw, -2); // -2 = Force deactivate
|
2012-06-01 10:05:25 +00:00
|
|
|
|
|
|
|
std::wstring error = GetFormattedString(ID_STR_UNABLETOREFRESHSKIN, skinFolder, L"");
|
|
|
|
MessageBox(NULL, error.c_str(), APPNAME, MB_OK | MB_TOPMOST | MB_ICONEXCLAMATION);
|
2010-07-22 00:31:59 +00:00
|
|
|
}
|
|
|
|
|
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
|
2012-02-02 12:05:14 +00:00
|
|
|
DeleteMeterWindow(NULL);
|
2011-09-04 07:40:12 +00:00
|
|
|
|
|
|
|
std::wstring backup = GetSettingsPath() + L"Themes\\Backup";
|
|
|
|
CreateDirectory(backup.c_str(), NULL);
|
|
|
|
backup += L"\\Rainmeter.thm";
|
2011-09-18 07:38:14 +00:00
|
|
|
|
|
|
|
if (_wcsicmp(name.c_str(), L"Backup") == 0)
|
|
|
|
{
|
|
|
|
// Just load the backup
|
|
|
|
CSystem::CopyFiles(backup, m_IniFile);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Make a copy of current Rainmeter.ini
|
|
|
|
CSystem::CopyFiles(m_IniFile, backup);
|
|
|
|
|
|
|
|
// Replace Rainmeter.ini with theme
|
2011-10-29 10:36:07 +00:00
|
|
|
std::wstring theme = GetSettingsPath() + L"Themes\\";
|
2011-09-18 07:38:14 +00:00
|
|
|
theme += name;
|
|
|
|
std::wstring wallpaper = theme + L"\\RainThemes.bmp";
|
|
|
|
theme += L"\\Rainmeter.thm";
|
2011-10-29 10:36:07 +00:00
|
|
|
CSystem::CopyFiles(theme, GetIniFile());
|
2011-09-18 07:38:14 +00:00
|
|
|
|
|
|
|
PreserveSetting(backup, L"SkinPath");
|
|
|
|
PreserveSetting(backup, L"ConfigEditor");
|
|
|
|
PreserveSetting(backup, L"LogViewer");
|
|
|
|
PreserveSetting(backup, L"Logging");
|
|
|
|
PreserveSetting(backup, L"DisableVersionCheck");
|
2011-10-01 17:55:33 +00:00
|
|
|
PreserveSetting(backup, L"Language");
|
2011-11-16 16:47:20 +00:00
|
|
|
PreserveSetting(backup, L"NormalStayDesktop");
|
2011-09-18 07:38:14 +00:00
|
|
|
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)
|
|
|
|
{
|
2011-10-14 14:53:02 +00:00
|
|
|
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)wallpaper.c_str(), SPIF_UPDATEINIFILE);
|
2011-09-18 07:38:14 +00:00
|
|
|
}
|
2011-09-04 07:40:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ReloadSettings();
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
// Create meter windows for active skins
|
|
|
|
ActivateActiveSkins();
|
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
|
|
|
** 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);
|
|
|
|
|
2011-09-28 18:28:35 +00:00
|
|
|
if (m_Debug)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
|
|
|
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
|
|
|
|
{
|
2012-06-01 13:13:01 +00:00
|
|
|
const MultiMonitorInfo& multimonInfo = CSystem::GetMultiMonitorInfo();
|
|
|
|
const std::vector<MonitorInfo>& monitors = multimonInfo.monitors;
|
2010-07-17 13:02:34 +00:00
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-28 18:28:35 +00:00
|
|
|
if (m_Debug)
|
2010-07-17 13:02:34 +00:00
|
|
|
{
|
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;
|
|
|
|
}
|
|
|
|
|
2011-09-28 18:28:35 +00:00
|
|
|
if (m_Debug)
|
2010-07-10 12:56:37 +00:00
|
|
|
{
|
|
|
|
std::wstring format = L"Applying DesktopWorkArea";
|
|
|
|
if (i != 0)
|
|
|
|
{
|
2010-09-13 20:06:52 +00:00
|
|
|
WCHAR buffer[64];
|
2011-12-09 19:49:06 +00:00
|
|
|
size_t len = _snwprintf_s(buffer, _TRUNCATE, L"@%i", i);
|
|
|
|
format.append(buffer, len);
|
2010-07-10 12:56:37 +00:00
|
|
|
}
|
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
|
|
|
{
|
2012-06-01 13:13:01 +00:00
|
|
|
// Update CSystem::MultiMonitorInfo for for work area variables
|
2010-07-17 13:02:34 +00:00
|
|
|
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
|
|
|
/*
|
|
|
|
** Reads the statistics from the ini-file
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void CRainmeter::ReadStats()
|
|
|
|
{
|
2011-12-01 08:40:37 +00:00
|
|
|
const WCHAR* statsFile = m_StatsFile.c_str();
|
|
|
|
|
2011-04-16 20:05:14 +00:00
|
|
|
// If m_StatsFile doesn't exist, create it and copy the stats section from m_IniFile
|
2011-12-01 08:40:37 +00:00
|
|
|
if (_waccess(statsFile, 0) == -1)
|
2011-04-16 20:05:14 +00:00
|
|
|
{
|
2011-12-01 08:40:37 +00:00
|
|
|
const WCHAR* iniFile = m_IniFile.c_str();
|
2011-04-16 20:05:14 +00:00
|
|
|
WCHAR* tmpSz = new WCHAR[SHRT_MAX]; // Max size returned by GetPrivateProfileSection()
|
|
|
|
|
2011-12-01 08:40:37 +00:00
|
|
|
if (GetPrivateProfileSection(L"Statistics", tmpSz, SHRT_MAX, iniFile) > 0)
|
|
|
|
{
|
|
|
|
WritePrivateProfileString(L"Statistics", NULL, NULL, iniFile);
|
|
|
|
}
|
|
|
|
else
|
2011-04-16 20:05:14 +00:00
|
|
|
{
|
2011-12-01 08:40:37 +00:00
|
|
|
tmpSz[0] = tmpSz[1] = L'\0';
|
2011-04-16 20:05:14 +00:00
|
|
|
}
|
2011-12-01 08:40:37 +00:00
|
|
|
WritePrivateProfileSection(L"Statistics", tmpSz, statsFile);
|
2011-04-16 20:05:14 +00:00
|
|
|
|
|
|
|
delete [] tmpSz;
|
|
|
|
}
|
|
|
|
|
2009-02-10 18:37:48 +00:00
|
|
|
// Only Net measure has stats at the moment
|
2012-05-20 13:12:13 +00:00
|
|
|
CMeasureNet::ReadStats(m_StatsFile, m_StatsDate);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2012-02-15 02:51:27 +00:00
|
|
|
** Writes the statistics to the ini-file. If bForce is false the stats are written only once per an appropriate interval.
|
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();
|
|
|
|
|
2012-02-15 02:51:27 +00:00
|
|
|
if (bForce || (lastWrite + INTERVAL_NETSTATS < 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-12-01 08:40:37 +00:00
|
|
|
const WCHAR* statsFile = m_StatsFile.c_str();
|
2011-12-09 19:49:06 +00:00
|
|
|
CMeasureNet::WriteStats(statsFile, m_StatsDate);
|
2009-07-27 12:30:28 +00:00
|
|
|
|
2011-12-01 08:40:37 +00:00
|
|
|
WritePrivateProfileString(NULL, NULL, NULL, statsFile);
|
2009-07-27 12:30:28 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** Clears the statistics
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
void CRainmeter::ResetStats()
|
|
|
|
{
|
|
|
|
// Set the stats-date string
|
2012-06-01 13:13:01 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
** 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
|
2011-09-23 16:28:38 +00:00
|
|
|
HMENU menu = LoadMenu(m_ResourceInstance, MAKEINTRESOURCE(IDR_CONTEXT_MENU));
|
2010-07-18 21:35:52 +00:00
|
|
|
|
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
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
SetMenuDefaultItem(subMenu, IDM_MANAGE, MF_BYCOMMAND);
|
2011-08-28 10:58:26 +00:00
|
|
|
|
2011-09-28 18:28:35 +00:00
|
|
|
if (_waccess(m_LogFile.c_str(), 0) == -1)
|
2010-07-18 21:35:52 +00:00
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
EnableMenuItem(subMenu, IDM_SHOWLOGFILE, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
EnableMenuItem(subMenu, IDM_DELETELOGFILE, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
EnableMenuItem(subMenu, IDM_STOPLOG, MF_BYCOMMAND | MF_GRAYED);
|
2010-07-08 10:59:06 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
EnableMenuItem(subMenu, (m_Logging) ? IDM_STARTLOG : IDM_STOPLOG, MF_BYCOMMAND | MF_GRAYED);
|
2011-09-28 18:28:35 +00:00
|
|
|
}
|
2010-07-07 23:46:44 +00:00
|
|
|
|
2011-09-28 18:28:35 +00:00
|
|
|
if (m_Debug)
|
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
CheckMenuItem(subMenu, IDM_DEBUGLOG, MF_BYCOMMAND | MF_CHECKED);
|
2010-07-18 21:35:52 +00:00
|
|
|
}
|
2009-08-12 17:11:52 +00:00
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
HMENU skinMenu = GetSubMenu(subMenu, 4);
|
|
|
|
if (skinMenu)
|
2010-07-18 21:35:52 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
if (!m_SkinFolders.empty())
|
2011-08-19 03:12:01 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
DeleteMenu(skinMenu, 0, MF_BYPOSITION); // "No skins available" menuitem
|
|
|
|
CreateAllSkinsMenu(skinMenu);
|
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)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
CheckMenuItem(skinMenu, IDM_DISABLEDRAG, MF_BYCOMMAND | MF_CHECKED);
|
2011-08-19 03:12:01 +00:00
|
|
|
}
|
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;
|
2012-06-01 13:06:36 +00:00
|
|
|
subMenu = CreateSkinMenu(meterWindow, 0, skinMenu);
|
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
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
// Create a menu for all active skins
|
2010-07-18 21:35:52 +00:00
|
|
|
int index = 0;
|
2012-02-03 10:15:18 +00:00
|
|
|
std::map<std::wstring, CMeterWindow*>::const_iterator iter = m_MeterWindows.begin();
|
|
|
|
for (; iter != m_MeterWindows.end(); ++iter)
|
2010-07-18 21:35:52 +00:00
|
|
|
{
|
|
|
|
CMeterWindow* mw = ((*iter).second);
|
2012-06-01 13:06:36 +00:00
|
|
|
HMENU menu = CreateSkinMenu(mw, index, skinMenu);
|
|
|
|
InsertMenu(subMenu, 12, MF_BYPOSITION | MF_POPUP, (UINT_PTR)menu, mw->GetFolderPath().c_str());
|
2010-07-18 21:35:52 +00:00
|
|
|
++index;
|
|
|
|
}
|
2010-06-23 12:36:39 +00:00
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
// Add update notification item
|
2010-07-18 21:35:52 +00:00
|
|
|
if (m_NewVersion)
|
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
InsertMenu(subMenu, 0, MF_BYPOSITION, IDM_NEW_VERSION, GetString(ID_STR_UPDATEAVAILABLE));
|
2011-10-29 10:36:07 +00:00
|
|
|
HiliteMenuItem(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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
int CRainmeter::CreateAllSkinsMenuRecursive(HMENU skinMenu, int index)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
int initialLevel = m_SkinFolders[index].level;
|
|
|
|
int menuIndex = 0;
|
|
|
|
|
|
|
|
const size_t max = Rainmeter->m_SkinFolders.size();
|
|
|
|
while (index < max)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
const SkinFolder& skinFolder = Rainmeter->m_SkinFolders[index];
|
|
|
|
if (skinFolder.level != initialLevel)
|
2012-06-01 10:05:25 +00:00
|
|
|
{
|
|
|
|
return index - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
HMENU subMenu = CreatePopupMenu();
|
|
|
|
|
|
|
|
// Add current folder
|
2012-06-01 13:06:36 +00:00
|
|
|
InsertMenu(skinMenu, menuIndex, MF_POPUP | MF_BYPOSITION, (UINT_PTR)subMenu, skinFolder.name.c_str());
|
2012-06-01 10:05:25 +00:00
|
|
|
|
|
|
|
// Add subfolders
|
|
|
|
const bool hasSubfolder = (index + 1) < max && m_SkinFolders[index + 1].level == initialLevel + 1;
|
|
|
|
if (hasSubfolder)
|
2011-08-19 03:12:01 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
index = CreateAllSkinsMenuRecursive(subMenu, index + 1);
|
2011-08-19 03:12:01 +00:00
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
// Add files
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
int fileIndex = 0;
|
2012-06-01 13:06:36 +00:00
|
|
|
int fileCount = (int)skinFolder.files.size();
|
2012-06-01 10:05:25 +00:00
|
|
|
for ( ; fileIndex < fileCount; ++fileIndex)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
InsertMenu(subMenu, fileIndex, MF_STRING | MF_BYPOSITION, skinFolder.commandBase + fileIndex, skinFolder.files[fileIndex].c_str());
|
2012-06-01 10:55:14 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
if (skinFolder.active)
|
2012-06-01 10:55:14 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
UINT checkPos = skinFolder.active - 1;
|
2012-06-01 10:55:14 +00:00
|
|
|
CheckMenuRadioItem(subMenu, checkPos, checkPos, checkPos, MF_BYPOSITION);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2012-06-01 10:05:25 +00:00
|
|
|
|
|
|
|
if (hasSubfolder && fileIndex != 0)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 10:05:25 +00:00
|
|
|
InsertMenu(subMenu, fileIndex, MF_SEPARATOR | MF_BYPOSITION, 0, NULL);
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
2011-08-19 03:12:01 +00:00
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
++menuIndex;
|
|
|
|
++index;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
2011-08-19 03:12:01 +00:00
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
return index;
|
2009-08-12 17:11:52 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
HMENU CRainmeter::CreateSkinMenu(CMeterWindow* meterWindow, int index, HMENU menu)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-09-23 16:28:38 +00:00
|
|
|
HMENU skinMenu = LoadMenu(m_ResourceInstance, MAKEINTRESOURCE(IDR_SKIN_MENU));
|
2009-02-10 18:37:48 +00:00
|
|
|
|
|
|
|
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
|
|
|
{
|
2012-06-01 10:55:14 +00:00
|
|
|
UINT checkPos = IDM_SKIN_NORMAL - (UINT)meterWindow->GetWindowZPosition();
|
|
|
|
CheckMenuRadioItem(posMenu, checkPos, checkPos, checkPos, MF_BYCOMMAND);
|
2009-02-10 18:37:48 +00:00
|
|
|
|
2012-02-21 09:03:16 +00:00
|
|
|
if (meterWindow->GetXFromRight()) CheckMenuItem(posMenu, IDM_SKIN_FROMRIGHT, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
if (meterWindow->GetYFromBottom()) CheckMenuItem(posMenu, IDM_SKIN_FROMBOTTOM, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
if (meterWindow->GetXPercentage()) CheckMenuItem(posMenu, IDM_SKIN_XPERCENTAGE, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
if (meterWindow->GetYPercentage()) CheckMenuItem(posMenu, IDM_SKIN_YPERCENTAGE, MF_BYCOMMAND | MF_CHECKED);
|
2009-03-24 04:29:48 +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
|
2012-04-17 06:32:10 +00:00
|
|
|
HMENU alphaMenu = GetSubMenu(settingsMenu, 1);
|
|
|
|
if (alphaMenu)
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-06-01 10:55:14 +00:00
|
|
|
UINT checkPos = (UINT)(10 - meterWindow->GetAlphaValue() / 25.5);
|
|
|
|
checkPos = min(9, checkPos);
|
|
|
|
checkPos = max(0, checkPos);
|
|
|
|
CheckMenuRadioItem(alphaMenu, checkPos, checkPos, checkPos, MF_BYPOSITION);
|
2012-04-17 06:32:10 +00:00
|
|
|
|
|
|
|
switch (meterWindow->GetWindowHide())
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2012-04-17 06:32:10 +00:00
|
|
|
case HIDEMODE_FADEIN:
|
|
|
|
CheckMenuItem(alphaMenu, IDM_SKIN_TRANSPARENCY_FADEIN, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
EnableMenuItem(alphaMenu, IDM_SKIN_TRANSPARENCY_FADEOUT, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
break;
|
2011-08-19 03:12:01 +00:00
|
|
|
|
2012-04-17 06:32:10 +00:00
|
|
|
case HIDEMODE_FADEOUT:
|
|
|
|
CheckMenuItem(alphaMenu, IDM_SKIN_TRANSPARENCY_FADEOUT, MF_BYCOMMAND | MF_CHECKED);
|
|
|
|
EnableMenuItem(alphaMenu, IDM_SKIN_TRANSPARENCY_FADEIN, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case HIDEMODE_HIDE:
|
|
|
|
EnableMenuItem(alphaMenu, IDM_SKIN_TRANSPARENCY_FADEIN, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
EnableMenuItem(alphaMenu, IDM_SKIN_TRANSPARENCY_FADEOUT, MF_BYCOMMAND | MF_GRAYED);
|
|
|
|
break;
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 10:55:14 +00:00
|
|
|
// Tick the settings
|
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:
|
2012-02-21 09:03:16 +00:00
|
|
|
CheckMenuItem(settingsMenu, IDM_SKIN_HIDEONMOUSE, MF_BYCOMMAND | MF_CHECKED);
|
2011-08-20 04:55:29 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case HIDEMODE_FADEIN:
|
|
|
|
case HIDEMODE_FADEOUT:
|
2012-02-21 09:03:16 +00:00
|
|
|
EnableMenuItem(settingsMenu, IDM_SKIN_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())
|
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
CheckMenuItem(settingsMenu, IDM_SKIN_SNAPTOEDGES, MF_BYCOMMAND | MF_CHECKED);
|
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->GetSavePosition())
|
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
CheckMenuItem(settingsMenu, IDM_SKIN_REMEMBERPOSITION, MF_BYCOMMAND | MF_CHECKED);
|
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 (m_DisableDragging)
|
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
EnableMenuItem(settingsMenu, IDM_SKIN_DRAGGABLE, MF_BYCOMMAND | MF_GRAYED);
|
2011-08-19 03:12:01 +00:00
|
|
|
}
|
|
|
|
else if (meterWindow->GetWindowDraggable())
|
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
CheckMenuItem(settingsMenu, IDM_SKIN_DRAGGABLE, MF_BYCOMMAND | MF_CHECKED);
|
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->GetClickThrough())
|
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
CheckMenuItem(settingsMenu, IDM_SKIN_CLICKTHROUGH, MF_BYCOMMAND | MF_CHECKED);
|
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->GetKeepOnScreen())
|
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
CheckMenuItem(settingsMenu, IDM_SKIN_KEEPONSCREEN, MF_BYCOMMAND | MF_CHECKED);
|
2011-08-19 03:12:01 +00:00
|
|
|
}
|
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
|
2012-06-01 13:06:36 +00:00
|
|
|
const std::wstring& skinName = meterWindow->GetFolderPath();
|
2012-02-21 09:03:16 +00:00
|
|
|
ModifyMenu(skinMenu, IDM_SKIN_OPENSKINSFOLDER, MF_BYCOMMAND, IDM_SKIN_OPENSKINSFOLDER, skinName.c_str());
|
|
|
|
SetMenuDefaultItem(skinMenu, IDM_SKIN_OPENSKINSFOLDER, FALSE);
|
2011-08-19 03:12:01 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
const SkinFolder& skinFolder = m_SkinFolders[FindSkinFolderIndex(skinName)];
|
|
|
|
for (int i = 0, isize = (int)skinFolder.files.size(); i < isize; ++i)
|
2012-06-01 10:55:14 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
InsertMenu(variantsMenu, i, MF_BYPOSITION, skinFolder.commandBase + i, skinFolder.files[i].c_str());
|
2012-06-01 10:55:14 +00:00
|
|
|
}
|
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
if (skinFolder.active)
|
2010-06-23 12:36:39 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
UINT checkPos = skinFolder.active - 1;
|
2012-06-01 10:55:14 +00:00
|
|
|
CheckMenuRadioItem(variantsMenu, checkPos, checkPos, checkPos, MF_BYPOSITION);
|
2010-06-23 12:36:39 +00:00
|
|
|
}
|
|
|
|
}
|
2010-07-18 21:35:52 +00:00
|
|
|
|
2012-06-01 13:06:36 +00:00
|
|
|
// Add skin root menu
|
|
|
|
int itemCount = GetMenuItemCount(menu);
|
2010-07-18 21:35:52 +00:00
|
|
|
if (itemCount > 0)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
std::wstring root = meterWindow->GetFolderPath();
|
2010-07-18 21:35:52 +00:00
|
|
|
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)
|
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
UINT state = GetMenuState(menu, i, MF_BYPOSITION);
|
2011-06-09 18:59:16 +00:00
|
|
|
if (state == 0xFFFFFFFF || (state & MF_POPUP) == 0) break;
|
|
|
|
|
|
|
|
WCHAR buffer[MAX_PATH];
|
2012-06-01 13:06:36 +00:00
|
|
|
if (GetMenuString(menu, 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
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
HMENU skinRootMenu = GetSubMenu(menu, i);
|
|
|
|
if (skinRootMenu)
|
2010-07-18 21:35:52 +00:00
|
|
|
{
|
2012-06-01 13:06:36 +00:00
|
|
|
InsertMenu(skinMenu, 3, MF_BYPOSITION | MF_POPUP, (UINT_PTR)skinRootMenu, root.c_str());
|
2010-07-18 21:35:52 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-02-10 18:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return skinMenu;
|
|
|
|
}
|
|
|
|
|
2012-06-01 10:05:25 +00:00
|
|
|
void CRainmeter::CreateThemeMenu(HMENU themeMenu)
|
|
|
|
{
|
|
|
|
for (size_t i = 0, isize = m_Themes.size(); i < isize; ++i)
|
|
|
|
{
|
|
|
|
InsertMenu(themeMenu, i, MF_BYPOSITION, ID_THEME_FIRST + i, m_Themes[i].c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2012-06-01 13:13:01 +00:00
|
|
|
const MultiMonitorInfo& multimonInfo = CSystem::GetMultiMonitorInfo();
|
|
|
|
const std::vector<MonitorInfo>& monitors = multimonInfo.monitors;
|
* 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
|
|
|
|
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];
|
2011-12-09 19:49:06 +00:00
|
|
|
size_t len = _snwprintf_s(buffer, _TRUNCATE, L"@%i: ", i + 1);
|
* 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
|
|
|
|
2011-12-09 19:49:06 +00:00
|
|
|
std::wstring item(buffer, len);
|
|
|
|
|
|
|
|
if (monitors[i].monitorName.size() > 32)
|
* 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
|
|
|
{
|
2011-12-09 19:49:06 +00:00
|
|
|
item.append(monitors[i].monitorName, 0, 32);
|
* 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
|
|
|
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
|
|
|
if (!screenDefined)
|
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
CheckMenuItem(monitorMenu, IDM_SKIN_MONITOR_PRIMARY, MF_BYCOMMAND | MF_CHECKED);
|
2010-06-23 12:36:39 +00:00
|
|
|
}
|
* 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())
|
|
|
|
{
|
2012-02-21 09:03:16 +00:00
|
|
|
CheckMenuItem(monitorMenu, IDM_SKIN_MONITOR_AUTOSELECT, MF_BYCOMMAND | MF_CHECKED);
|
2010-06-23 12:36:39 +00:00
|
|
|
}
|
* 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
|
2012-05-30 03:45:03 +00:00
|
|
|
const WCHAR* logFile = m_LogFile.c_str();
|
2012-05-29 16:02:20 +00:00
|
|
|
if (_waccess(logFile, 0) == -1)
|
2010-07-08 10:59:06 +00:00
|
|
|
{
|
|
|
|
// Create log file
|
2012-05-29 16:02:20 +00:00
|
|
|
HANDLE file = CreateFile(logFile, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
|
2010-07-08 10:59:06 +00:00
|
|
|
if (file != INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
CloseHandle(file);
|
|
|
|
SetLogging(true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Disable logging
|
|
|
|
SetLogging(false);
|
2011-09-23 16:28:38 +00:00
|
|
|
|
2012-05-29 16:02:20 +00:00
|
|
|
std::wstring text = GetFormattedString(ID_STR_LOGFILECREATEFAIL, logFile);
|
2011-09-23 16:28:38 +00:00
|
|
|
MessageBox(NULL, text.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);
|
|
|
|
}
|
|
|
|
|
2012-02-21 19:15:10 +00:00
|
|
|
void CRainmeter::ShowLogFile()
|
|
|
|
{
|
|
|
|
// Check if the file exists
|
2012-05-30 03:45:03 +00:00
|
|
|
const WCHAR* logFile = m_LogFile.c_str();
|
2012-05-29 16:02:20 +00:00
|
|
|
if (_waccess(logFile, 0) != -1)
|
2012-02-21 19:15:10 +00:00
|
|
|
{
|
2012-05-29 16:02:20 +00:00
|
|
|
RunFile(m_LogViewer.c_str(), logFile);
|
2012-02-21 19:15:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-07-08 10:59:06 +00:00
|
|
|
void CRainmeter::DeleteLogFile()
|
|
|
|
{
|
|
|
|
// Check if the file exists
|
2012-05-30 03:45:03 +00:00
|
|
|
const WCHAR* logFile = m_LogFile.c_str();
|
2012-05-29 16:02:20 +00:00
|
|
|
if (_waccess(logFile, 0) != -1)
|
2010-07-08 10:59:06 +00:00
|
|
|
{
|
2012-05-29 16:02:20 +00:00
|
|
|
std::wstring text = GetFormattedString(ID_STR_LOGFILEDELETE, logFile);
|
2011-09-23 16:28:38 +00:00
|
|
|
int res = MessageBox(NULL, text.c_str(), APPNAME, MB_YESNO | MB_TOPMOST | MB_ICONQUESTION);
|
2010-07-08 10:59:06 +00:00
|
|
|
if (res == IDYES)
|
|
|
|
{
|
|
|
|
// Disable logging
|
|
|
|
SetLogging(false);
|
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
|
2012-06-01 13:06:36 +00:00
|
|
|
LogInfo logInfo = {level, time, message};
|
2011-09-03 16:45:29 +00:00
|
|
|
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)
|
|
|
|
{
|
2011-09-28 18:28:35 +00:00
|
|
|
m_Debug = debug;
|
2010-07-07 23:46:44 +00:00
|
|
|
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
|
|
|
{
|
2012-05-30 04:08:50 +00:00
|
|
|
const WCHAR* iniFile = m_IniFile.c_str();
|
|
|
|
if (!CSystem::IsFileWritable(iniFile))
|
2009-02-10 18:37:48 +00:00
|
|
|
{
|
2011-09-24 09:13:13 +00:00
|
|
|
std::wstring error = GetString(ID_STR_SETTINGSNOTWRITABLE);
|
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
|
|
|
|
2012-05-30 04:08:50 +00:00
|
|
|
error += GetFormattedString(ID_STR_SETTINGSMOVEFILE, iniFile, strTarget.c_str());
|
2009-07-24 07:56:37 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-05-30 04:08:50 +00:00
|
|
|
error += GetFormattedString(ID_STR_SETTINGSREADONLY, iniFile);
|
2009-07-24 07:56:37 +00:00
|
|
|
}
|
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
|
|
|
{
|
2011-11-26 02:49:52 +00:00
|
|
|
std::wstring::size_type pos;
|
|
|
|
|
|
|
|
if ((pos = strPath.find(L'%')) != std::wstring::npos &&
|
|
|
|
strPath.find(L'%', pos + 2) != 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
|
2011-11-26 02:49:52 +00:00
|
|
|
pos = strPath.find(L"%APPDATA%", pos);
|
2010-07-22 00:31:59 +00:00
|
|
|
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))
|
|
|
|
{
|
2011-11-24 00:30:56 +00:00
|
|
|
size_t len = wcslen(buffer);
|
2010-07-22 01:50:22 +00:00
|
|
|
do
|
|
|
|
{
|
2011-11-24 00:30:56 +00:00
|
|
|
strPath.replace(pos, 9, buffer, len);
|
2010-07-22 01:50:22 +00:00
|
|
|
}
|
2011-11-24 00:30:56 +00:00
|
|
|
while ((pos = strPath.find(L"%APPDATA%", pos + len)) != 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
|
|
|
|
2011-11-24 00:30:56 +00:00
|
|
|
if ((pos = strPath.find(L'%')) != std::wstring::npos &&
|
|
|
|
strPath.find(L'%', pos + 2) != std::wstring::npos)
|
2009-07-26 21:08:46 +00:00
|
|
|
{
|
2010-07-22 00:31:59 +00:00
|
|
|
// Expand the environment variables
|
2011-11-08 10:32:57 +00:00
|
|
|
do
|
2010-07-22 00:31:59 +00:00
|
|
|
{
|
2011-11-08 10:32:57 +00:00
|
|
|
DWORD ret = ExpandEnvironmentStrings(strPath.c_str(), buffer, bufSize);
|
|
|
|
if (ret == 0) // Error
|
|
|
|
{
|
|
|
|
LogWithArgs(LOG_WARNING, L"Unable to expand environment strings in: %s", strPath.c_str());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (ret <= bufSize) // Fits in the buffer
|
|
|
|
{
|
2011-12-09 19:49:06 +00:00
|
|
|
strPath.assign(buffer, ret - 1);
|
2011-11-08 10:32:57 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
delete [] buffer;
|
|
|
|
bufSize = ret;
|
|
|
|
buffer = new WCHAR[bufSize];
|
2010-07-22 00:31:59 +00:00
|
|
|
}
|
2011-11-08 10:32:57 +00:00
|
|
|
while (true);
|
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
|
|
|
}
|
|
|
|
}
|