コード例 #1
0
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);
				}
			}
		}
	}
}
コード例 #2
0
HMENU ContextMenu::CreateSkinMenu(Skin* skin, 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_ITEM(IDM_SKIN_TRANSPARENCY_100, ID_STR_100PERCENT),
				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_ITEM(IDM_SKIN_FAVORITE, ID_STR_FAVORITE)),
		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)skin->GetWindowZPosition();
			CheckMenuRadioItem(posMenu, checkPos, checkPos, checkPos, MF_BYCOMMAND);

			if (skin->GetXFromRight()) CheckMenuItem(posMenu, IDM_SKIN_FROMRIGHT, MF_BYCOMMAND | MF_CHECKED);
			if (skin->GetYFromBottom()) CheckMenuItem(posMenu, IDM_SKIN_FROMBOTTOM, MF_BYCOMMAND | MF_CHECKED);
			if (skin->GetXPercentage()) CheckMenuItem(posMenu, IDM_SKIN_XPERCENTAGE, MF_BYCOMMAND | MF_CHECKED);
			if (skin->GetYPercentage()) CheckMenuItem(posMenu, IDM_SKIN_YPERCENTAGE, MF_BYCOMMAND | MF_CHECKED);

			HMENU monitorMenu = GetSubMenu(posMenu, 0);
			if (monitorMenu)
			{
				CreateMonitorMenu(monitorMenu, skin);
			}
		}

		// Tick the transparency
		HMENU alphaMenu = GetSubMenu(settingsMenu, 1);
		if (alphaMenu)
		{
			int alpha = skin->GetAlphaValue();
			if (alpha <= 1)	// ~100%
			{
				CheckMenuRadioItem(alphaMenu, 10, 10, 10, MF_BYPOSITION);
			}
			else
			{
				UINT checkPos = (UINT)(10 - alpha / 25.5);
				checkPos = min(9, checkPos);
				checkPos = max(0, checkPos);
				CheckMenuRadioItem(alphaMenu, checkPos, checkPos, checkPos, MF_BYPOSITION);
			}

			switch (skin->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 (skin->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 (skin->GetSnapEdges())
		{
			CheckMenuItem(settingsMenu, IDM_SKIN_SNAPTOEDGES, MF_BYCOMMAND | MF_CHECKED);
		}

		if (skin->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 (skin->GetWindowDraggable())
		{
			CheckMenuItem(settingsMenu, IDM_SKIN_DRAGGABLE, MF_BYCOMMAND | MF_CHECKED);
		}

		if (skin->GetClickThrough())
		{
			CheckMenuItem(settingsMenu, IDM_SKIN_CLICKTHROUGH, MF_BYCOMMAND | MF_CHECKED);
		}

		if (skin->GetKeepOnScreen())
		{
			CheckMenuItem(settingsMenu, IDM_SKIN_KEEPONSCREEN, MF_BYCOMMAND | MF_CHECKED);
		}

		if (Gfx::CanvasD2D::Initialize())
		{
			if (!Rainmeter::GetInstance().GetUseD2D())
			{
				EnableMenuItem(settingsMenu, IDM_SKIN_USED2D, MF_BYCOMMAND | MF_GRAYED);
			}
			else if (skin->GetUseD2D())
			{
				CheckMenuItem(settingsMenu, IDM_SKIN_USED2D, MF_BYCOMMAND | MF_CHECKED);
			}
		}
		else
		{
			DeleteMenu(settingsMenu, IDM_SKIN_USED2D, MF_BYCOMMAND);
		}
		Gfx::CanvasD2D::Finalize();

		if (skin->GetFavorite())
		{
			CheckMenuItem(settingsMenu, IDM_SKIN_FAVORITE, MF_BYCOMMAND | MF_CHECKED);
		}
	}

	// Add the name of the Skin to the menu
	const std::wstring& skinName = skin->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].filename.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 = skin->GetFolderPath();
		std::wstring::size_type pos = root.find_first_of(L'\\');
		if (pos != std::wstring::npos)
		{
			root.erase(pos);
		}

		// Skip "Open folder", "Disable dragging" and a separator
		for (int i = 3; 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(skin, index, skinMenu, false);

	return skinMenu;
}
コード例 #3
0
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 (!Rainmeter::GetInstance().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;
				}
			}
		}
	}

	// 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
			const 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
					{
						const UINT_PTR id = (index << 16) | (IDM_SKIN_CUSTOMCONTEXTMENU_FIRST + i);
						InsertMenu(skinMenu, position + 1, MF_BYPOSITION | MF_STRING, id, 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
					{
						const UINT_PTR id = (index << 16) | (IDM_SKIN_CUSTOMCONTEXTMENU_FIRST + i);
						AppendMenu(customMenu, MF_BYPOSITION | MF_STRING, id, cTitles[i].c_str());
					}
				}

				InsertMenu(skinMenu, 1, MF_BYPOSITION | MF_SEPARATOR, 0, nullptr);
			}
		}
	}

	return skinMenu;
}