mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Move context menu related code into ContextMenu.cpp
This commit is contained in:
parent
a4b36423b9
commit
a4c7e83391
646
Library/ContextMenu.cpp
Normal file
646
Library/ContextMenu.cpp
Normal file
@ -0,0 +1,646 @@
|
|||||||
|
/*
|
||||||
|
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 "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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rainmeter& rainmeter = GetRainmeter();
|
||||||
|
|
||||||
|
m_MenuActive = true;
|
||||||
|
|
||||||
|
// Show context menu, if no actions were executed
|
||||||
|
HMENU menu = MenuTemplate::CreateMenu(s_Menu, _countof(s_Menu), GetString);
|
||||||
|
if (menu)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the window to foreground
|
||||||
|
hWnd = meterWindow ? meterWindow->GetWindow() : rainmeter.m_TrayWindow->GetWindow();
|
||||||
|
HWND hWndForeground = GetForegroundWindow();
|
||||||
|
if (hWndForeground != hWnd)
|
||||||
|
{
|
||||||
|
DWORD foregroundThreadID = GetWindowThreadProcessId(hWndForeground, nullptr);
|
||||||
|
DWORD currentThreadID = GetCurrentThreadId();
|
||||||
|
AttachThreadInput(currentThreadID, foregroundThreadID, TRUE);
|
||||||
|
SetForegroundWindow(hWnd);
|
||||||
|
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,
|
||||||
|
hWnd,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
if (meterWindow)
|
||||||
|
{
|
||||||
|
DestroyMenu(menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DestroyMenu(menu);
|
||||||
|
|
||||||
|
m_MenuActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_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)
|
||||||
|
{
|
||||||
|
// Tick the position
|
||||||
|
HMENU settingsMenu = GetSubMenu(skinMenu, 4);
|
||||||
|
if (settingsMenu)
|
||||||
|
{
|
||||||
|
HMENU posMenu = GetSubMenu(settingsMenu, 0);
|
||||||
|
if (posMenu)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add custom actions to the context menu
|
||||||
|
std::wstring contextTitle = meterWindow->GetParser().ReadString(L"Rainmeter", L"ContextTitle", L"");
|
||||||
|
if (!contextTitle.empty())
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
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
|
||||||
|
size_t titleSize = cTitles.size();
|
||||||
|
if (titleSize <= 3)
|
||||||
|
{
|
||||||
|
size_t position = 0;
|
||||||
|
for (size_t i = 0; i < titleSize; ++i)
|
||||||
|
{
|
||||||
|
if (isTitleSeparator(cTitles[i]))
|
||||||
|
{
|
||||||
|
// Separators not allowed in main top-level menu
|
||||||
|
--position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InsertMenu(skinMenu, position + 1, MF_BYPOSITION | MF_STRING, (index << 16) | (IDM_SKIN_CUSTOMCONTEXTMENU_FIRST + i), cTitles[i].c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
++position;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position != 0)
|
||||||
|
{
|
||||||
|
InsertMenu(skinMenu, 1, MF_BYPOSITION | MF_STRING | MF_GRAYED, 0, L"Custom skin actions");
|
||||||
|
InsertMenu(skinMenu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HMENU customMenu = CreatePopupMenu();
|
||||||
|
InsertMenu(skinMenu, 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
|
||||||
|
{
|
||||||
|
AppendMenu(customMenu, MF_BYPOSITION | MF_STRING, (index << 16) | (IDM_SKIN_CUSTOMCONTEXTMENU_FIRST + i), cTitles[i].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertMenu(skinMenu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return skinMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
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, i, MF_BYPOSITION, ID_THEME_FIRST + i, layouts[i].c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContextMenu::CreateMonitorMenu(HMENU monitorMenu, MeterWindow* meterWindow)
|
||||||
|
{
|
||||||
|
bool screenDefined = meterWindow->GetXScreenDefined();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
InsertMenu(monitorMenu,
|
||||||
|
i + 2,
|
||||||
|
MF_BYPOSITION | ((screenDefined && screenIndex == i) ? MF_CHECKED : MF_UNCHECKED) | ((!(*iter).active) ? MF_GRAYED : MF_ENABLED),
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
50
Library/ContextMenu.h
Normal file
50
Library/ContextMenu.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
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();
|
||||||
|
|
||||||
|
bool IsMenuActive() { return m_MenuActive; }
|
||||||
|
|
||||||
|
void ShowMenu(POINT pos, MeterWindow* meterWindow);
|
||||||
|
|
||||||
|
static void CreateMonitorMenu(HMENU monitorMenu, MeterWindow* meterWindow);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static HMENU CreateSkinMenu(MeterWindow* meterWindow, int index, HMENU menu);
|
||||||
|
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
|
@ -1185,7 +1185,7 @@ INT_PTR DialogManage::TabSkins::OnCommand(WPARAM wParam, LPARAM lParam)
|
|||||||
HMENU menu = MenuTemplate::CreateMenu(s_Menu, _countof(s_Menu), GetString);
|
HMENU menu = MenuTemplate::CreateMenu(s_Menu, _countof(s_Menu), GetString);
|
||||||
if (menu)
|
if (menu)
|
||||||
{
|
{
|
||||||
GetRainmeter().CreateMonitorMenu(menu, m_SkinWindow);
|
ContextMenu::CreateMonitorMenu(menu, m_SkinWindow);
|
||||||
|
|
||||||
RECT r;
|
RECT r;
|
||||||
GetWindowRect((HWND)lParam, &r);
|
GetWindowRect((HWND)lParam, &r);
|
||||||
|
@ -90,6 +90,9 @@
|
|||||||
<ClCompile Include="ConfigParser_Test.cpp">
|
<ClCompile Include="ConfigParser_Test.cpp">
|
||||||
<ExcludedFromBuild>$(ExcludeTests)</ExcludedFromBuild>
|
<ExcludedFromBuild>$(ExcludeTests)</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="ContextMenu.cpp">
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="DialogAbout.cpp">
|
<ClCompile Include="DialogAbout.cpp">
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -315,6 +318,7 @@
|
|||||||
<ClInclude Include="..\Common\Gfx\Util\WICBitmapLockGDIP.h" />
|
<ClInclude Include="..\Common\Gfx\Util\WICBitmapLockGDIP.h" />
|
||||||
<ClInclude Include="CommandHandler.h" />
|
<ClInclude Include="CommandHandler.h" />
|
||||||
<ClInclude Include="ConfigParser.h" />
|
<ClInclude Include="ConfigParser.h" />
|
||||||
|
<ClInclude Include="ContextMenu.h" />
|
||||||
<ClInclude Include="DialogAbout.h" />
|
<ClInclude Include="DialogAbout.h" />
|
||||||
<ClInclude Include="Error.h" />
|
<ClInclude Include="Error.h" />
|
||||||
<ClInclude Include="Group.h" />
|
<ClInclude Include="Group.h" />
|
||||||
|
@ -387,6 +387,9 @@
|
|||||||
<ClCompile Include="SkinRegistry_Test.cpp">
|
<ClCompile Include="SkinRegistry_Test.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="ContextMenu.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="ConfigParser.h">
|
<ClInclude Include="ConfigParser.h">
|
||||||
@ -662,6 +665,9 @@
|
|||||||
<ClInclude Include="SkinRegistry.h">
|
<ClInclude Include="SkinRegistry.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="ContextMenu.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="Library.rc">
|
<ResourceCompile Include="Library.rc">
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "../Common/MenuTemplate.h"
|
|
||||||
#include "../Common/PathUtil.h"
|
#include "../Common/PathUtil.h"
|
||||||
#include "Rainmeter.h"
|
#include "Rainmeter.h"
|
||||||
#include "TrayWindow.h"
|
#include "TrayWindow.h"
|
||||||
@ -28,7 +27,6 @@
|
|||||||
#include "MeasureNet.h"
|
#include "MeasureNet.h"
|
||||||
#include "MeasureCPU.h"
|
#include "MeasureCPU.h"
|
||||||
#include "MeterString.h"
|
#include "MeterString.h"
|
||||||
#include "resource.h"
|
|
||||||
#include "UpdateCheck.h"
|
#include "UpdateCheck.h"
|
||||||
#include "../Version.h"
|
#include "../Version.h"
|
||||||
|
|
||||||
@ -115,7 +113,6 @@ Rainmeter::Rainmeter() :
|
|||||||
m_DesktopWorkAreaChanged(false),
|
m_DesktopWorkAreaChanged(false),
|
||||||
m_DesktopWorkAreaType(false),
|
m_DesktopWorkAreaType(false),
|
||||||
m_NormalStayDesktop(true),
|
m_NormalStayDesktop(true),
|
||||||
m_MenuActive(false),
|
|
||||||
m_DisableRDP(false),
|
m_DisableRDP(false),
|
||||||
m_DisableDragging(false),
|
m_DisableDragging(false),
|
||||||
m_CurrentParser(),
|
m_CurrentParser(),
|
||||||
@ -1708,610 +1705,6 @@ int Rainmeter::ShowMessage(HWND parent, const WCHAR* text, UINT type)
|
|||||||
return MessageBox(parent, text, APPNAME, type);
|
return MessageBox(parent, text, APPNAME, type);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
** Opens the context menu in given coordinates.
|
|
||||||
**
|
|
||||||
*/
|
|
||||||
void Rainmeter::ShowContextMenu(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()))
|
|
||||||
{
|
|
||||||
m_MenuActive = true;
|
|
||||||
|
|
||||||
// Show context menu, if no actions were executed
|
|
||||||
HMENU menu = MenuTemplate::CreateMenu(s_Menu, _countof(s_Menu), GetString);
|
|
||||||
if (menu)
|
|
||||||
{
|
|
||||||
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 (m_Debug)
|
|
||||||
{
|
|
||||||
CheckMenuItem(menu, IDM_DEBUGLOG, MF_BYCOMMAND | MF_CHECKED);
|
|
||||||
}
|
|
||||||
|
|
||||||
HMENU allSkinsMenu = GetSubMenu(menu, 4);
|
|
||||||
if (allSkinsMenu)
|
|
||||||
{
|
|
||||||
if (!m_SkinRegistry.IsEmpty())
|
|
||||||
{
|
|
||||||
DeleteMenu(allSkinsMenu, 0, MF_BYPOSITION); // "No skins available" menuitem
|
|
||||||
CreateAllSkinsMenu(allSkinsMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_DisableDragging)
|
|
||||||
{
|
|
||||||
CheckMenuItem(allSkinsMenu, IDM_DISABLEDRAG, MF_BYCOMMAND | MF_CHECKED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HMENU layoutMenu = GetSubMenu(menu, 5);
|
|
||||||
if (layoutMenu)
|
|
||||||
{
|
|
||||||
if (!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 = m_MeterWindows.begin();
|
|
||||||
for (; iter != 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 (m_NewVersion)
|
|
||||||
{
|
|
||||||
InsertMenu(menu, 0, MF_BYPOSITION, IDM_NEW_VERSION, GetString(ID_STR_UPDATEAVAILABLE));
|
|
||||||
HiliteMenuItem(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 = GetMeterWindow(hWnd);
|
|
||||||
if (mw)
|
|
||||||
{
|
|
||||||
// Cancel the mouse event beforehand
|
|
||||||
mw->SetMouseLeaveEvent(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the window to foreground
|
|
||||||
hWnd = meterWindow ? meterWindow->GetWindow() : m_TrayWindow->GetWindow();
|
|
||||||
HWND hWndForeground = GetForegroundWindow();
|
|
||||||
if (hWndForeground != hWnd)
|
|
||||||
{
|
|
||||||
DWORD foregroundThreadID = GetWindowThreadProcessId(hWndForeground, nullptr);
|
|
||||||
DWORD currentThreadID = GetCurrentThreadId();
|
|
||||||
AttachThreadInput(currentThreadID, foregroundThreadID, TRUE);
|
|
||||||
SetForegroundWindow(hWnd);
|
|
||||||
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,
|
|
||||||
hWnd,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
DestroyMenu(menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_MenuActive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Rainmeter::CreateAllSkinsMenuRecursive(HMENU skinMenu, int index)
|
|
||||||
{
|
|
||||||
const int initialLevel = m_SkinRegistry.GetFolder(index).level;
|
|
||||||
int menuIndex = 0;
|
|
||||||
|
|
||||||
const size_t max = m_SkinRegistry.GetFolderCount();
|
|
||||||
while (index < max)
|
|
||||||
{
|
|
||||||
const SkinRegistry::Folder& skinFolder = m_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 && m_SkinRegistry.GetFolder(index + 1).level == initialLevel + 1;
|
|
||||||
if (hasSubfolder)
|
|
||||||
{
|
|
||||||
index = CreateAllSkinsMenuRecursive(subMenu, index + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add files
|
|
||||||
{
|
|
||||||
int fileIndex = 0;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
HMENU Rainmeter::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_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)
|
|
||||||
{
|
|
||||||
// Tick the position
|
|
||||||
HMENU settingsMenu = GetSubMenu(skinMenu, 4);
|
|
||||||
if (settingsMenu)
|
|
||||||
{
|
|
||||||
HMENU posMenu = GetSubMenu(settingsMenu, 0);
|
|
||||||
if (posMenu)
|
|
||||||
{
|
|
||||||
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 (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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 = *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)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add custom actions to the context menu
|
|
||||||
std::wstring contextTitle = meterWindow->GetParser().ReadString(L"Rainmeter", L"ContextTitle", L"");
|
|
||||||
if (!contextTitle.empty())
|
|
||||||
{
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
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
|
|
||||||
size_t titleSize = cTitles.size();
|
|
||||||
if (titleSize <= 3)
|
|
||||||
{
|
|
||||||
size_t position = 0;
|
|
||||||
for (size_t i = 0; i < titleSize; ++i)
|
|
||||||
{
|
|
||||||
if (isTitleSeparator(cTitles[i]))
|
|
||||||
{
|
|
||||||
// Separators not allowed in main top-level menu
|
|
||||||
--position;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
InsertMenu(skinMenu, position + 1, MF_BYPOSITION | MF_STRING, (index << 16) | (IDM_SKIN_CUSTOMCONTEXTMENU_FIRST + i), cTitles[i].c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
++position;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (position != 0)
|
|
||||||
{
|
|
||||||
InsertMenu(skinMenu, 1, MF_BYPOSITION | MF_STRING | MF_GRAYED, 0, L"Custom skin actions");
|
|
||||||
InsertMenu(skinMenu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
HMENU customMenu = CreatePopupMenu();
|
|
||||||
InsertMenu(skinMenu, 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
|
|
||||||
{
|
|
||||||
AppendMenu(customMenu, MF_BYPOSITION | MF_STRING, (index << 16) | (IDM_SKIN_CUSTOMCONTEXTMENU_FIRST + i), cTitles[i].c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InsertMenu(skinMenu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return skinMenu;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rainmeter::CreateLayoutMenu(HMENU layoutMenu)
|
|
||||||
{
|
|
||||||
for (size_t i = 0, isize = m_Layouts.size(); i < isize; ++i)
|
|
||||||
{
|
|
||||||
InsertMenu(layoutMenu, i, MF_BYPOSITION, ID_THEME_FIRST + i, m_Layouts[i].c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rainmeter::CreateMonitorMenu(HMENU monitorMenu, MeterWindow* meterWindow)
|
|
||||||
{
|
|
||||||
bool screenDefined = meterWindow->GetXScreenDefined();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
InsertMenu(monitorMenu,
|
|
||||||
i + 2,
|
|
||||||
MF_BYPOSITION | ((screenDefined && screenIndex == i) ? MF_CHECKED : MF_UNCHECKED) | ((!(*iter).active) ? MF_GRAYED : MF_ENABLED),
|
|
||||||
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 Rainmeter::ChangeSkinIndex(HMENU menu, int index)
|
|
||||||
{
|
|
||||||
if (index > 0)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rainmeter::ShowLogFile()
|
void Rainmeter::ShowLogFile()
|
||||||
{
|
{
|
||||||
std::wstring logFile = L'"' + GetLogger().GetLogFilePath();
|
std::wstring logFile = L'"' + GetLogger().GetLogFilePath();
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "CommandHandler.h"
|
#include "CommandHandler.h"
|
||||||
|
#include "ContextMenu.h"
|
||||||
#include "Logger.h"
|
#include "Logger.h"
|
||||||
#include "MeterWindow.h"
|
#include "MeterWindow.h"
|
||||||
#include "SkinRegistry.h"
|
#include "SkinRegistry.h"
|
||||||
@ -162,8 +163,8 @@ public:
|
|||||||
|
|
||||||
int ShowMessage(HWND parent, const WCHAR* text, UINT type);
|
int ShowMessage(HWND parent, const WCHAR* text, UINT type);
|
||||||
|
|
||||||
bool IsMenuActive() { return m_MenuActive; }
|
bool IsMenuActive() { return m_ContextMenu.IsMenuActive(); }
|
||||||
void ShowContextMenu(POINT pos, MeterWindow* meterWindow);
|
void ShowContextMenu(POINT pos, MeterWindow* mw) { return m_ContextMenu.ShowMenu(pos, mw); }
|
||||||
|
|
||||||
const std::wstring& GetTrayExecuteR() { return m_TrayExecuteR; }
|
const std::wstring& GetTrayExecuteR() { return m_TrayExecuteR; }
|
||||||
const std::wstring& GetTrayExecuteM() { return m_TrayExecuteM; }
|
const std::wstring& GetTrayExecuteM() { return m_TrayExecuteM; }
|
||||||
@ -180,6 +181,7 @@ public:
|
|||||||
void PreserveSetting(const std::wstring& from, LPCTSTR key, bool replace = true);
|
void PreserveSetting(const std::wstring& from, LPCTSTR key, bool replace = true);
|
||||||
|
|
||||||
friend class CommandHandler;
|
friend class CommandHandler;
|
||||||
|
friend class ContextMenu;
|
||||||
friend class DialogManage;
|
friend class DialogManage;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -199,14 +201,7 @@ private:
|
|||||||
void SetLoadOrder(int folderIndex, int order);
|
void SetLoadOrder(int folderIndex, int order);
|
||||||
int GetLoadOrder(const std::wstring& folderPath);
|
int GetLoadOrder(const std::wstring& folderPath);
|
||||||
void UpdateDesktopWorkArea(bool reset);
|
void UpdateDesktopWorkArea(bool reset);
|
||||||
HMENU CreateSkinMenu(MeterWindow* meterWindow, int index, HMENU menu);
|
|
||||||
void ChangeSkinIndex(HMENU subMenu, int index);
|
|
||||||
|
|
||||||
void CreateAllSkinsMenu(HMENU skinMenu) { CreateAllSkinsMenuRecursive(skinMenu, 0); }
|
|
||||||
int CreateAllSkinsMenuRecursive(HMENU skinMenu, int index);
|
|
||||||
|
|
||||||
void CreateLayoutMenu(HMENU layoutMenu);
|
|
||||||
void CreateMonitorMenu(HMENU monitorMenu, MeterWindow* meterWindow);
|
|
||||||
void CreateOptionsFile();
|
void CreateOptionsFile();
|
||||||
void CreateDataFile();
|
void CreateDataFile();
|
||||||
void CreateComponentFolders(bool defaultIniLocation);
|
void CreateComponentFolders(bool defaultIniLocation);
|
||||||
@ -249,8 +244,6 @@ private:
|
|||||||
|
|
||||||
bool m_NormalStayDesktop;
|
bool m_NormalStayDesktop;
|
||||||
|
|
||||||
bool m_MenuActive;
|
|
||||||
|
|
||||||
bool m_DisableRDP;
|
bool m_DisableRDP;
|
||||||
|
|
||||||
bool m_DisableDragging;
|
bool m_DisableDragging;
|
||||||
@ -258,7 +251,7 @@ private:
|
|||||||
std::wstring m_SkinEditor;
|
std::wstring m_SkinEditor;
|
||||||
|
|
||||||
CommandHandler m_CommandHandler;
|
CommandHandler m_CommandHandler;
|
||||||
|
ContextMenu m_ContextMenu;
|
||||||
SkinRegistry m_SkinRegistry;
|
SkinRegistry m_SkinRegistry;
|
||||||
|
|
||||||
ConfigParser* m_CurrentParser;
|
ConfigParser* m_CurrentParser;
|
||||||
|
Loading…
Reference in New Issue
Block a user