Work on trimming native rainmeter library. Incomplete (won't build!!!)

This commit is contained in:
Tiberiu Chibici 2014-08-12 16:38:37 +03:00
parent b8c8f2a1b0
commit dc7eff73b4
36 changed files with 2334 additions and 9369 deletions

View File

@ -32,7 +32,6 @@
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<ResourceCompile Include="Language.rc" />
<ResourceCompile Include="Resource.rc">
<ExcludedFromBuild>true</ExcludedFromBuild>
</ResourceCompile>

View File

@ -15,9 +15,6 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Language.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
<ResourceCompile Include="Resource.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>

View File

@ -20,13 +20,10 @@
#include "../Common/PathUtil.h"
#include "CommandHandler.h"
#include "ConfigParser.h"
#include "DialogAbout.h"
#include "DialogManage.h"
#include "Measure.h"
#include "Logger.h"
#include "Rainmeter.h"
#include "System.h"
#include "TrayWindow.h"
#include "resource.h"
namespace {
@ -708,26 +705,12 @@ void CommandHandler::DoSetWallpaperBang(std::vector<std::wstring>& args, MeterWi
void CommandHandler::DoAboutBang(std::vector<std::wstring>& args, MeterWindow* meterWindow)
{
DialogAbout::Open(args.empty() ? L"" : args[0].c_str());
LogErrorF(L"!About: about bang is unsupported.");
}
void CommandHandler::DoManageBang(std::vector<std::wstring>& args, MeterWindow* meterWindow)
{
const size_t argsSize = args.size();
if (argsSize >= 2 && argsSize <= 3)
{
DialogManage::Open(args[0].c_str(),
args[1].c_str(),
(argsSize == 3) ? args[2].c_str() : L"");
}
else if (argsSize <= 1)
{
DialogManage::Open(args.empty() ? L"" : args[0].c_str());
}
else
{
LogErrorF(meterWindow, L"!Manage: Invalid parameters");
}
LogErrorF(L"!Manage: manage bang is unsupported.");
}
void CommandHandler::DoSkinMenuBang(std::vector<std::wstring>& args, MeterWindow* skin)

View File

@ -92,7 +92,7 @@ void ConfigParser::SetBuiltInVariables(const std::wstring& filename, const std::
return m_BuiltInVariables.insert(std::make_pair(name, value));
};
insertVariable(L"PROGRAMPATH", GetRainmeter().GetPath());
insertVariable(L"PROGRAMPATH", GetRainmeter().GetWorkDirectory());
insertVariable(L"PROGRAMDRIVE", GetRainmeter().GetDrive());
insertVariable(L"SETTINGSPATH", GetRainmeter().GetSettingsPath());
insertVariable(L"SKINSPATH", GetRainmeter().GetSkinPath());

View File

@ -1,690 +0,0 @@
/*
Copyright (C) 2013 Rainmeter Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "../Common/MenuTemplate.h"
#include "../Common/Gfx/CanvasD2D.h"
#include "ContextMenu.h"
#include "Rainmeter.h"
#include "Litestep.h"
#include "MeterWindow.h"
#include "System.h"
#include "TrayWindow.h"
#include "resource.h"
ContextMenu::ContextMenu() :
m_MenuActive(false)
{
}
/*
** Opens the context menu in given coordinates.
*/
void ContextMenu::ShowMenu(POINT pos, MeterWindow* meterWindow)
{
static const MenuTemplate s_Menu[] =
{
MENU_ITEM(IDM_MANAGE, ID_STR_MANAGE),
MENU_ITEM(IDM_ABOUT, ID_STR_ABOUT),
MENU_ITEM(IDM_SHOW_HELP, ID_STR_HELP),
MENU_SEPARATOR(),
MENU_SUBMENU(ID_STR_SKINS,
MENU_ITEM_GRAYED(0, ID_STR_NOSKINS),
MENU_SEPARATOR(),
MENU_ITEM(IDM_OPENSKINSFOLDER, ID_STR_OPENFOLDER),
MENU_ITEM(IDM_DISABLEDRAG, ID_STR_DISABLEDRAGGING)),
MENU_SUBMENU(ID_STR_THEMES,
MENU_ITEM_GRAYED(0, ID_STR_NOTHEMES)),
MENU_SEPARATOR(),
MENU_ITEM(IDM_EDITCONFIG, ID_STR_EDITSETTINGS),
MENU_ITEM(IDM_REFRESH, ID_STR_REFRESHALL),
MENU_SEPARATOR(),
MENU_SUBMENU(ID_STR_LOGGING,
MENU_ITEM(IDM_SHOWLOGFILE, ID_STR_SHOWLOGFILE),
MENU_SEPARATOR(),
MENU_ITEM(IDM_STARTLOG, ID_STR_STARTLOGGING),
MENU_ITEM(IDM_STOPLOG, ID_STR_STOPLOGGING),
MENU_SEPARATOR(),
MENU_ITEM(IDM_DELETELOGFILE, ID_STR_DELETELOGFILE),
MENU_ITEM(IDM_DEBUGLOG, ID_STR_DEBUGMODE)),
MENU_SEPARATOR(),
MENU_ITEM(IDM_QUIT, ID_STR_EXIT)
};
if (m_MenuActive || (meterWindow && meterWindow->IsClosing())) return;
// Show context menu, if no actions were executed
HMENU menu = MenuTemplate::CreateMenu(s_Menu, _countof(s_Menu), GetString);
if (!menu) return;
m_MenuActive = true;
Rainmeter& rainmeter = GetRainmeter();
SetMenuDefaultItem(menu, IDM_MANAGE, MF_BYCOMMAND);
if (_waccess(GetLogger().GetLogFilePath().c_str(), 0) == -1)
{
EnableMenuItem(menu, IDM_SHOWLOGFILE, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(menu, IDM_DELETELOGFILE, MF_BYCOMMAND | MF_GRAYED);
EnableMenuItem(menu, IDM_STOPLOG, MF_BYCOMMAND | MF_GRAYED);
}
else
{
EnableMenuItem(
menu,
(GetLogger().IsLogToFile()) ? IDM_STARTLOG : IDM_STOPLOG,
MF_BYCOMMAND | MF_GRAYED);
}
if (rainmeter.m_Debug)
{
CheckMenuItem(menu, IDM_DEBUGLOG, MF_BYCOMMAND | MF_CHECKED);
}
HMENU allSkinsMenu = GetSubMenu(menu, 4);
if (allSkinsMenu)
{
if (!rainmeter.m_SkinRegistry.IsEmpty())
{
DeleteMenu(allSkinsMenu, 0, MF_BYPOSITION); // "No skins available" menuitem
CreateAllSkinsMenu(allSkinsMenu);
}
if (rainmeter.m_DisableDragging)
{
CheckMenuItem(allSkinsMenu, IDM_DISABLEDRAG, MF_BYCOMMAND | MF_CHECKED);
}
}
HMENU layoutMenu = GetSubMenu(menu, 5);
if (layoutMenu)
{
if (!rainmeter.m_Layouts.empty())
{
DeleteMenu(layoutMenu, 0, MF_BYPOSITION); // "No layouts available" menuitem
CreateLayoutMenu(layoutMenu);
}
}
if (meterWindow)
{
HMENU rainmeterMenu = menu;
menu = CreateSkinMenu(meterWindow, 0, allSkinsMenu);
InsertMenu(menu, IDM_CLOSESKIN, MF_BYCOMMAND | MF_POPUP, (UINT_PTR)rainmeterMenu, L"Rainmeter");
InsertMenu(menu, IDM_CLOSESKIN, MF_BYCOMMAND | MF_SEPARATOR, 0, nullptr);
}
else
{
InsertMenu(menu, 12, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
// Create a menu for all active skins
int index = 0;
std::map<std::wstring, MeterWindow*>::const_iterator iter = rainmeter.m_MeterWindows.begin();
for (; iter != rainmeter.m_MeterWindows.end(); ++iter)
{
MeterWindow* mw = ((*iter).second);
HMENU skinMenu = CreateSkinMenu(mw, index, allSkinsMenu);
InsertMenu(menu, 12, MF_BYPOSITION | MF_POPUP, (UINT_PTR)skinMenu, mw->GetFolderPath().c_str());
++index;
}
// Add update notification item
if (rainmeter.m_NewVersion)
{
InsertMenu(menu, 0, MF_BYPOSITION, IDM_NEW_VERSION, GetString(ID_STR_UPDATEAVAILABLE));
HiliteMenuItem(rainmeter.GetTrayWindow()->GetWindow(), menu, 0, MF_BYPOSITION | MF_HILITE);
InsertMenu(menu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
}
}
HWND hWnd = WindowFromPoint(pos);
if (hWnd != nullptr)
{
MeterWindow* mw = rainmeter.GetMeterWindow(hWnd);
if (mw)
{
// Cancel the mouse event beforehand
mw->SetMouseLeaveEvent(true);
}
}
DisplayMenu(pos, menu, meterWindow ? meterWindow->GetWindow() : rainmeter.m_TrayWindow->GetWindow());
DestroyMenu(menu);
m_MenuActive = false;
}
void ContextMenu::ShowSkinCustomMenu(POINT pos, MeterWindow* meterWindow)
{
if (m_MenuActive || meterWindow->IsClosing()) return;
m_MenuActive = true;
HMENU menu = CreatePopupMenu();
AppendSkinCustomMenu(meterWindow, 0, menu, true);
DisplayMenu(pos, menu, meterWindow->GetWindow());
DestroyMenu(menu);
m_MenuActive = false;
}
void ContextMenu::DisplayMenu(POINT pos, HMENU menu, HWND parentWindow)
{
// Set the window to foreground
HWND foregroundWindow = GetForegroundWindow();
if (foregroundWindow != parentWindow)
{
const DWORD foregroundThreadID = GetWindowThreadProcessId(foregroundWindow, nullptr);
const DWORD currentThreadID = GetCurrentThreadId();
AttachThreadInput(currentThreadID, foregroundThreadID, TRUE);
SetForegroundWindow(parentWindow);
AttachThreadInput(currentThreadID, foregroundThreadID, FALSE);
}
// Show context menu
TrackPopupMenu(
menu,
TPM_RIGHTBUTTON | TPM_LEFTALIGN | (*GetString(ID_STR_ISRTL) == L'1' ? TPM_LAYOUTRTL : 0),
pos.x,
pos.y,
0,
parentWindow,
nullptr);
}
HMENU ContextMenu::CreateSkinMenu(MeterWindow* meterWindow, int index, HMENU menu)
{
static const MenuTemplate s_Menu[] =
{
MENU_ITEM(IDM_SKIN_OPENSKINSFOLDER, 0),
MENU_SEPARATOR(),
MENU_SUBMENU(ID_STR_VARIANTS,
MENU_SEPARATOR()),
MENU_SEPARATOR(),
MENU_SUBMENU(ID_STR_SETTINGS,
MENU_SUBMENU(ID_STR_POSITION,
MENU_SUBMENU(ID_STR_DISPLAYMONITOR,
MENU_ITEM(IDM_SKIN_MONITOR_PRIMARY, ID_STR_USEDEFAULTMONITOR),
MENU_ITEM(ID_MONITOR_FIRST, ID_STR_VIRTUALSCREEN),
MENU_SEPARATOR(),
MENU_SEPARATOR(),
MENU_ITEM(IDM_SKIN_MONITOR_AUTOSELECT, ID_STR_AUTOSELECTMONITOR)),
MENU_SEPARATOR(),
MENU_ITEM(IDM_SKIN_VERYTOPMOST, ID_STR_STAYTOPMOST),
MENU_ITEM(IDM_SKIN_TOPMOST, ID_STR_TOPMOST),
MENU_ITEM(IDM_SKIN_NORMAL, ID_STR_NORMAL),
MENU_ITEM(IDM_SKIN_BOTTOM, ID_STR_BOTTOM),
MENU_ITEM(IDM_SKIN_ONDESKTOP, ID_STR_ONDESKTOP),
MENU_SEPARATOR(),
MENU_ITEM(IDM_SKIN_FROMRIGHT, ID_STR_FROMRIGHT),
MENU_ITEM(IDM_SKIN_FROMBOTTOM, ID_STR_FROMBOTTOM),
MENU_ITEM(IDM_SKIN_XPERCENTAGE, ID_STR_XASPERCENTAGE),
MENU_ITEM(IDM_SKIN_YPERCENTAGE, ID_STR_YASPERCENTAGE)),
MENU_SUBMENU(ID_STR_TRANSPARENCY,
MENU_ITEM(IDM_SKIN_TRANSPARENCY_0, ID_STR_0PERCENT),
MENU_ITEM(IDM_SKIN_TRANSPARENCY_10, ID_STR_10PERCENT),
MENU_ITEM(IDM_SKIN_TRANSPARENCY_20, ID_STR_20PERCENT),
MENU_ITEM(IDM_SKIN_TRANSPARENCY_30, ID_STR_30PERCENT),
MENU_ITEM(IDM_SKIN_TRANSPARENCY_40, ID_STR_40PERCENT),
MENU_ITEM(IDM_SKIN_TRANSPARENCY_50, ID_STR_50PERCENT),
MENU_ITEM(IDM_SKIN_TRANSPARENCY_60, ID_STR_60PERCENT),
MENU_ITEM(IDM_SKIN_TRANSPARENCY_70, ID_STR_70PERCENT),
MENU_ITEM(IDM_SKIN_TRANSPARENCY_80, ID_STR_80PERCENT),
MENU_ITEM(IDM_SKIN_TRANSPARENCY_90, ID_STR_90PERCENT),
MENU_SEPARATOR(),
MENU_ITEM(IDM_SKIN_TRANSPARENCY_FADEIN, ID_STR_FADEIN),
MENU_ITEM(IDM_SKIN_TRANSPARENCY_FADEOUT, ID_STR_FADEOUT)),
MENU_SEPARATOR(),
MENU_ITEM(IDM_SKIN_HIDEONMOUSE, ID_STR_HIDEONMOUSEOVER),
MENU_ITEM(IDM_SKIN_DRAGGABLE, ID_STR_DRAGGABLE),
MENU_ITEM(IDM_SKIN_REMEMBERPOSITION, ID_STR_SAVEPOSITION),
MENU_ITEM(IDM_SKIN_SNAPTOEDGES, ID_STR_SNAPTOEDGES),
MENU_ITEM(IDM_SKIN_CLICKTHROUGH, ID_STR_CLICKTHROUGH),
MENU_ITEM(IDM_SKIN_KEEPONSCREEN, ID_STR_KEEPONSCREEN),
MENU_ITEM(IDM_SKIN_USED2D, ID_STR_USED2D)),
MENU_SEPARATOR(),
MENU_ITEM(IDM_SKIN_MANAGESKIN, ID_STR_MANAGESKIN),
MENU_ITEM(IDM_SKIN_EDITSKIN, ID_STR_EDITSKIN),
MENU_ITEM(IDM_SKIN_REFRESH, ID_STR_REFRESHSKIN),
MENU_SEPARATOR(),
MENU_ITEM(IDM_CLOSESKIN, ID_STR_UNLOADSKIN)
};
HMENU skinMenu = MenuTemplate::CreateMenu(s_Menu, _countof(s_Menu), GetString);
if (!skinMenu) return nullptr;
// Tick the position
HMENU settingsMenu = GetSubMenu(skinMenu, 4);
if (settingsMenu)
{
HMENU posMenu = GetSubMenu(settingsMenu, 0);
if (posMenu)
{
const UINT checkPos = IDM_SKIN_NORMAL - (UINT)meterWindow->GetWindowZPosition();
CheckMenuRadioItem(posMenu, checkPos, checkPos, checkPos, MF_BYCOMMAND);
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);
HMENU monitorMenu = GetSubMenu(posMenu, 0);
if (monitorMenu)
{
CreateMonitorMenu(monitorMenu, meterWindow);
}
}
// Tick the transparency
HMENU alphaMenu = GetSubMenu(settingsMenu, 1);
if (alphaMenu)
{
UINT checkPos = (UINT)(10 - meterWindow->GetAlphaValue() / 25.5);
checkPos = min(9, checkPos);
checkPos = max(0, checkPos);
CheckMenuRadioItem(alphaMenu, checkPos, checkPos, checkPos, MF_BYPOSITION);
switch (meterWindow->GetWindowHide())
{
case HIDEMODE_FADEIN:
CheckMenuItem(alphaMenu, IDM_SKIN_TRANSPARENCY_FADEIN, MF_BYCOMMAND | MF_CHECKED);
EnableMenuItem(alphaMenu, IDM_SKIN_TRANSPARENCY_FADEOUT, MF_BYCOMMAND | MF_GRAYED);
break;
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;
}
}
// Tick the settings
switch (meterWindow->GetWindowHide())
{
case HIDEMODE_HIDE:
CheckMenuItem(settingsMenu, IDM_SKIN_HIDEONMOUSE, MF_BYCOMMAND | MF_CHECKED);
break;
case HIDEMODE_FADEIN:
case HIDEMODE_FADEOUT:
EnableMenuItem(settingsMenu, IDM_SKIN_HIDEONMOUSE, MF_BYCOMMAND | MF_GRAYED);
break;
}
if (meterWindow->GetSnapEdges())
{
CheckMenuItem(settingsMenu, IDM_SKIN_SNAPTOEDGES, MF_BYCOMMAND | MF_CHECKED);
}
if (meterWindow->GetSavePosition())
{
CheckMenuItem(settingsMenu, IDM_SKIN_REMEMBERPOSITION, MF_BYCOMMAND | MF_CHECKED);
}
if (GetRainmeter().m_DisableDragging)
{
EnableMenuItem(settingsMenu, IDM_SKIN_DRAGGABLE, MF_BYCOMMAND | MF_GRAYED);
}
else if (meterWindow->GetWindowDraggable())
{
CheckMenuItem(settingsMenu, IDM_SKIN_DRAGGABLE, MF_BYCOMMAND | MF_CHECKED);
}
if (meterWindow->GetClickThrough())
{
CheckMenuItem(settingsMenu, IDM_SKIN_CLICKTHROUGH, MF_BYCOMMAND | MF_CHECKED);
}
if (meterWindow->GetKeepOnScreen())
{
CheckMenuItem(settingsMenu, IDM_SKIN_KEEPONSCREEN, MF_BYCOMMAND | MF_CHECKED);
}
if (Gfx::CanvasD2D::Initialize())
{
if (!GetRainmeter().GetUseD2D())
{
EnableMenuItem(settingsMenu, IDM_SKIN_USED2D, MF_BYCOMMAND | MF_GRAYED);
}
else if (meterWindow->GetUseD2D())
{
CheckMenuItem(settingsMenu, IDM_SKIN_USED2D, MF_BYCOMMAND | MF_CHECKED);
}
}
else
{
DeleteMenu(settingsMenu, IDM_SKIN_USED2D, MF_BYCOMMAND);
}
Gfx::CanvasD2D::Finalize();
}
// Add the name of the Skin to the menu
const std::wstring& skinName = meterWindow->GetFolderPath();
ModifyMenu(skinMenu, IDM_SKIN_OPENSKINSFOLDER, MF_BYCOMMAND, IDM_SKIN_OPENSKINSFOLDER, skinName.c_str());
SetMenuDefaultItem(skinMenu, IDM_SKIN_OPENSKINSFOLDER, FALSE);
// Remove dummy menuitem from the variants menu
HMENU variantsMenu = GetSubMenu(skinMenu, 2);
if (variantsMenu)
{
DeleteMenu(variantsMenu, 0, MF_BYPOSITION);
}
// Give the menuitem the unique id that depends on the skin
ChangeSkinIndex(skinMenu, index);
// Add the variants menu
if (variantsMenu)
{
const SkinRegistry::Folder& skinFolder = *GetRainmeter().m_SkinRegistry.FindFolder(skinName);
for (int i = 0, isize = (int)skinFolder.files.size(); i < isize; ++i)
{
InsertMenu(variantsMenu, i, MF_BYPOSITION, skinFolder.baseID + i, skinFolder.files[i].c_str());
}
if (skinFolder.active)
{
UINT checkPos = skinFolder.active - 1;
CheckMenuRadioItem(variantsMenu, checkPos, checkPos, checkPos, MF_BYPOSITION);
}
}
// Add skin root menu
int itemCount = GetMenuItemCount(menu);
if (itemCount > 0)
{
std::wstring root = meterWindow->GetFolderPath();
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)
{
const UINT state = GetMenuState(menu, i, MF_BYPOSITION);
if (state == 0xFFFFFFFF || (state & MF_POPUP) == 0) break;
WCHAR buffer[MAX_PATH];
if (GetMenuString(menu, i, buffer, MAX_PATH, MF_BYPOSITION))
{
if (_wcsicmp(root.c_str(), buffer) == 0)
{
HMENU skinRootMenu = GetSubMenu(menu, i);
if (skinRootMenu)
{
InsertMenu(skinMenu, 3, MF_BYPOSITION | MF_POPUP, (UINT_PTR)skinRootMenu, root.c_str());
}
break;
}
}
}
}
AppendSkinCustomMenu(meterWindow, index, skinMenu, false);
return skinMenu;
}
void ContextMenu::AppendSkinCustomMenu(
MeterWindow* meterWindow, int index, HMENU menu, bool standaloneMenu)
{
// Add custom actions to the context menu
std::wstring contextTitle = meterWindow->GetParser().ReadString(L"Rainmeter", L"ContextTitle", L"");
if (contextTitle.empty())
{
return;
}
auto isTitleSeparator = [](const std::wstring& title)
{
return title.find_first_not_of(L'-') == std::wstring::npos;
};
std::wstring contextAction = meterWindow->GetParser().ReadString(L"Rainmeter", L"ContextAction", L"");
if (contextAction.empty() && !isTitleSeparator(contextTitle))
{
return;
}
std::vector<std::wstring> cTitles;
WCHAR buffer[128];
int i = 1;
while (!contextTitle.empty() &&
(!contextAction.empty() || isTitleSeparator(contextTitle)) &&
(IDM_SKIN_CUSTOMCONTEXTMENU_FIRST + i - 1) <= IDM_SKIN_CUSTOMCONTEXTMENU_LAST) // Set maximum context items in resource.h
{
// Trim long titles
if (contextTitle.size() > 30)
{
contextTitle.replace(27, contextTitle.size() - 27, L"...");
}
cTitles.push_back(contextTitle);
_snwprintf_s(buffer, _TRUNCATE, L"ContextTitle%i", ++i);
contextTitle = meterWindow->GetParser().ReadString(L"Rainmeter", buffer, L"");
_snwprintf_s(buffer, _TRUNCATE, L"ContextAction%i", i);
contextAction = meterWindow->GetParser().ReadString(L"Rainmeter", buffer, L"");
}
// Build a sub-menu if more than three items
const size_t titleSize = cTitles.size();
if (titleSize <= 3 || standaloneMenu)
{
size_t position = 0;
for (size_t i = 0; i < titleSize; ++i)
{
if (isTitleSeparator(cTitles[i]))
{
if (standaloneMenu)
{
AppendMenu(menu, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
}
else
{
// Separators not allowed in main top-level menu
--position;
}
}
else
{
const UINT_PTR id = (index << 16) | (IDM_SKIN_CUSTOMCONTEXTMENU_FIRST + i);
InsertMenu(menu, (UINT)(position + 1), MF_BYPOSITION | MF_STRING, id, cTitles[i].c_str());
}
++position;
}
if (position != 0 && !standaloneMenu)
{
InsertMenu(menu, 1, MF_BYPOSITION | MF_STRING | MF_GRAYED, 0, L"Custom skin actions");
InsertMenu(menu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
}
}
else
{
HMENU customMenu = CreatePopupMenu();
InsertMenu(menu, 1, MF_BYPOSITION | MF_POPUP, (UINT_PTR)customMenu, L"Custom skin actions");
for (size_t i = 0; i < titleSize; ++i)
{
if (isTitleSeparator(cTitles[i]))
{
AppendMenu(customMenu, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
}
else
{
const UINT_PTR id = (index << 16) | (IDM_SKIN_CUSTOMCONTEXTMENU_FIRST + i);
AppendMenu(customMenu, MF_BYPOSITION | MF_STRING, id, cTitles[i].c_str());
}
}
InsertMenu(menu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
}
}
int ContextMenu::CreateAllSkinsMenuRecursive(HMENU skinMenu, int index)
{
SkinRegistry& skinRegistry = GetRainmeter().m_SkinRegistry;
const int initialLevel = skinRegistry.GetFolder(index).level;
int menuIndex = 0;
const size_t max = skinRegistry.GetFolderCount();
while (index < max)
{
const SkinRegistry::Folder& skinFolder = skinRegistry.GetFolder(index);
if (skinFolder.level != initialLevel)
{
return index - 1;
}
HMENU subMenu = CreatePopupMenu();
// Add current folder
InsertMenu(skinMenu, menuIndex, MF_POPUP | MF_BYPOSITION, (UINT_PTR)subMenu, skinFolder.name.c_str());
// Add subfolders
const bool hasSubfolder = (index + 1) < max && skinRegistry.GetFolder(index + 1).level == initialLevel + 1;
if (hasSubfolder)
{
index = CreateAllSkinsMenuRecursive(subMenu, index + 1);
}
// Add files
{
int fileIndex = 0;
const int fileCount = (int)skinFolder.files.size();
for ( ; fileIndex < fileCount; ++fileIndex)
{
InsertMenu(subMenu, fileIndex, MF_STRING | MF_BYPOSITION, skinFolder.baseID + fileIndex, skinFolder.files[fileIndex].c_str());
}
if (skinFolder.active)
{
UINT checkPos = skinFolder.active - 1;
CheckMenuRadioItem(subMenu, checkPos, checkPos, checkPos, MF_BYPOSITION);
}
if (hasSubfolder && fileIndex != 0)
{
InsertMenu(subMenu, fileIndex, MF_SEPARATOR | MF_BYPOSITION, 0, nullptr);
}
}
++menuIndex;
++index;
}
return index;
}
void ContextMenu::CreateLayoutMenu(HMENU layoutMenu)
{
const auto& layouts = GetRainmeter().m_Layouts;
for (size_t i = 0, isize = layouts.size(); i < isize; ++i)
{
InsertMenu(layoutMenu, (UINT)i, MF_BYPOSITION, ID_THEME_FIRST + i, layouts[i].c_str());
}
}
void ContextMenu::CreateMonitorMenu(HMENU monitorMenu, MeterWindow* meterWindow)
{
const bool screenDefined = meterWindow->GetXScreenDefined();
const int screenIndex = meterWindow->GetXScreen();
// for the "Specified monitor" (@n)
const size_t numOfMonitors = System::GetMonitorCount(); // intentional
const std::vector<MonitorInfo>& monitors = System::GetMultiMonitorInfo().monitors;
int i = 1;
for (auto iter = monitors.cbegin(); iter != monitors.cend(); ++iter, ++i)
{
WCHAR buffer[64];
size_t len = _snwprintf_s(buffer, _TRUNCATE, L"@%i: ", i);
std::wstring item(buffer, len);
if ((*iter).monitorName.size() > 32)
{
item.append((*iter).monitorName, 0, 32);
item += L"...";
}
else
{
item += (*iter).monitorName;
}
const UINT flags =
MF_BYPOSITION |
((screenDefined && screenIndex == i) ? MF_CHECKED : MF_UNCHECKED) |
((*iter).active ? MF_ENABLED : MF_GRAYED);
InsertMenu(monitorMenu, i + 2, flags, ID_MONITOR_FIRST + i, item.c_str());
}
if (!screenDefined)
{
CheckMenuItem(monitorMenu, IDM_SKIN_MONITOR_PRIMARY, MF_BYCOMMAND | MF_CHECKED);
}
if (screenDefined && screenIndex == 0)
{
CheckMenuItem(monitorMenu, ID_MONITOR_FIRST, MF_BYCOMMAND | MF_CHECKED);
}
if (meterWindow->GetAutoSelectScreen())
{
CheckMenuItem(monitorMenu, IDM_SKIN_MONITOR_AUTOSELECT, MF_BYCOMMAND | MF_CHECKED);
}
}
void ContextMenu::ChangeSkinIndex(HMENU menu, int index)
{
if (index > 0)
{
const int count = GetMenuItemCount(menu);
for (int i = 0; i < count; ++i)
{
HMENU subMenu = GetSubMenu(menu, i);
if (subMenu)
{
ChangeSkinIndex(subMenu, index);
}
else
{
MENUITEMINFO mii = {sizeof(MENUITEMINFO)};
mii.fMask = MIIM_FTYPE | MIIM_ID;
GetMenuItemInfo(menu, i, TRUE, &mii);
if ((mii.fType & MFT_SEPARATOR) == 0)
{
mii.wID |= (index << 16);
mii.fMask = MIIM_ID;
SetMenuItemInfo(menu, i, TRUE, &mii);
}
}
}
}
}

View File

@ -1,58 +0,0 @@
/*
Copyright (C) 2013 Rainmeter Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef RM_LIBRARY_CONTEXTMENU_H
#define RM_LIBRARY_CONTEXTMENU_H
#include <Windows.h>
class MeterWindow;
// Handles the creation and display of Rainmeter and skin context menus.
class ContextMenu
{
public:
ContextMenu();
ContextMenu(const ContextMenu& other) = delete;
ContextMenu& operator=(ContextMenu other) = delete;
bool IsMenuActive() { return m_MenuActive; }
void ShowMenu(POINT pos, MeterWindow* meterWindow);
void ShowSkinCustomMenu(POINT pos, MeterWindow* meterWindow);
static void CreateMonitorMenu(HMENU monitorMenu, MeterWindow* meterWindow);
private:
static void DisplayMenu(POINT pos, HMENU menu, HWND parentWindow);
static HMENU CreateSkinMenu(MeterWindow* meterWindow, int index, HMENU menu);
static void AppendSkinCustomMenu(
MeterWindow* meterWindow, int index, HMENU menu, bool standaloneMenu);
static void ChangeSkinIndex(HMENU subMenu, int index);
static void CreateAllSkinsMenu(HMENU skinMenu) { CreateAllSkinsMenuRecursive(skinMenu, 0); }
static int CreateAllSkinsMenuRecursive(HMENU skinMenu, int index);
static void CreateLayoutMenu(HMENU layoutMenu);
bool m_MenuActive;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,182 +0,0 @@
/*
Copyright (C) 2011 Birunthan Mohanathas
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __DIALOGABOUT_H__
#define __DIALOGABOUT_H__
#include "../Common/Dialog.h"
#include "Logger.h"
#include "MeterWindow.h"
class DialogAbout : public Dialog
{
public:
DialogAbout();
virtual ~DialogAbout();
DialogAbout(const DialogAbout& other) = delete;
DialogAbout& operator=(DialogAbout other) = delete;
static Dialog* GetDialog() { return c_Dialog; }
static void Open(int tab = 0);
static void Open(const WCHAR* name);
static void ShowAboutLog();
static void AddLogItem(Logger::Level level, LPCWSTR time, LPCWSTR source, LPCWSTR message);
static void UpdateSkins();
static void UpdateMeasures(MeterWindow* meterWindow);
protected:
virtual INT_PTR HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR OnInitDialog(WPARAM wParam, LPARAM lParam);
INT_PTR OnNotify(WPARAM wParam, LPARAM lParam);
INT_PTR OnCommand(WPARAM wParam, LPARAM lParam);
private:
// Log tab
class TabLog : public Tab
{
public:
enum Id
{
Id_ItemsListView = 100,
Id_ErrorCheckBox,
Id_WarningCheckBox,
Id_NoticeCheckBox,
Id_DebugCheckBox,
Id_ClearButton
};
TabLog();
void Create(HWND owner);
virtual void Initialize();
virtual void Resize(int w, int h);
void AddItem(Logger::Level level, LPCWSTR time, LPCWSTR source, LPCWSTR message);
protected:
virtual INT_PTR HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR OnCommand(WPARAM wParam, LPARAM lParam);
INT_PTR OnNotify(WPARAM wParam, LPARAM lParam);
private:
bool m_Error;
bool m_Warning;
bool m_Notice;
bool m_Debug;
};
// Measures tab
class TabSkins : public Tab
{
public:
enum Id
{
Id_SkinsListBox = 100,
Id_ItemsListView
};
TabSkins();
void Create(HWND owner);
virtual void Initialize();
virtual void Resize(int w, int h);
void UpdateSkinList();
void UpdateMeasureList(MeterWindow* meterWindow);
protected:
virtual INT_PTR HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR OnCommand(WPARAM wParam, LPARAM lParam);
INT_PTR OnNotify(WPARAM wParam, LPARAM lParam);
private:
static int CALLBACK ListSortProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
MeterWindow* m_SkinWindow;
};
// Plugins tab
class TabPlugins : public Tab
{
public:
enum Id
{
Id_ItemsListView = 100
};
TabPlugins();
void Create(HWND owner);
virtual void Initialize();
virtual void Resize(int w, int h);
private:
typedef LPCTSTR (*GETPLUGINAUTHOR)();
typedef UINT (*GETPLUGINVERSION)();
};
// Version tab
class TabVersion : public Tab
{
public:
enum Id
{
Id_AppIcon = 100,
Id_VersionLabel,
Id_HomeLink,
Id_LicenseLink,
Id_WinVerLabel,
Id_PathLabel,
Id_IniFileLabel,
Id_SkinPathLabel,
Id_CopyButton
};
TabVersion();
void Create(HWND owner);
virtual void Initialize();
virtual void Resize(int w, int h);
protected:
virtual INT_PTR HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR OnNotify(WPARAM wParam, LPARAM lParam);
INT_PTR OnCommand(WPARAM wParam, LPARAM lParam);
};
enum Id
{
Id_CloseButton = IDCLOSE,
Id_Tab = 100
};
Tab& GetActiveTab();
TabLog m_TabLog;
TabSkins m_TabSkins;
TabPlugins m_TabPlugins;
TabVersion m_TabVersion;
static WINDOWPLACEMENT c_WindowPlacement;
static DialogAbout* c_Dialog;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,193 +0,0 @@
/*
Copyright (C) 2011 Birunthan Mohanathas
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __DIALOGMANAGE_H__
#define __DIALOGMANAGE_H__
#include "../Common/Dialog.h"
#include "resource.h"
class DialogManage : public Dialog
{
public:
DialogManage();
virtual ~DialogManage();
DialogManage(const DialogManage& other) = delete;
DialogManage& operator=(DialogManage other) = delete;
static Dialog* GetDialog() { return c_Dialog; }
static void Open(const WCHAR* tabName, const WCHAR* param1, const WCHAR* param2);
static void Open(const WCHAR* name);
static void Open(int tab = 0);
static void OpenSkin(MeterWindow* meterWindow);
static void UpdateSkins(MeterWindow* meterWindow, bool deleted = false);
static void UpdateLayouts();
protected:
virtual INT_PTR HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR OnInitDialog(WPARAM wParam, LPARAM lParam);
INT_PTR OnNotify(WPARAM wParam, LPARAM lParam);
INT_PTR OnCommand(WPARAM wParam, LPARAM lParam);
private:
// Skins tab
class TabSkins : public Tab
{
public:
enum Id
{
Id_ActiveSkinsButton = 100,
Id_SkinsTreeView,
Id_CreateSkinPackageButton,
Id_FileLabel,
Id_ConfigLabel,
Id_AuthorLabel,
Id_VersionLabel,
Id_LicenseLabel,
Id_DescriptionLabel,
Id_AddMetadataLink,
Id_XPositionEdit,
Id_YPositionEdit,
Id_ZPositionDropDownList,
Id_LoadOrderEdit,
Id_OnHoverDropDownList,
Id_TransparencyDropDownList,
Id_DisplayMonitorButton,
Id_DraggableCheckBox,
Id_ClickThroughCheckBox,
Id_KeepOnScreenCheckBox,
Id_SavePositionCheckBox,
Id_SnapToEdgesCheckBox,
Id_LoadButton = IDM_MANAGESKINSMENU_LOAD,
Id_RefreshButton = IDM_MANAGESKINSMENU_REFRESH,
Id_EditButton = IDM_MANAGESKINSMENU_EDIT
};
TabSkins();
void Create(HWND owner);
virtual void Initialize();
void Update(MeterWindow* meterWindow, bool deleted);
static void SelectTreeItem(HWND tree, HTREEITEM item, LPCWSTR name);
protected:
virtual INT_PTR HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR OnNotify(WPARAM wParam, LPARAM lParam);
INT_PTR OnCommand(WPARAM wParam, LPARAM lParam);
private:
void SetControls();
void DisableControls(bool clear = false);
void ReadSkin();
static std::wstring GetTreeSelectionPath(HWND tree);
static int PopulateTree(HWND tree, TVINSERTSTRUCT& tvi, int index = 0);
std::wstring m_SkinFileName;
std::wstring m_SkinFolderPath;
MeterWindow* m_SkinWindow;
bool m_HandleCommands;
bool m_IgnoreUpdate;
};
// Layouts tab
class TabLayouts : public Tab
{
public:
enum Id
{
Id_List = 100,
Id_LoadButton,
Id_DeleteButton,
Id_EditButton,
Id_SaveButton,
Id_SaveEmptyThemeCheckBox,
Id_ExcludeUnusedSkinsCheckBox,
Id_IncludeWallpaperCheckBox,
Id_NameLabel
};
TabLayouts();
void Create(HWND owner);
virtual void Initialize();
void Update();
protected:
virtual INT_PTR HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR OnCommand(WPARAM wParam, LPARAM lParam);
};
// Settings tab
class TabSettings : public Tab
{
public:
enum Id
{
Id_CheckForUpdatesCheckBox = 100,
Id_LockSkinsCheckBox,
Id_ResetStatisticsButton,
Id_LogToFileCheckBox,
Id_VerboseLoggingCheckbox,
Id_ShowLogFileButton,
Id_DeleteLogFileButton,
Id_LanguageDropDownList,
Id_EditorEdit,
Id_EditorBrowseButton,
Id_ShowTrayIconCheckBox,
Id_UseD2DCheckBox
};
TabSettings();
void Create(HWND owner);
virtual void Initialize();
protected:
virtual INT_PTR HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR OnCommand(WPARAM wParam, LPARAM lParam);
};
enum Id
{
Id_CloseButton = IDCLOSE,
Id_Tab = 100,
Id_RefreshAllButton,
Id_EditSettingsButton,
Id_OpenLogButton,
Id_HelpButton
};
Tab& GetActiveTab();
TabSkins m_TabSkins;
TabLayouts m_TabLayouts;
TabSettings m_TabSettings;
static WINDOWPLACEMENT c_WindowPlacement;
static DialogManage* c_Dialog;
};
#endif

View File

@ -1,3 +1,13 @@
#pragma once
#define EXPORT extern "C" _declspec(dllexport)
namespace Results {
enum CallResult
{
Ok = 0,
InvalidHandle = 1
};
}

View File

@ -4,29 +4,29 @@
#include "HandleManager.h"
#include "Exports_Common.h"
EXPORT bool Group_BelongsToGroup (bool* result, int32_t handle, LPWSTR str)
EXPORT int Group_BelongsToGroup(bool* result, int32_t handle, LPWSTR str)
{
Group* group = (Group*)handle_get_resource (handle);
Group* group = (Group*) handle_get_resource(handle);
if (group != nullptr)
{
*result = group->BelongsToGroup (str);
return true;
*result = group->BelongsToGroup(str);
return Results::Ok;
}
return false;
return Results::InvalidHandle;
}
EXPORT bool Group_Destroy (int32_t handle)
EXPORT int Group_Destroy(int32_t handle)
{
Group* group = (Group*)handle_get_resource (handle);
Group* group = (Group*) handle_get_resource(handle);
if (group != nullptr)
{
handle_free (handle);
handle_free(handle);
delete group;
return true;
return Results::Ok;
}
return false;
return Results::InvalidHandle;
}

View File

@ -4,18 +4,16 @@
#include "HandleManager.h"
#include "Exports_Common.h"
EXPORT bool Meter_Destroy (int handle)
EXPORT int Meter_Destroy(int handle)
{
Meter* meter = (Meter*)handle_get_resource (handle);
Meter* meter = (Meter*) handle_get_resource(handle);
if (meter != nullptr)
{
handle_free (handle);
handle_free(handle);
delete meter;
return true;
return Results::Ok;
}
return false;
return Results::InvalidHandle;
}

View File

@ -4,32 +4,32 @@
#include "HandleManager.h"
#include "Exports_Common.h"
EXPORT bool MeterString_Init (int* handle_result, int meterCanvasHandle, LPCWSTR name)
EXPORT int MeterString_Init(int* handle_result, int meterCanvasHandle, LPCWSTR name)
{
MeterWindow* w = (MeterWindow*) handle_get_resource (meterCanvasHandle);
MeterWindow* w = (MeterWindow*) handle_get_resource(meterCanvasHandle);
if (w != nullptr)
{
MeterString* result = new MeterString (w, name);
*handle_result = handle_allocate (result);
MeterString* result = new MeterString(w, name);
*handle_result = handle_allocate(result);
return true;
return Results::Ok;
}
return false;
return Results::InvalidHandle;
}
EXPORT bool MeterString_Destroy (int handle)
EXPORT int MeterString_Destroy(int handle)
{
MeterString* ms = (MeterString*) handle_get_resource (handle);
MeterString* ms = (MeterString*) handle_get_resource(handle);
if (ms != nullptr)
{
handle_free (handle);
handle_free(handle);
delete ms;
return true;
return Results::Ok;
}
return false;
return Results::InvalidHandle;
}

View File

@ -7,7 +7,7 @@
*/
bool Rainmeter_Initialize()
{
int res = GetRainmeter().Initialize(nullptr, nullptr);
int res = GetRainmeter().Initialize();
// Success?
if (res == 0)
@ -22,6 +22,6 @@ bool Rainmeter_Initialize()
*/
void Rainmeter_Finalize(void* ptr)
{
Rainmeter* rainmeter = (Rainmeter*)ptr;
Rainmeter* rainmeter = (Rainmeter*) ptr;
rainmeter->Finalize();
}

View File

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

View File

@ -34,10 +34,12 @@
<ClCompile Include="ConfigParser_Test.cpp">
<ExcludedFromBuild>$(ExcludeTests)</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="ContextMenu.cpp" />
<ClCompile Include="DialogAbout.cpp" />
<ClCompile Include="DialogManage.cpp" />
<ClCompile Include="Exports_Meter.cpp" />
<ClCompile Include="Exports_MeterString.cpp" />
<ClCompile Include="Exports_Rainmeter.cpp" />
<ClCompile Include="Group.cpp" />
<ClCompile Include="Exports_Group.cpp" />
<ClCompile Include="HandleManager.cpp" />
<ClCompile Include="IfActions.cpp" />
<ClCompile Include="Litestep.cpp" />
<ClCompile Include="Logger.cpp" />
@ -73,17 +75,11 @@
<ClCompile Include="Rainmeter.cpp" />
<ClCompile Include="Export.cpp" />
<ClCompile Include="Section.cpp" />
<ClCompile Include="SkinRegistry.cpp" />
<ClCompile Include="SkinRegistry_Test.cpp">
<ExcludedFromBuild>$(ExcludeTests)</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="StdAfx.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="System.cpp" />
<ClCompile Include="TintedImage.cpp" />
<ClCompile Include="TrayWindow.cpp" />
<ClCompile Include="UpdateCheck.cpp" />
<ClCompile Include="lua\LuaManager.cpp" />
<ClCompile Include="lua\LuaScript.cpp" />
<ClCompile Include="lua\glue\LuaMeasure.cpp" />
@ -92,18 +88,21 @@
<ClCompile Include="lua\glue\LuaGlobal.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\Language\Language.rc" />
<ResourceCompile Include="Library.rc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="CommandHandler.h" />
<ClInclude Include="ConfigParser.h" />
<ClInclude Include="ContextMenu.h" />
<ClInclude Include="DialogAbout.h" />
<ClInclude Include="Error.h" />
<ClInclude Include="Exports_Common.h" />
<ClCompile Include="Exports_Section.cpp">
<FileType>CppHeader</FileType>
</ClCompile>
<ClInclude Include="Group.h" />
<ClInclude Include="HandleManager.h" />
<ClInclude Include="IfActions.h" />
<ClInclude Include="Litestep.h" />
<ClInclude Include="DialogManage.h" />
<ClInclude Include="Logger.h" />
<ClInclude Include="Measure.h" />
<ClInclude Include="MeasureCalc.h" />
@ -139,12 +138,9 @@
<ClInclude Include="RainmeterQuery.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="Section.h" />
<ClInclude Include="SkinRegistry.h" />
<ClInclude Include="StdAfx.h" />
<ClInclude Include="System.h" />
<ClInclude Include="TintedImage.h" />
<ClInclude Include="TrayWindow.h" />
<ClInclude Include="UpdateCheck.h" />
<ClInclude Include="lua\LuaManager.h" />
<ClInclude Include="lua\LuaScript.h" />
</ItemGroup>

View File

@ -19,6 +19,12 @@
<Filter Include="Lua\glue">
<UniqueIdentifier>{941dce28-a314-4492-befb-5770432c98bf}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Exports">
<UniqueIdentifier>{86873eb6-7daf-4cde-b957-2c1bfc5aa066}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Exports">
<UniqueIdentifier>{2bd33bb1-d45c-4072-9ef2-cfa77bbf82df}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ConfigParser.cpp">
@ -126,12 +132,6 @@
<ClCompile Include="TintedImage.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TrayWindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UpdateCheck.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="lua\LuaManager.cpp">
<Filter>Lua</Filter>
</ClCompile>
@ -150,12 +150,6 @@
<ClCompile Include="lua\glue\LuaGlobal.cpp">
<Filter>Lua\glue</Filter>
</ClCompile>
<ClCompile Include="DialogAbout.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DialogManage.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Export.cpp">
<Filter>Source Files</Filter>
</ClCompile>
@ -171,21 +165,30 @@
<ClCompile Include="CommandHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SkinRegistry.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SkinRegistry_Test.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ContextMenu.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="IfActions.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="MeasureString.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="HandleManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Exports_Group.cpp">
<Filter>Source Files\Exports</Filter>
</ClCompile>
<ClCompile Include="Exports_Section.cpp">
<Filter>Source Files\Exports</Filter>
</ClCompile>
<ClCompile Include="Exports_Meter.cpp">
<Filter>Source Files\Exports</Filter>
</ClCompile>
<ClCompile Include="Exports_MeterString.cpp">
<Filter>Source Files\Exports</Filter>
</ClCompile>
<ClCompile Include="Exports_Rainmeter.cpp">
<Filter>Source Files\Exports</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ConfigParser.h">
@ -299,24 +302,12 @@
<ClInclude Include="TintedImage.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TrayWindow.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UpdateCheck.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="lua\LuaManager.h">
<Filter>Lua</Filter>
</ClInclude>
<ClInclude Include="lua\LuaScript.h">
<Filter>Lua</Filter>
</ClInclude>
<ClInclude Include="DialogAbout.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DialogManage.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Export.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -332,23 +323,26 @@
<ClInclude Include="CommandHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SkinRegistry.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ContextMenu.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IfActions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="MeasureString.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HandleManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Exports_Common.h">
<Filter>Header Files\Exports</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Library.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
<ResourceCompile Include="..\Language\Language.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<None Include="Exports.def">

View File

@ -31,7 +31,7 @@ UINT GetUniqueID()
WCHAR* GetString(UINT id)
{
LPWSTR pData;
int len = LoadString(GetRainmeter().GetResourceInstance(), id, (LPWSTR)&pData, 0);
int len = LoadString(GetRainmeter().GetModuleInstance(), id, (LPWSTR)&pData, 0);
return len ? pData : L"";
}

View File

@ -33,7 +33,7 @@ const size_t MAX_LOG_ENTIRES = 20;
} // namespace
Logger::Logger() :
m_LogToFile(false)
m_LoggerCallback (nullptr)
{
System::InitializeCriticalSection(&m_CsLog);
System::InitializeCriticalSection(&m_CsLogDelay);
@ -51,56 +51,6 @@ Logger& Logger::GetInstance()
return s_Logger;
}
void Logger::StartLogFile()
{
const WCHAR* filePath = m_LogFilePath.c_str();
if (_waccess(filePath, 0) == -1)
{
// Create empty log file.
HANDLE file = CreateFile(filePath, GENERIC_WRITE, 0, nullptr, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, nullptr);
if (file != INVALID_HANDLE_VALUE)
{
CloseHandle(file);
}
else
{
const std::wstring text = GetFormattedString(ID_STR_LOGFILECREATEFAIL, filePath);
GetRainmeter().ShowMessage(nullptr, text.c_str(), MB_OK | MB_ICONERROR);
SetLogToFile(false);
return;
}
}
SetLogToFile(true);
}
void Logger::StopLogFile()
{
SetLogToFile(false);
}
void Logger::DeleteLogFile()
{
const WCHAR* filePath = m_LogFilePath.c_str();
if (_waccess(filePath, 0) != -1)
{
const std::wstring text = GetFormattedString(ID_STR_LOGFILEDELETE, filePath);
const int res = GetRainmeter().ShowMessage(nullptr, text.c_str(), MB_YESNO | MB_ICONQUESTION);
if (res == IDYES)
{
SetLogToFile(false);
System::RemoveFile(m_LogFilePath);
}
}
}
void Logger::SetLogToFile(bool logToFile)
{
m_LogToFile = logToFile;
WritePrivateProfileString(
L"Rainmeter", L"Logging", logToFile ? L"1" : L"0", GetRainmeter().GetIniFile().c_str());
}
void Logger::LogInternal(Level level, ULONGLONG timestamp, const WCHAR* source, const WCHAR* msg)
{
WCHAR timestampSz[128];
@ -121,15 +71,11 @@ void Logger::LogInternal(Level level, ULONGLONG timestamp, const WCHAR* source,
m_Entries.pop_front();
}
DialogAbout::AddLogItem(level, timestampSz, source, msg);
WriteToLogFile(entry);
}
// Call callback function
if (m_LoggerCallback != nullptr)
(*m_LoggerCallback)(entry.level, entry.timestamp.c_str(), source, msg);
void Logger::WriteToLogFile(Entry& entry)
{
#ifndef _DEBUG
if (!m_LogToFile) return;
#endif
#ifdef _DEBUG
const WCHAR* levelSz =
(entry.level == Level::Error) ? L"ERRO" :
@ -146,26 +92,9 @@ void Logger::WriteToLogFile(Entry& entry)
message += entry.message;
message += L'\n';
#ifdef _DEBUG
_RPTW0(_CRT_WARN, message.c_str());
if (!m_LogToFile) return;
#endif
OutputDebugStringW (message.c_str ());
const WCHAR* filePath = m_LogFilePath.c_str();
if (_waccess(filePath, 0) == -1)
{
// The file has been deleted manually.
StopLogFile();
}
else
{
FILE* file = _wfopen(filePath, L"a+, ccs=UTF-8");
if (file)
{
fputws(message.c_str(), file);
fclose(file);
}
}
#endif
}
void Logger::Log(Level level, const WCHAR* source, const WCHAR* msg)

View File

@ -49,14 +49,9 @@ public:
static Logger& GetInstance();
void SetLogFilePath(std::wstring path) { m_LogFilePath = path; }
typedef void (*LoggerCallback) (Level level, LPCWSTR timestamp, LPCWSTR source, LPCWSTR message);
void StartLogFile();
void StopLogFile();
void DeleteLogFile();
bool IsLogToFile() { return m_LogToFile; }
void SetLogToFile(bool logToFile);
void SetLogCallback(LoggerCallback callback) { m_LoggerCallback = callback; }
void Log(Level level, const WCHAR* source, const WCHAR* msg);
void LogVF(Level level, const WCHAR* source, const WCHAR* format, va_list args);
@ -64,16 +59,11 @@ public:
void LogSection(Logger::Level level, Section* section, const WCHAR* message);
void LogSectionVF(Logger::Level level, Section* section, const WCHAR* format, va_list args);
const std::wstring& GetLogFilePath() { return m_LogFilePath; }
const std::list<Entry>& GetEntries() { return m_Entries; }
private:
void LogInternal(Level level, ULONGLONG timestamp, const WCHAR* source, const WCHAR* msg);
// Appends |entry| to the log file.
void WriteToLogFile(Entry& entry);
Logger();
~Logger();
@ -81,7 +71,7 @@ private:
Logger& operator=(Logger other) = delete;
bool m_LogToFile;
std::wstring m_LogFilePath;
LoggerCallback m_LoggerCallback;
std::list<Entry> m_Entries;

View File

@ -19,13 +19,10 @@
#include "StdAfx.h"
#include "MeterWindow.h"
#include "Rainmeter.h"
#include "TrayWindow.h"
#include "System.h"
#include "Error.h"
#include "Meter.h"
#include "Measure.h"
#include "DialogAbout.h"
#include "DialogManage.h"
#include "resource.h"
#include "Litestep.h"
#include "MeasureCalc.h"
@ -414,7 +411,7 @@ void MeterWindow::Refresh(bool init, bool all)
if (!ReadSkin())
{
GetRainmeter().DeactivateSkin(this, -1);
GetRainmeter().DeactivateSkin(this);
return;
}
@ -798,7 +795,7 @@ void MeterWindow::DoBang(Bang bang, const std::vector<std::wstring>& args)
case Bang::UpdateMeasure:
UpdateMeasure(args[0]);
DialogAbout::UpdateMeasures(this);
// TODO: update measure callback
break;
case Bang::DisableMeasureGroup:
@ -827,7 +824,7 @@ void MeterWindow::DoBang(Bang bang, const std::vector<std::wstring>& args)
case Bang::UpdateMeasureGroup:
UpdateMeasure(args[0], true);
DialogAbout::UpdateMeasures(this);
// DialogAbout::UpdateMeasures(this);
break;
case Bang::Show:
@ -1880,7 +1877,7 @@ void MeterWindow::ScreenToWindow()
*/
void MeterWindow::ReadOptions()
{
WCHAR buffer[32];
/*WCHAR buffer[32];
const WCHAR* section = m_FolderPath.c_str();
ConfigParser parser;
@ -1953,7 +1950,7 @@ void MeterWindow::ReadOptions()
}
// Set WindowXScreen/WindowYScreen temporarily
WindowToScreen();
WindowToScreen();*/
}
/*
@ -1962,7 +1959,7 @@ void MeterWindow::ReadOptions()
*/
void MeterWindow::WriteOptions(INT setting)
{
const WCHAR* iniFile = GetRainmeter().GetIniFile().c_str();
/*const WCHAR* iniFile = GetRainmeter().GetIniFile().c_str();
if (*iniFile)
{
@ -1971,7 +1968,7 @@ void MeterWindow::WriteOptions(INT setting)
if (setting != OPTION_ALL)
{
DialogManage::UpdateSkins(this);
//DialogManage::UpdateSkins(this);
}
if (setting & OPTION_POSITION)
@ -2046,7 +2043,7 @@ void MeterWindow::WriteOptions(INT setting)
{
WritePrivateProfileString(section, L"UseD2D", m_UseD2D ? L"1" : L"0", iniFile);
}
}
}*/
}
/*
@ -2063,7 +2060,7 @@ bool MeterWindow::ReadSkin()
if (_waccess(iniFile.c_str(), 0) == -1)
{
std::wstring message = GetFormattedString(ID_STR_UNABLETOREFRESHSKIN, m_FolderPath.c_str(), m_FileName.c_str());
GetRainmeter().ShowMessage(m_Window, message.c_str(), MB_OK | MB_ICONEXCLAMATION);
// unsupported: GetRainmeter().ShowMessage(m_Window, message.c_str(), MB_OK | MB_ICONEXCLAMATION);
return false;
}
@ -2095,8 +2092,7 @@ bool MeterWindow::ReadSkin()
_snwprintf_s(buffer, _TRUNCATE, L"%u.%u", appVersion / 1000000, (appVersion / 1000) % 1000);
}
std::wstring text = GetFormattedString(ID_STR_NEWVERSIONREQUIRED, m_FolderPath.c_str(), m_FileName.c_str(), buffer);
GetRainmeter().ShowMessage(m_Window, text.c_str(), MB_OK | MB_ICONEXCLAMATION);
// TODO: throw error or something
return false;
}
@ -2234,7 +2230,7 @@ bool MeterWindow::ReadSkin()
do
{
// Try program folder first
std::wstring szFontFile = GetRainmeter().GetPath() + L"Fonts\\";
std::wstring szFontFile = GetRainmeter().GetWorkDirectory() + L"Fonts\\";
szFontFile += localFont;
if (!m_FontCollection->AddFile(szFontFile.c_str()))
{
@ -2310,7 +2306,7 @@ bool MeterWindow::ReadSkin()
if (m_Meters.empty())
{
std::wstring text = GetFormattedString(ID_STR_NOMETERSINSKIN, m_FolderPath.c_str(), m_FileName.c_str());
GetRainmeter().ShowMessage(m_Window, text.c_str(), MB_OK | MB_ICONEXCLAMATION);
// Unsupported: GetRainmeter().ShowMessage(m_Window, text.c_str(), MB_OK | MB_ICONEXCLAMATION);
return false;
}
@ -2767,7 +2763,7 @@ void MeterWindow::Update(bool refresh)
}
}
DialogAbout::UpdateMeasures(this);
// TODO: call update measures callback
// Update all meters
bool bActiveTransition = false;
@ -2792,12 +2788,7 @@ void MeterWindow::Update(bool refresh)
SetResizeWindowMode(RESIZEMODE_CHECK);
}
// If our option is to disable when in an RDP session, then check if in an RDP session.
// Only redraw if we are not in a remote session
if (GetRainmeter().IsRedrawable())
{
Redraw();
}
Redraw();
}
// Post-updates
@ -3391,22 +3382,10 @@ LRESULT MeterWindow::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (wParam)
{
case IDM_SKIN_EDITSKIN:
GetRainmeter().EditSkinFile(m_FolderPath, m_FileName);
break;
case IDM_SKIN_REFRESH:
Refresh(false);
break;
case IDM_SKIN_OPENSKINSFOLDER:
GetRainmeter().OpenSkinFolder(m_FolderPath);
break;
case IDM_SKIN_MANAGESKIN:
DialogManage::OpenSkin(this);
break;
case IDM_SKIN_VERYTOPMOST:
SetWindowZPosition(ZPOSITION_ONTOPMOST);
break;
@ -3466,7 +3445,7 @@ LRESULT MeterWindow::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam)
case IDM_CLOSESKIN:
if (m_State != STATE_CLOSING)
{
GetRainmeter().DeactivateSkin(this, -1);
GetRainmeter().DeactivateSkin(this);
}
break;
@ -3559,20 +3538,6 @@ LRESULT MeterWindow::OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam)
GetRainmeter().ExecuteCommand(action.c_str(), this);
}
}
else
{
// Forward to tray window, which handles all the other commands
HWND tray = GetRainmeter().GetTrayWindow()->GetWindow();
if (wParam == IDM_QUIT)
{
PostMessage(tray, WM_COMMAND, wParam, lParam);
}
else
{
SendMessage(tray, WM_COMMAND, wParam, lParam);
}
}
break;
}
@ -3667,7 +3632,7 @@ void MeterWindow::SavePositionIfAppropriate()
else
{
ScreenToWindow();
DialogManage::UpdateSkins(this);
// TODO: call update skins callback
}
}

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
*/
#ifndef __RAINMETER_H__
#define __RAINMETER_H__
@ -25,10 +25,9 @@
#include <list>
#include <string>
#include "CommandHandler.h"
#include "ContextMenu.h"
#include "Logger.h"
#include "MeterWindow.h"
#include "SkinRegistry.h"
#include "../Common/PathUtil.h"
#define MAX_LINE_LENGTH 4096
@ -56,14 +55,21 @@ struct GlobalOptions
};
class ConfigParser;
class TrayWindow;
class Rainmeter
{
public:
#pragma region Singleton
/// <brief>
/// Gets the instance
/// </brief>
static Rainmeter& GetInstance();
int Initialize(LPCWSTR iniPath, LPCWSTR layout);
#pragma endregion
int Initialize();
void Finalize();
int MessagePump();
@ -73,8 +79,6 @@ public:
ConfigParser* GetCurrentParser() { return m_CurrentParser; }
void SetCurrentParser(ConfigParser* parser) { m_CurrentParser = parser; }
TrayWindow* GetTrayWindow() { return m_TrayWindow; }
bool HasMeterWindow(const MeterWindow* meterWindow) const;
MeterWindow* GetMeterWindow(const std::wstring& folderPath);
@ -84,93 +88,60 @@ public:
void GetMeterWindowsByLoadOrder(std::multimap<int, MeterWindow*>& windows, const std::wstring& group = std::wstring());
std::map<std::wstring, MeterWindow*>& GetAllMeterWindows() { return m_MeterWindows; }
const std::vector<std::wstring>& GetAllLayouts() { return m_Layouts; }
void RemoveMeterWindow(MeterWindow* meterWindow);
void AddUnmanagedMeterWindow(MeterWindow* meterWindow);
void RemoveUnmanagedMeterWindow(MeterWindow* meterWindow);
bool ActivateSkin(const std::wstring& folderPath);
bool ActivateSkin(const std::wstring& folderPath, const std::wstring& file);
void ActivateSkin(int folderIndex, int fileIndex);
void DeactivateSkin(MeterWindow* meterWindow, int folderIndex, bool save = true);
void ToggleSkin(int folderIndex, int fileIndex);
void ActivateSkin(std::wstring file);
void DeactivateSkin(MeterWindow* meterWindow);
void ToggleSkin(std::wstring file);
void ToggleSkinWithID(UINT id);
const std::wstring& GetPath() { return m_Path; }
const std::wstring& GetIniFile() { return m_IniFile; }
const std::wstring& GetDataFile() { return m_DataFile; }
const std::wstring& GetSettingsPath() { return m_SettingsPath; }
const std::wstring& GetSkinPath() { return m_SkinPath; }
void SetSkinPath(const std::wstring& skinPath);
std::wstring GetLayoutPath() { return m_SettingsPath + L"Layouts\\"; }
std::wstring GetPluginPath() { return m_Path + L"Plugins\\"; }
std::wstring GetUserPluginPath() { return m_SettingsPath + L"Plugins\\"; }
std::wstring GetAddonPath() { return m_SettingsPath + L"Addons\\"; }
std::wstring GetWorkDirectory()
{
if (m_UseCurrentDirectory)
{
WCHAR buffer[MAX_PATH];
GetCurrentDirectoryW(MAX_PATH, buffer);
return buffer;
}
bool HasUserPluginPath() { return (_wcsicmp(m_Path.c_str(), m_SettingsPath.c_str()) != 0); }
return m_WorkDirectory;
}
std::wstring GetDefaultSkinPath() { return m_Path + L"Defaults\\Skins\\"; }
std::wstring GetDefaultLayoutPath() { return m_Path + L"Defaults\\Layouts\\"; }
std::wstring GetDefaultPluginPath() { return m_Path + L"Defaults\\Plugins\\"; }
std::wstring GetDefaultAddonPath() { return m_Path + L"Defaults\\Addons\\"; }
std::wstring GetSkinPath() { return GetWorkDirectory() + L"Skins\\"; }
std::wstring GetLayoutPath() { return GetWorkDirectory() + L"Layouts\\"; }
std::wstring GetPluginPath() { return GetWorkDirectory() + L"Plugins\\"; }
std::wstring GetUserPluginPath() { return GetWorkDirectory() + L"Plugins\\"; }
std::wstring GetAddonPath() { return GetWorkDirectory() + L"Addons\\"; }
const std::wstring& GetDrive() { return m_Drive; }
std::wstring GetDrive() { return PathUtil::GetVolume(GetWorkDirectory()); }
const std::wstring& GetSkinEditor() { return m_SkinEditor; }
void SetSkinEditor(const std::wstring& path);
const std::wstring& GetStatsDate() { return m_StatsDate; }
HWND GetWindow() { return m_Window; }
HINSTANCE GetModuleInstance() { return m_Instance; }
HINSTANCE GetResourceInstance() { return m_ResourceInstance; }
LCID GetResourceLCID() { return m_ResourceLCID; }
bool GetUseD2D() const { return m_UseD2D; }
void SetUseD2D(bool enabled);
bool GetDebug() { return m_Debug; }
bool GetDebug() const { return m_Debug; }
GlobalOptions& GetGlobalOptions() { return m_GlobalOptions; }
void ReloadSettings();
void EditSettings();
void EditSkinFile(const std::wstring& name, const std::wstring& iniFile);
void OpenSkinFolder(const std::wstring& name = std::wstring());
void UpdateStats();
void ReadStats();
void WriteStats(bool bForce);
void ResetStats();
bool GetDisableVersionCheck() { return m_DisableVersionCheck; }
void SetDisableVersionCheck(bool check);
bool GetNewVersion() { return m_NewVersion; }
void SetNewVersion() { m_NewVersion = true; }
void ShowLogFile();
bool GetDisableRDP() { return m_DisableRDP; }
bool IsRedrawable() { return (!GetDisableRDP() || !GetSystemMetrics(SM_REMOTESESSION)); }
bool GetDisableDragging() { return m_DisableDragging; }
void SetDisableDragging(bool dragging);
bool IsNormalStayDesktop() { return m_NormalStayDesktop; }
void SetDebug(bool debug);
int ShowMessage(HWND parent, const WCHAR* text, UINT type);
bool IsMenuActive() { return m_ContextMenu.IsMenuActive(); }
void ShowContextMenu(POINT pos, MeterWindow* mw) { return m_ContextMenu.ShowMenu(pos, mw); }
void ShowSkinCustomContextMenu(POINT pos, MeterWindow* mw) { return m_ContextMenu.ShowSkinCustomMenu(pos, mw); }
const std::wstring& GetTrayExecuteR() { return m_TrayExecuteR; }
const std::wstring& GetTrayExecuteM() { return m_TrayExecuteM; }
const std::wstring& GetTrayExecuteDR() { return m_TrayExecuteDR; }
const std::wstring& GetTrayExecuteDM() { return m_TrayExecuteDM; }
bool IsMenuActive() { /* TODO: implement c# callback */ LogErrorF(L"IsMenuActive callback not implemented."); return false; }
void ShowContextMenu(POINT pos, MeterWindow* mw) { /* TODO: implement c# callback */ LogErrorF(L"ShowContextMenu callback not implemented."); }
void ShowSkinCustomContextMenu(POINT pos, MeterWindow* mw) { /* TODO: implement c# callback */ LogErrorF(L"ShowSkinCustomContextMenu callback not implemented."); }
void ExecuteBang(const WCHAR* bang, std::vector<std::wstring>& args, MeterWindow* meterWindow);
void ExecuteCommand(const WCHAR* command, MeterWindow* meterWindow, bool multi = true);
@ -178,85 +149,60 @@ public:
void RefreshAll();
bool LoadLayout(const std::wstring& name);
void PreserveSetting(const std::wstring& from, LPCTSTR key, bool replace = true);
bool LoadLayout(std::wstring filename = std::wstring());
friend class CommandHandler;
friend class ContextMenu;
friend class DialogManage;
private:
#pragma region Constructor, destructor
Rainmeter();
~Rainmeter();
Rainmeter(const Rainmeter& other) = delete;
Rainmeter& operator=(Rainmeter other) = delete;
#pragma endregion
static LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void ActivateActiveSkins();
void CreateMeterWindow(const std::wstring& folderPath, const std::wstring& file);
void CreateMeterWindow(std::wstring file);
void DeleteAllMeterWindows();
void DeleteAllUnmanagedMeterWindows();
void WriteActive(const std::wstring& folderPath, int fileIndex);
void ScanForSkins();
void ScanForLayouts();
void ReadGeneralSettings(const std::wstring& iniFile);
void SetLoadOrder(int folderIndex, int order);
void SetLoadOrder(const std::wstring& file, int order);
int GetLoadOrder(const std::wstring& folderPath);
void UpdateDesktopWorkArea(bool reset);
std::wstring GetAbsolutePath(const std::wstring& path);
std::wstring NormalizePath(const std::wstring& path);
void CreateOptionsFile();
void CreateDataFile();
void CreateComponentFolders(bool defaultIniLocation);
void TestSettingsFile(bool bDefaultIniLocation);
#pragma region Private fields
TrayWindow* m_TrayWindow;
std::multimap<int, int> m_SkinOrders;
std::multimap<int, std::wstring> m_SkinOrders;
std::map<std::wstring, MeterWindow*> m_MeterWindows;
std::list<MeterWindow*> m_UnmanagedMeterWindows;
std::vector<std::wstring> m_Layouts;
std::wstring m_Path;
std::wstring m_IniFile;
std::wstring m_DataFile;
std::wstring m_StatsFile;
std::wstring m_SettingsPath;
std::wstring m_SkinPath;
std::wstring m_Drive;
std::wstring m_WorkDirectory;
bool m_UseCurrentDirectory; // TODO: getter, setter
std::wstring m_StatsFile; // TODO: getter, setter
std::wstring m_LayoutFile; // TODO: getter, setter
std::wstring m_StatsDate;
std::wstring m_TrayExecuteR;
std::wstring m_TrayExecuteM;
std::wstring m_TrayExecuteDR;
std::wstring m_TrayExecuteDM;
bool m_UseD2D;
bool m_Debug;
bool m_DisableVersionCheck;
bool m_NewVersion;
bool m_DesktopWorkAreaChanged;
bool m_DesktopWorkAreaType;
std::map<UINT, RECT> m_DesktopWorkAreas;
std::vector<RECT> m_OldDesktopWorkAreas;
bool m_NormalStayDesktop;
bool m_DisableRDP;
bool m_Debug;
bool m_DisableDragging;
std::wstring m_SkinEditor;
CommandHandler m_CommandHandler;
ContextMenu m_ContextMenu;
SkinRegistry m_SkinRegistry;
ConfigParser* m_CurrentParser;
@ -264,23 +210,15 @@ private:
HANDLE m_Mutex;
HINSTANCE m_Instance;
HMODULE m_ResourceInstance;
LCID m_ResourceLCID;
ULONG_PTR m_GDIplusToken;
GlobalOptions m_GlobalOptions;
#pragma endregion
};
// Convenience function.
inline Rainmeter& GetRainmeter() { return Rainmeter::GetInstance(); }
#ifdef LIBRARY_EXPORTS
#define EXPORT_PLUGIN EXTERN_C
#else
#define EXPORT_PLUGIN EXTERN_C __declspec(dllimport)
#endif
EXPORT_PLUGIN int RainmeterMain(LPWSTR cmdLine);
#endif

View File

@ -89,7 +89,7 @@ These Queries return a string in a wide char format
#define RAINMETER_QUERY_ID_SKINS_PATH 4101
#define RAINMETER_QUERY_ID_SETTINGS_PATH 4102
#define RAINMETER_QUERY_ID_PLUGINS_PATH 4103
#define RAINMETER_QUERY_ID_PROGRAM_PATH 4104
#define RAINMETER_QUERY_ID_PROGRAm_WorkDirectory 4104
#define RAINMETER_QUERY_ID_LOG_PATH 4105
#define RAINMETER_QUERY_ID_CONFIG_EDITOR 4106

View File

@ -1,242 +0,0 @@
/*
Copyright (C) 2013 Rainmeter Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "../Common/PathUtil.h"
#include "SkinRegistry.h"
#include "resource.h"
/*
** Returns the skin folder path relative to the skin folder (e.g. illustro\Clock).
*/
std::wstring SkinRegistry::GetFolderPath(int folderIndex) const
{
// Traverse |m_Folders| backwards until level 1 is reached.
const auto& skinFolder = m_Folders[folderIndex];
std::wstring path = skinFolder.name;
for (int i = skinFolder.level - 1, index = folderIndex; i >= 1; --i)
{
while (m_Folders[index].level != i)
{
--index;
}
path.insert(0, L"\\");
path.insert(0, m_Folders[index].name);
}
return path;
}
/*
** Finds the skin index for the specified skin folder path.
*/
int SkinRegistry::FindFolderIndex(const std::wstring& folderPath) const
{
if (folderPath.empty()) return -1;
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_Folders.size(); i < isize; ++i)
{
const auto& skinFolder = m_Folders[i];
if (skinFolder.level == level)
{
if (skinFolder.name.length() == len && _wcsnicmp(skinFolder.name.c_str(), path, len) == 0)
{
path += len;
if (*path)
{
++path; // Skip backslash
len = 0;
while (path[len] && path[len] != L'\\') ++len;
}
else
{
// Match found
return i;
}
++level;
}
}
else if (skinFolder.level < level)
{
break;
}
}
return -1;
}
SkinRegistry::Folder* SkinRegistry::FindFolder(const std::wstring& folderPath)
{
const int folderIndex = FindFolderIndex(folderPath);
return (folderIndex != -1) ? &m_Folders[folderIndex] : nullptr;
}
SkinRegistry::Indexes SkinRegistry::FindIndexes(const std::wstring& folderPath, const std::wstring& file)
{
const int folderIndex = FindFolderIndex(folderPath);
if (folderIndex != -1)
{
const Folder& skinFolder = m_Folders[folderIndex];
const WCHAR* fileSz = file.c_str();
for (size_t i = 0, isize = skinFolder.files.size(); i < isize; ++i)
{
if (_wcsicmp(skinFolder.files[i].c_str(), fileSz) == 0)
{
return Indexes(folderIndex, (int)i);
}
}
}
return Indexes::Invalid(); // Not found.
}
SkinRegistry::Indexes SkinRegistry::FindIndexesForID(UINT id)
{
if (id >= ID_CONFIG_FIRST && id <= ID_CONFIG_LAST)
{
// Check which skin was selected
for (size_t i = 0, isize = m_Folders.size(); i < isize; ++i)
{
const Folder& skinFolder = m_Folders[i];
if (id >= skinFolder.baseID &&
id < (skinFolder.baseID + skinFolder.files.size()))
{
return Indexes((int)i, (int)(id - skinFolder.baseID));
}
}
}
return Indexes::Invalid(); // Not found.
}
/*
** Re-scans all the subfolders of |path| for .ini files and populates |m_Folders|.
*/
void SkinRegistry::Populate(const std::wstring& path)
{
m_Folders.clear();
PopulateRecursive(path, L"", 0, 0);
}
int SkinRegistry::PopulateRecursive(const std::wstring& path, std::wstring base, int index, UINT level)
{
WIN32_FIND_DATA fileData; // Data structure describes the file found
HANDLE hSearch; // Search handle returned by FindFirstFile
std::list<std::wstring> subfolders;
// Find all .ini files and subfolders
std::wstring filter = path + base;
filter += L"\\*";
hSearch = FindFirstFileEx(
filter.c_str(),
(IsWindows7OrGreater()) ? FindExInfoBasic : FindExInfoStandard,
&fileData,
FindExSearchNameMatch,
nullptr,
0);
bool foundFiles = false;
if (hSearch != INVALID_HANDLE_VALUE)
{
Folder folder;
folder.baseID = ID_CONFIG_FIRST + index;
folder.active = 0;
folder.level = level;
do
{
const std::wstring filename = fileData.cFileName;
if (fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (!PathUtil::IsDotOrDotDot(fileData.cFileName) &&
!(level == 0 && wcscmp(L"@Backup", fileData.cFileName) == 0) &&
!(level == 0 && wcscmp(L"Backup", fileData.cFileName) == 0) &&
!(level == 1 && wcscmp(L"@Resources", fileData.cFileName) == 0))
{
subfolders.push_back(filename);
}
}
else if (level != 0)
{
// Check whether the extension is ".ini"
size_t filenameLen = filename.size();
if (filenameLen >= 4 && _wcsicmp(fileData.cFileName + (filenameLen - 4), L".ini") == 0)
{
foundFiles = true;
folder.files.push_back(filename);
++index;
}
}
}
while (FindNextFile(hSearch, &fileData));
FindClose(hSearch);
if (level > 0 && (foundFiles || !subfolders.empty()))
{
if (level == 1)
{
folder.name = base;
}
else
{
std::wstring::size_type pos = base.rfind(L'\\') + 1;
folder.name.assign(base, pos, base.length() - pos);
}
m_Folders.push_back(std::move(folder));
}
}
if (level != 0)
{
base += L'\\';
}
if (!subfolders.empty())
{
bool popFolder = !foundFiles;
std::list<std::wstring>::const_iterator iter = subfolders.begin();
for ( ; iter != subfolders.end(); ++iter)
{
int newIndex = PopulateRecursive(path, base + (*iter), index, level + 1);
if (newIndex != index)
{
popFolder = false;
}
index = newIndex;
}
if (popFolder)
{
m_Folders.pop_back();
}
}
return index;
}

View File

@ -1,105 +0,0 @@
/*
Copyright (C) 2013 Rainmeter Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef RM_LIBRARY_SKINDIRECTORY_H_
#define RM_LIBRARY_SKINDIRECTORY_H_
#include <Windows.h>
#include <string>
#include <vector>
#include <cstdint>
// Reprsents a hierarchy of skin folders (reprsented by the Folder struct) and the names of their
// respective files.
class SkinRegistry
{
public:
SkinRegistry() = default;
SkinRegistry(const SkinRegistry& other) = delete;
SkinRegistry& operator=(SkinRegistry other) = delete;
struct Folder
{
std::wstring name;
std::vector<std::wstring> files;
UINT baseID;
int16_t active;
int16_t level;
Folder() {}
~Folder() {}
Folder(Folder&& r) :
name(std::move(r.name)),
files(std::move(r.files)),
baseID(r.baseID),
active(r.active),
level(r.level)
{
}
Folder& operator=(Folder&& r)
{
name = std::move(r.name);
files = std::move(r.files);
baseID = r.baseID;
active = r.active;
level = r.level;
return *this;
}
};
struct Indexes
{
int folder;
int file;
Indexes(int folderIndex = 0, int fileIndex = 0) : folder(folderIndex), file(fileIndex) {}
bool IsValid() const { return folder != -1; }
static Indexes Invalid() { return Indexes(-1, 0); }
};
int FindFolderIndex(const std::wstring& folderPath) const;
Folder* FindFolder(const std::wstring& folderPath);
Indexes FindIndexes(const std::wstring& folderPath, const std::wstring& file);
Indexes FindIndexesForID(UINT id);
std::wstring GetFolderPath(int folderIndex) const;
Folder& GetFolder(int index) { return m_Folders[index]; }
int GetFolderCount() const { return (int)m_Folders.size(); }
bool IsEmpty() const { return m_Folders.empty(); }
void Populate(const std::wstring& path);
private:
int PopulateRecursive(const std::wstring& path, std::wstring base, int index, UINT level);
// Contains a sequential list of Folders. The folders are arranged as follows:
// A (index: 0, level: 1)
// B (index: 1, level: 2)
// C (index: 2, level: 3)
// D (index: 3, level: 2)
std::vector<Folder> m_Folders;
};
#endif

View File

@ -1,104 +0,0 @@
/*
Copyright (C) 2013 Rainmeter Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "SkinRegistry.h"
#include "../Common/UnitTest.h"
TEST_CLASS(Library_SkinRegistry_Test)
{
public:
Library_SkinRegistry_Test()
{
m_SkinRegistry.Populate(L"..\\..\\..\\Library\\Test\\SkinRegistry\\");
}
TEST_METHOD(TestContents)
{
std::vector<std::wstring> files1;
files1.push_back(L"1.ini");
std::vector<std::wstring> files3;
files3.push_back(L"1.ini");
files3.push_back(L"2.ini");
files3.push_back(L"3.ini");
Assert::AreEqual(5, m_SkinRegistry.GetFolderCount());
const auto& folderA1 = m_SkinRegistry.GetFolder(0);
Assert::AreEqual(L"A1", folderA1.name.c_str());
Assert::AreEqual((int16_t)1, folderA1.level);
Assert::IsTrue(folderA1.files.empty());
const auto& folderA1_B1 = m_SkinRegistry.GetFolder(1);
Assert::AreEqual(L"B1", folderA1_B1.name.c_str());
Assert::AreEqual((int16_t)2, folderA1_B1.level);
Assert::IsTrue(files1 == folderA1_B1.files);
const auto& folderA1_B2 = m_SkinRegistry.GetFolder(2);
Assert::AreEqual(L"B2", folderA1_B2.name.c_str());
Assert::AreEqual((int16_t)2, folderA1_B2.level);
Assert::IsTrue(files1 == folderA1_B2.files);
const auto& folderA1_B2_C1 = m_SkinRegistry.GetFolder(3);
Assert::AreEqual(L"C1", folderA1_B2_C1.name.c_str());
Assert::AreEqual((int16_t)3, folderA1_B2_C1.level);
Assert::IsTrue(files1 == folderA1_B2_C1.files);
const auto& folderA2 = m_SkinRegistry.GetFolder(4);
Assert::AreEqual(L"A2", folderA2.name.c_str());
Assert::AreEqual((int16_t)1, folderA2.level);
Assert::IsTrue(files3 == folderA2.files);
}
TEST_METHOD(TestFindFolderIndex)
{
Assert::AreEqual(3, m_SkinRegistry.FindFolderIndex(L"A1\\B2\\C1"));
Assert::AreEqual(-1, m_SkinRegistry.FindFolderIndex(L"A1\\B5\\C1"));
}
TEST_METHOD(TestFindIndexes)
{
const auto indexes1 = m_SkinRegistry.FindIndexes(L"A1\\B2", L"1.ini");
Assert::IsTrue(indexes1.folder == 2 && indexes1.file == 0);
const auto indexes2 = m_SkinRegistry.FindIndexes(L"A2", L"2.ini");
Assert::IsTrue(indexes2.folder == 4 && indexes2.file == 1);
const auto indexes3 = m_SkinRegistry.FindIndexes(L"A3", L"1.ini");
Assert::IsFalse(indexes3.IsValid());
}
TEST_METHOD(TestFindIndexesForID)
{
const auto indexes1 = m_SkinRegistry.FindIndexesForID(30002);
Assert::IsTrue(indexes1.folder == 2 && indexes1.file == 0);
const auto indexes2 = m_SkinRegistry.FindIndexesForID(30005);
Assert::IsTrue(indexes2.folder == 4 && indexes2.file == 1);
}
TEST_METHOD(TestGetFolderPath)
{
Assert::AreEqual(L"A1\\B2\\C1", m_SkinRegistry.GetFolderPath(3).c_str());
Assert::AreEqual(L"A2", m_SkinRegistry.GetFolderPath(4).c_str());
}
private:
SkinRegistry m_SkinRegistry;
};

View File

@ -942,9 +942,8 @@ LRESULT CALLBACK System::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa
break;
case TIMER_RESUME:
KillTimer(hWnd, TIMER_RESUME);
if (GetRainmeter().IsRedrawable())
{
KillTimer(hWnd, TIMER_RESUME);
std::map<std::wstring, MeterWindow*>::const_iterator iter = GetRainmeter().GetAllMeterWindows().begin();
for ( ; iter != GetRainmeter().GetAllMeterWindows().end(); ++iter)
{
@ -1147,7 +1146,7 @@ void System::SetWallpaper(const std::wstring& wallpaper, const std::wstring& sty
Bitmap bitmap(wallpaper.c_str());
if (bitmap.GetLastStatus() == Ok)
{
std::wstring file = GetRainmeter().GetSettingsPath() + L"Wallpaper.bmp";
std::wstring file = /*TODO - fix: GetRainmeter().GetSettingsPath() + */ L"Wallpaper.bmp";
const CLSID bmpClsid = { 0x557cf400, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } };
if (bitmap.Save(file.c_str(), &bmpClsid) == Ok)

View File

@ -318,7 +318,7 @@ void TintedImage::LoadImage(const std::wstring& imageName, bool bLoadAlways)
// Load the bitmap if defined
if (!imageName.empty())
{
std::wstring filename = m_Path + imageName;
std::wstring filename = m_WorkDirectory + imageName;
if (m_MeterWindow) m_MeterWindow->MakePathAbsolute(filename);
m_HasPathChanged = false;
@ -629,12 +629,12 @@ void TintedImage::ReadOptions(ConfigParser& parser, const WCHAR* section, const
ColorMatrix oldColorMatrix = *m_ColorMatrix;
RotateFlipType oldFlip = m_Flip;
REAL oldRotate = m_Rotate;
std::wstring oldPath = m_Path;
std::wstring oldPath = m_WorkDirectory;
m_Path = parser.ReadString(section, m_OptionArray[OptionIndexImagePath], imagePath);
PathUtil::AppendBacklashIfMissing(m_Path);
m_WorkDirectory = parser.ReadString(section, m_OptionArray[OptionIndexImagePath], imagePath);
PathUtil::AppendBacklashIfMissing(m_WorkDirectory);
m_HasPathChanged = (oldPath != m_Path);
m_HasPathChanged = (oldPath != m_WorkDirectory);
if (!m_DisableTransform)
{

View File

@ -128,7 +128,7 @@ protected:
Gdiplus::REAL m_Rotate;
bool m_UseExifOrientation;
std::wstring m_Path;
std::wstring m_WorkDirectory;
bool m_HasPathChanged;
std::wstring m_CacheKey;

View File

@ -1,736 +0,0 @@
/*
Copyright (C) 2004 Kimmo Pekkola
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "TrayWindow.h"
#include "Measure.h"
#include "resource.h"
#include "Litestep.h"
#include "Rainmeter.h"
#include "DialogAbout.h"
#include "DialogManage.h"
#include "System.h"
#include "Error.h"
#include "RainmeterQuery.h"
#include "resource.h"
#include "../Version.h"
#define RAINMETER_OFFICIAL L"http://rainmeter.net/cms/"
#define RAINMETER_HELP L"http://docs.rainmeter.net/"
#define ZPOS_FLAGS (SWP_NOMOVE | SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING)
enum TIMER
{
TIMER_ADDTRAYICON = 1,
TIMER_TRAYMEASURE = 3
};
enum INTERVAL
{
INTERVAL_ADDTRAYICON = 3000,
INTERVAL_TRAYMEASURE = 1000
};
const UINT WM_TASKBARCREATED = ::RegisterWindowMessage(L"TaskbarCreated");
using namespace Gdiplus;
TrayWindow::TrayWindow() :
m_Icon(),
m_Measure(),
m_MeterType(TRAY_METER_TYPE_HISTOGRAM),
m_Color1(0, 100, 0),
m_Color2(0, 255, 0),
m_Bitmap(),
m_Values(),
m_Pos(),
m_Notification(TRAY_NOTIFICATION_NONE),
m_TrayContextMenuEnabled(true),
m_IconEnabled(true)
{
}
TrayWindow::~TrayWindow()
{
KillTimer(m_Window, TIMER_ADDTRAYICON);
KillTimer(m_Window, TIMER_TRAYMEASURE);
RemoveTrayIcon();
delete m_Bitmap;
delete m_Measure;
for (size_t i = 0, isize = m_Icons.size(); i < isize; ++i)
{
DestroyIcon(m_Icons[i]);
}
m_Icons.clear();
if (m_Window) DestroyWindow(m_Window);
}
void TrayWindow::Initialize()
{
WNDCLASS wc = {0};
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.hInstance = GetRainmeter().GetModuleInstance();
wc.lpszClassName = L"RainmeterTrayClass";
wc.hIcon = GetIcon(IDI_RAINMETER);
RegisterClass(&wc);
m_Window = CreateWindowEx(
WS_EX_TOOLWINDOW,
L"RainmeterTrayClass",
nullptr,
WS_POPUP | WS_DISABLED,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
nullptr,
nullptr,
wc.hInstance,
this);
SetWindowPos(m_Window, HWND_BOTTOM, 0, 0, 0, 0, ZPOS_FLAGS);
}
bool TrayWindow::AddTrayIcon()
{
NOTIFYICONDATA tnid = {sizeof(NOTIFYICONDATA)};
tnid.hWnd = m_Window;
tnid.uID = IDI_TRAY;
tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
tnid.uCallbackMessage = WM_TRAY_NOTIFYICON;
tnid.hIcon = m_Icon;
wcsncpy_s(tnid.szTip, APPNAME, _TRUNCATE);
return (Shell_NotifyIcon(NIM_ADD, &tnid) || GetLastError() != ERROR_TIMEOUT);
}
bool TrayWindow::IsTrayIconReady()
{
NOTIFYICONDATA tnid = {sizeof(NOTIFYICONDATA)};
tnid.hWnd = m_Window;
tnid.uID = IDI_TRAY;
return Shell_NotifyIcon(NIM_MODIFY, &tnid) != FALSE;
}
void TrayWindow::TryAddTrayIcon()
{
if (IsTrayIconReady())
{
ModifyTrayIcon(0);
return;
}
if (m_Icon)
{
DestroyIcon(m_Icon);
m_Icon = nullptr;
}
m_Icon = CreateTrayIcon(0);
if (!AddTrayIcon())
{
SetTimer(m_Window, TIMER_ADDTRAYICON, INTERVAL_ADDTRAYICON, nullptr);
}
}
void TrayWindow::CheckTrayIcon()
{
if (IsTrayIconReady() || AddTrayIcon())
{
KillTimer(m_Window, TIMER_ADDTRAYICON);
}
}
void TrayWindow::RemoveTrayIcon()
{
NOTIFYICONDATA tnid = {sizeof(NOTIFYICONDATA)};
tnid.hWnd = m_Window;
tnid.uID = IDI_TRAY;
tnid.uFlags = 0;
Shell_NotifyIcon(NIM_DELETE, &tnid);
if (m_Icon)
{
DestroyIcon(m_Icon);
m_Icon = nullptr;
}
}
void TrayWindow::ModifyTrayIcon(double value)
{
if (m_Icon)
{
DestroyIcon(m_Icon);
m_Icon = nullptr;
}
m_Icon = CreateTrayIcon(value);
NOTIFYICONDATA tnid = {sizeof(NOTIFYICONDATA)};
tnid.hWnd = m_Window;
tnid.uID = IDI_TRAY;
tnid.uFlags = NIF_ICON;
tnid.hIcon = m_Icon;
Shell_NotifyIcon(NIM_MODIFY, &tnid);
}
HICON TrayWindow::CreateTrayIcon(double value)
{
if (m_Measure != nullptr)
{
if (m_MeterType == TRAY_METER_TYPE_HISTOGRAM)
{
m_Values[m_Pos] = value;
m_Pos = (m_Pos + 1) % TRAYICON_SIZE;
Bitmap trayBitmap(TRAYICON_SIZE, TRAYICON_SIZE);
Graphics graphics(&trayBitmap);
graphics.SetSmoothingMode(SmoothingModeAntiAlias);
Point points[TRAYICON_SIZE + 2];
points[0].X = 0;
points[0].Y = TRAYICON_SIZE;
points[TRAYICON_SIZE + 1].X = TRAYICON_SIZE - 1;
points[TRAYICON_SIZE + 1].Y = TRAYICON_SIZE;
for (int i = 0; i < TRAYICON_SIZE; ++i)
{
points[i + 1].X = i;
points[i + 1].Y = (int)(TRAYICON_SIZE * (1.0 - m_Values[(m_Pos + i) % TRAYICON_SIZE]));
}
SolidBrush brush(m_Color1);
graphics.FillRectangle(&brush, 0, 0, TRAYICON_SIZE, TRAYICON_SIZE);
SolidBrush brush2(m_Color2);
graphics.FillPolygon(&brush2, points, TRAYICON_SIZE + 2);
HICON icon = nullptr;
trayBitmap.GetHICON(&icon);
return icon;
}
else if (m_MeterType == TRAY_METER_TYPE_BITMAP && (m_Bitmap || !m_Icons.empty()))
{
if (!m_Icons.empty())
{
size_t frame = 0;
size_t frameCount = m_Icons.size();
// Select the correct frame linearly
frame = (size_t)(value * frameCount);
frame = min((frameCount - 1), frame);
return CopyIcon(m_Icons[frame]);
}
else
{
int frame = 0;
int frameCount = 0;
int newX, newY;
if (m_Bitmap->GetWidth() > m_Bitmap->GetHeight())
{
frameCount = m_Bitmap->GetWidth() / TRAYICON_SIZE;
}
else
{
frameCount = m_Bitmap->GetHeight() / TRAYICON_SIZE;
}
// Select the correct frame linearly
frame = (int)(value * frameCount);
frame = min((frameCount - 1), frame);
if (m_Bitmap->GetWidth() > m_Bitmap->GetHeight())
{
newX = frame * TRAYICON_SIZE;
newY = 0;
}
else
{
newX = 0;
newY = frame * TRAYICON_SIZE;
}
Bitmap trayBitmap(TRAYICON_SIZE, TRAYICON_SIZE);
Graphics graphics(&trayBitmap);
graphics.SetSmoothingMode(SmoothingModeAntiAlias);
// Blit the image
Rect r(0, 0, TRAYICON_SIZE, TRAYICON_SIZE);
graphics.DrawImage(m_Bitmap, r, newX, newY, TRAYICON_SIZE, TRAYICON_SIZE, UnitPixel);
HICON icon = nullptr;
trayBitmap.GetHICON(&icon);
return icon;
}
}
}
// Return the default icon if there is no valid measure
return GetIcon(IDI_TRAY);
}
void TrayWindow::ShowNotification(TRAY_NOTIFICATION id, const WCHAR* title, const WCHAR* text)
{
if (m_Notification == TRAY_NOTIFICATION_NONE)
{
NOTIFYICONDATA nid = {sizeof(NOTIFYICONDATA)};
nid.hWnd = m_Window;
nid.uID = IDI_TRAY;
nid.uFlags = NIF_INFO;
nid.uTimeout = 30000;
nid.dwInfoFlags = NIIF_USER;
wcsncpy_s(nid.szInfoTitle, title, _TRUNCATE);
wcsncpy_s(nid.szInfo, text, _TRUNCATE);
if (IsWindows7OrGreater())
{
nid.dwInfoFlags |= NIIF_LARGE_ICON;
nid.hBalloonIcon = GetIcon(IDI_RAINMETER, true);
}
if (Shell_NotifyIcon(NIM_MODIFY, &nid))
{
m_Notification = id;
}
}
}
void TrayWindow::ShowWelcomeNotification()
{
ShowNotification(TRAY_NOTIFICATION_WELCOME, GetString(ID_STR_WELCOME), GetString(ID_STR_CLICKTOMANAGE));
}
void TrayWindow::ShowUpdateNotification(const WCHAR* newVersion)
{
std::wstring text = GetFormattedString(ID_STR_CLICKTODOWNLOAD, newVersion);
ShowNotification(TRAY_NOTIFICATION_UPDATE, GetString(ID_STR_UPDATEAVAILABLE), text.c_str());
}
void TrayWindow::SetTrayIcon(bool enabled)
{
enabled ? TryAddTrayIcon() : RemoveTrayIcon();
m_IconEnabled = enabled;
// Save to Rainmeter.ini.
const std::wstring& iniFile = GetRainmeter().GetIniFile();
WritePrivateProfileString(L"Rainmeter", L"TrayIcon", enabled ? nullptr : L"0", iniFile.c_str());
}
void TrayWindow::ReadOptions(ConfigParser& parser)
{
// Clear old Settings
KillTimer(m_Window, TIMER_ADDTRAYICON);
KillTimer(m_Window, TIMER_TRAYMEASURE);
delete m_Measure;
m_Measure = nullptr;
delete m_Bitmap;
m_Bitmap = nullptr;
std::vector<HICON>::const_iterator iter = m_Icons.begin();
for ( ; iter != m_Icons.end(); ++iter)
{
DestroyIcon((*iter));
}
m_Icons.clear();
m_MeterType = TRAY_METER_TYPE_NONE;
// Read tray settings
m_IconEnabled = parser.ReadBool(L"Rainmeter", L"TrayIcon", true);
if (m_IconEnabled)
{
const std::wstring& measureName = parser.ReadString(L"TrayMeasure", L"Measure", L"");
if (!measureName.empty())
{
ConfigParser* oldParser = GetRainmeter().GetCurrentParser();
GetRainmeter().SetCurrentParser(&parser);
m_Measure = Measure::Create(measureName.c_str(), nullptr, L"TrayMeasure");
if (m_Measure)
{
m_Measure->ReadOptions(parser);
}
GetRainmeter().SetCurrentParser(oldParser);
}
const WCHAR* type = parser.ReadString(L"TrayMeasure", L"TrayMeter", m_Measure ? L"HISTOGRAM" : L"NONE").c_str();
if (_wcsicmp(type, L"NONE") == 0)
{
// Use main icon
}
else if (_wcsicmp(type, L"HISTOGRAM") == 0)
{
m_MeterType = TRAY_METER_TYPE_HISTOGRAM;
m_Color1 = parser.ReadColor(L"TrayMeasure", L"TrayColor1", Color::MakeARGB(255, 0, 100, 0));
m_Color2 = parser.ReadColor(L"TrayMeasure", L"TrayColor2", Color::MakeARGB(255, 0, 255, 0));
}
else if (_wcsicmp(type, L"BITMAP") == 0)
{
m_MeterType = TRAY_METER_TYPE_BITMAP;
std::wstring imageName = parser.ReadString(L"TrayMeasure", L"TrayBitmap", L"");
// Load the bitmaps if defined
if (!imageName.empty())
{
imageName.insert(0, GetRainmeter().GetSkinPath());
const WCHAR* imagePath = imageName.c_str();
if (_wcsicmp(imagePath + (imageName.size() - 4), L".ico") == 0)
{
int count = 1;
HICON hIcon = nullptr;
// Load the icons
do
{
WCHAR buffer[MAX_PATH];
_snwprintf_s(buffer, _TRUNCATE, imagePath, count++);
hIcon = (HICON)LoadImage(nullptr, buffer, IMAGE_ICON, TRAYICON_SIZE, TRAYICON_SIZE, LR_LOADFROMFILE);
if (hIcon) m_Icons.push_back(hIcon);
if (wcscmp(imagePath, buffer) == 0) break;
}
while(hIcon != nullptr);
}
if (m_Icons.empty())
{
// No icons found so load as bitmap
delete m_Bitmap;
m_Bitmap = new Bitmap(imagePath);
Status status = m_Bitmap->GetLastStatus();
if (Ok != status)
{
delete m_Bitmap;
m_Bitmap = nullptr;
LogWarningF(L"Bitmap image not found: %s", imagePath);
}
}
}
}
else
{
LogErrorF(L"No such TrayMeter: %s", type);
}
TryAddTrayIcon();
if (m_Measure)
{
SetTimer(m_Window, TIMER_TRAYMEASURE, INTERVAL_TRAYMEASURE, nullptr); // Update the tray once per sec
}
}
else
{
RemoveTrayIcon();
}
}
LRESULT CALLBACK TrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
TrayWindow* tray = GetRainmeter().GetTrayWindow();
switch (uMsg)
{
case WM_COMMAND:
switch (wParam)
{
case IDM_MANAGE:
DialogManage::Open();
break;
case IDM_ABOUT:
DialogAbout::Open();
break;
case IDM_SHOW_HELP:
CommandHandler::RunFile(RAINMETER_HELP);
break;
case IDM_NEW_VERSION:
CommandHandler::RunFile(RAINMETER_OFFICIAL);
break;
case IDM_REFRESH:
PostMessage(GetRainmeter().GetWindow(), WM_RAINMETER_DELAYED_REFRESH_ALL, (WPARAM)nullptr, (LPARAM)nullptr);
break;
case IDM_SHOWLOGFILE:
GetRainmeter().ShowLogFile();
break;
case IDM_STARTLOG:
GetLogger().StartLogFile();
break;
case IDM_STOPLOG:
GetLogger().StopLogFile();
break;
case IDM_DELETELOGFILE:
GetLogger().DeleteLogFile();
break;
case IDM_DEBUGLOG:
GetRainmeter().SetDebug(!GetRainmeter().GetDebug());
break;
case IDM_DISABLEDRAG:
GetRainmeter().SetDisableDragging(!GetRainmeter().GetDisableDragging());
break;
case IDM_EDITCONFIG:
GetRainmeter().EditSettings();
break;
case IDM_QUIT:
PostQuitMessage(0);
break;
case IDM_OPENSKINSFOLDER:
GetRainmeter().OpenSkinFolder();
break;
default:
{
UINT mID = wParam & 0x0FFFF;
if (mID >= ID_THEME_FIRST && mID <= ID_THEME_LAST)
{
int pos = mID - ID_THEME_FIRST;
const std::vector<std::wstring>& layouts = GetRainmeter().GetAllLayouts();
if (pos >= 0 && pos < (int)layouts.size())
{
GetRainmeter().LoadLayout(layouts[pos]);
}
}
else if (mID >= ID_CONFIG_FIRST && mID <= ID_CONFIG_LAST)
{
GetRainmeter().ToggleSkinWithID(mID);
}
else
{
// Forward the message to correct window
int index = (int)(wParam >> 16);
const std::map<std::wstring, MeterWindow*>& windows = GetRainmeter().GetAllMeterWindows();
if (index < (int)windows.size())
{
std::map<std::wstring, MeterWindow*>::const_iterator iter = windows.begin();
for ( ; iter != windows.end(); ++iter)
{
--index;
if (index < 0)
{
MeterWindow* meterWindow = (*iter).second;
SendMessage(meterWindow->GetWindow(), WM_COMMAND, mID, 0);
break;
}
}
}
}
}
break;
}
break; // Don't send WM_COMMANDS any further
case WM_TRAY_NOTIFYICON:
{
UINT uMouseMsg = (UINT)lParam;
LPCWSTR bang;
// Check TrayExecute actions
switch (uMouseMsg)
{
case WM_MBUTTONDOWN:
bang = GetRainmeter().GetTrayExecuteM().c_str();
break;
case WM_RBUTTONDOWN:
bang = GetRainmeter().GetTrayExecuteR().c_str();
break;
case WM_MBUTTONDBLCLK:
bang = GetRainmeter().GetTrayExecuteDM().c_str();
break;
case WM_RBUTTONDBLCLK:
bang = GetRainmeter().GetTrayExecuteDR().c_str();
break;
default:
bang = L"";
break;
}
if (*bang &&
!IsCtrlKeyDown()) // Ctrl is pressed, so only run default action
{
GetRainmeter().ExecuteCommand(bang, nullptr);
tray->m_TrayContextMenuEnabled = (uMouseMsg != WM_RBUTTONDOWN);
break;
}
// Run default UI action
switch (uMouseMsg)
{
case WM_RBUTTONDOWN:
tray->m_TrayContextMenuEnabled = true;
break;
case WM_RBUTTONUP:
if (tray->m_TrayContextMenuEnabled)
{
POINT pos = System::GetCursorPosition();
GetRainmeter().ShowContextMenu(pos, nullptr);
}
break;
case WM_LBUTTONUP:
case WM_LBUTTONDBLCLK:
DialogManage::Open();
break;
case NIN_BALLOONUSERCLICK:
if (tray->m_Notification == TRAY_NOTIFICATION_WELCOME)
{
DialogManage::Open();
}
else if (tray->m_Notification == TRAY_NOTIFICATION_UPDATE)
{
CommandHandler::RunFile(RAINMETER_OFFICIAL);
}
tray->m_Notification = TRAY_NOTIFICATION_NONE;
break;
case NIN_BALLOONHIDE:
case NIN_BALLOONTIMEOUT:
tray->m_Notification = TRAY_NOTIFICATION_NONE;
break;
}
}
break;
case WM_QUERY_RAINMETER:
if (IsWindow((HWND)lParam))
{
auto sendCopyData = [&](const std::wstring& data)
{
COPYDATASTRUCT cds;
cds.dwData = wParam;
cds.cbData = (DWORD)((data.length() + 1) * sizeof(WCHAR));
cds.lpData = (PVOID)data.c_str();
SendMessage((HWND)lParam, WM_COPYDATA, (WPARAM)hWnd, (LPARAM)&cds);
};
switch (wParam)
{
case RAINMETER_QUERY_ID_SKINS_PATH:
sendCopyData(GetRainmeter().GetSkinPath());
return 0;
case RAINMETER_QUERY_ID_SETTINGS_PATH:
sendCopyData(GetRainmeter().GetSettingsPath());
return 0;
case RAINMETER_QUERY_ID_PLUGINS_PATH:
sendCopyData(GetRainmeter().GetPluginPath());
return 0;
case RAINMETER_QUERY_ID_PROGRAM_PATH:
sendCopyData(GetRainmeter().GetPath());
return 0;
case RAINMETER_QUERY_ID_LOG_PATH:
sendCopyData(GetLogger().GetLogFilePath());
return 0;
case RAINMETER_QUERY_ID_CONFIG_EDITOR:
sendCopyData(GetRainmeter().GetSkinEditor());
return 0;
case RAINMETER_QUERY_ID_IS_DEBUGGING:
{
BOOL debug = GetRainmeter().GetDebug();
SendMessage((HWND)lParam, WM_QUERY_RAINMETER_RETURN, (WPARAM)hWnd, (LPARAM)debug);
}
return 0;
}
}
return 1;
case WM_COPYDATA:
{
COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam;
if (cds->dwData == RAINMETER_QUERY_ID_SKIN_WINDOWHANDLE)
{
LPCWSTR folderPath = (LPCWSTR)cds->lpData;
MeterWindow* mw = GetRainmeter().GetMeterWindow(folderPath);
return (mw) ? (LRESULT)mw->GetWindow() : 0;
}
}
return 1;
case WM_TIMER:
if (wParam == TIMER_TRAYMEASURE)
{
if (tray->m_Measure)
{
tray->m_Measure->Update();
tray->ModifyTrayIcon(tray->m_Measure->GetRelativeValue());
}
}
else if (wParam == TIMER_ADDTRAYICON)
{
tray->CheckTrayIcon();
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
if (uMsg == WM_TASKBARCREATED)
{
if (tray->IsTrayIconEnabled())
{
tray->RemoveTrayIcon();
tray->TryAddTrayIcon();
}
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}

View File

@ -1,101 +0,0 @@
/*
Copyright (C) 2004 Kimmo Pekkola
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __TRAYWINDOW_H__
#define __TRAYWINDOW_H__
#include <windows.h>
#include <ole2.h> // For Gdiplus.h.
#include <gdiplus.h>
#include <vector>
#define WM_TRAY_NOTIFYICON WM_USER + 101
#define TRAYICON_SIZE 16
enum TRAY_METER_TYPE
{
TRAY_METER_TYPE_NONE,
TRAY_METER_TYPE_HISTOGRAM,
TRAY_METER_TYPE_BITMAP
};
class ConfigParser;
class Measure;
class TrayWindow
{
public:
TrayWindow();
~TrayWindow();
TrayWindow(const TrayWindow& other) = delete;
TrayWindow& operator=(TrayWindow other) = delete;
void Initialize();
void ReadOptions(ConfigParser& parser);
HWND GetWindow() { return m_Window; }
bool IsTrayIconEnabled() { return m_IconEnabled; }
void SetTrayIcon(bool enabled);
void ShowWelcomeNotification();
void ShowUpdateNotification(const WCHAR* newVersion);
protected:
static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
private:
enum TRAY_NOTIFICATION
{
TRAY_NOTIFICATION_NONE,
TRAY_NOTIFICATION_WELCOME,
TRAY_NOTIFICATION_UPDATE
};
bool AddTrayIcon();
bool IsTrayIconReady();
void TryAddTrayIcon();
void CheckTrayIcon();
void RemoveTrayIcon();
void ModifyTrayIcon(double value);
HICON CreateTrayIcon(double value);
void ShowNotification(TRAY_NOTIFICATION id, const WCHAR* title, const WCHAR* text);
HICON m_Icon;
HWND m_Window;
Measure* m_Measure;
TRAY_METER_TYPE m_MeterType;
Gdiplus::Color m_Color1;
Gdiplus::Color m_Color2;
Gdiplus::Bitmap* m_Bitmap;
std::vector<HICON> m_Icons;
double m_Values[TRAYICON_SIZE];
int m_Pos;
TRAY_NOTIFICATION m_Notification;
bool m_TrayContextMenuEnabled;
bool m_IconEnabled;
};
#endif

View File

@ -1,97 +0,0 @@
/*
Copyright (C) 2004 Kimmo Pekkola
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "StdAfx.h"
#include "Litestep.h"
#include "Rainmeter.h"
#include "TrayWindow.h"
#include "../Version.h"
void CheckVersion(void* dummy)
{
HINTERNET hRootHandle = InternetOpen(
L"Rainmeter",
INTERNET_OPEN_TYPE_PRECONFIG,
nullptr,
nullptr,
0);
if (hRootHandle == nullptr)
{
return;
}
HINTERNET hUrlDump = InternetOpenUrl(
hRootHandle, L"http://rainmeter.github.io/rainmeter/release", nullptr, 0, INTERNET_FLAG_RESYNCHRONIZE, 0);
if (hUrlDump)
{
DWORD dwSize;
char urlData[16] = {0};
if (InternetReadFile(hUrlDump, (LPVOID)urlData, sizeof(urlData) - 1, &dwSize))
{
auto parseVersion = [](const WCHAR* str)->int
{
int version = _wtoi(str) * 1000000;
const WCHAR* pos = wcschr(str, L'.');
if (pos)
{
++pos; // Skip .
version += _wtoi(pos) * 1000;
pos = wcschr(pos, '.');
if (pos)
{
++pos; // Skip .
version += _wtoi(pos);
}
}
return version;
};
std::wstring tmpSz = StringUtil::Widen(urlData);
const WCHAR* version = tmpSz.c_str();
int availableVersion = parseVersion(version);
if (availableVersion > RAINMETER_VERSION ||
(revision_beta && availableVersion == RAINMETER_VERSION))
{
GetRainmeter().SetNewVersion();
WCHAR buffer[32];
const WCHAR* dataFile = GetRainmeter().GetDataFile().c_str();
GetPrivateProfileString(L"Rainmeter", L"LastCheck", L"0", buffer, _countof(buffer), dataFile);
// Show tray notification only once per new version
int lastVersion = parseVersion(buffer);
if (availableVersion > lastVersion)
{
GetRainmeter().GetTrayWindow()->ShowUpdateNotification(version);
WritePrivateProfileString(L"Rainmeter", L"LastCheck", version, dataFile);
}
}
}
InternetCloseHandle(hUrlDump);
}
InternetCloseHandle(hRootHandle);
}
void CheckUpdate()
{
_beginthread(CheckVersion, 0, nullptr);
}

View File

@ -1,24 +0,0 @@
/*
Copyright (C) 2004 Kimmo Pekkola
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __UPDATE_CHECK_H__
#define __UPDATE_CHECK_H__
void CheckUpdate();
#endif