Files
Open-Shell-Menu/Src/StartMenu/StartMenuDLL/CustomMenu.cpp
thisismy-github bb26cec0ec Added option to single-expand any Win7 style item
Expands the "display as a list of drives" option from This PC to work on
almost any item in the Windows 7 style. Incompatible items have a new
setting called ITEM_NODRIVES which blocks the option from appearing.
This PC still uses the original "list of drives" text, while other items
use "list of links" instead. Sorting has been updated to account for
this option by adding a property called bFolderLink which marks any
folder, even if it is not explicitly expandable.
2022-08-13 16:00:26 -04:00

619 lines
21 KiB
C++

// Classic Shell (c) 2009-2017, Ivo Beltchev
// Open-Shell (c) 2017-2018, The Open-Shell Team
// Confidential information of Ivo Beltchev. Not for disclosure or distribution without prior written consent from the author
#include "stdafx.h"
#include "CustomMenu.h"
#include "SettingsParser.h"
#include "Translations.h"
#include "MenuContainer.h"
#include "Settings.h"
#include "SettingsUI.h"
#include "FNVHash.h"
#include "ResourceHelper.h"
#include "resource.h"
#include <algorithm>
// This table defines the standard menu items
static StdMenuItem g_StdMenu[]=
{
// * means the command is not executable (for things like Settings, or for items that have FOLDERID)
{L"*programs",MENU_PROGRAMS,&FOLDERID_Programs,&FOLDERID_CommonPrograms},
{L"*favorites",MENU_FAVORITES,&FOLDERID_Favorites},
{L"*computer",MENU_COMPUTER,&FOLDERID_ComputerFolder},
{L"*recent_documents",MENU_DOCUMENTS,&FOLDERID_Recent},
{L"*settings",MENU_SETTINGS},
{L"*search",MENU_SEARCH},
{L"help",MENU_HELP},
{L"run",MENU_RUN},
{L"logoff",MENU_LOGOFF},
{L"undock",MENU_UNDOCK},
{L"monitor_off",MENU_MONITOROFF},
{L"disconnect",MENU_DISCONNECT},
{L"shutdown_box",MENU_SHUTDOWN_BOX},
{L"*user_files",MENU_USERFILES,&FOLDERID_UsersFiles},
{L"*user_documents",MENU_USERDOCUMENTS,&FOLDERID_Documents},
{L"*user_pictures",MENU_USERPICTURES,&FOLDERID_Pictures},
{L"*control_panel",MENU_CONTROLPANEL,&FOLDERID_ControlPanelFolder},
{L"pc_settings",MENU_PCSETTINGS},
{L"windows_security",MENU_SECURITY},
{L"*network_connections",MENU_NETWORK,&FOLDERID_ConnectionsFolder},
{L"*printers",MENU_PRINTERS,&FOLDERID_PrintersFolder},
{L"taskbar_settings",MENU_TASKBAR},
{L"programs_features",MENU_FEATURES},
{L"menu_settings",MENU_CLASSIC_SETTINGS},
{L"search_files",MENU_SEARCH_FILES},
{L"search_printer",MENU_SEARCH_PRINTER},
{L"search_computers",MENU_SEARCH_COMPUTERS},
{L"search_people",MENU_SEARCH_PEOPLE},
{L"sleep",MENU_SLEEP},
{L"hibernate",MENU_HIBERNATE},
{L"restart",MENU_RESTART},
{L"restart_noupdate",MENU_RESTART_NOUPDATE},
{L"shutdown",MENU_SHUTDOWN},
{L"shutdown_noupdate",MENU_SHUTDOWN_NOUPDATE},
{L"switch_user",MENU_SWITCHUSER},
{L"lock",MENU_LOCK},
{L"*recent_programs",MENU_RECENT_PROGRAMS},
{L"search_box",MENU_SEARCH_BOX},
{L"*apps",MENU_APPS},
{L"*fonts",MENU_CUSTOM,&FOLDERID_Fonts},
{L"*desktop",MENU_CUSTOM,&FOLDERID_Desktop},
{L"*admin",MENU_CUSTOM,&FOLDERID_CommonAdminTools,&FOLDERID_AdminTools},
{L"*startup",MENU_CUSTOM,&FOLDERID_Startup,&FOLDERID_CommonStartup},
{L"*user_music",MENU_CUSTOM,&FOLDERID_Music},
{L"*user_videos",MENU_CUSTOM,&FOLDERID_Videos},
{L"*downloads",MENU_CUSTOM,&FOLDERID_Downloads},
{L"*games",MENU_CUSTOM,&FOLDERID_Games},
{L"*links",MENU_CUSTOM,&FOLDERID_Links},
{L"*libraries",MENU_CUSTOM,&FOLDERID_Libraries},
{L"*lib_documents",MENU_CUSTOM,&FOLDERID_DocumentsLibrary},
{L"*lib_music",MENU_CUSTOM,&FOLDERID_MusicLibrary},
{L"*lib_pictures",MENU_CUSTOM,&FOLDERID_PicturesLibrary},
{L"*lib_videos",MENU_CUSTOM,&FOLDERID_VideosLibrary},
{L"*lib_tv",MENU_CUSTOM,&FOLDERID_RecordedTVLibrary},
{L"*homegroup",MENU_CUSTOM,&FOLDERID_HomeGroup},
{L"*network",MENU_CUSTOM,&FOLDERID_NetworkFolder},
{L"*devices",MENU_CUSTOM},
{L"*defaults",MENU_CUSTOM},
};
CStdCommand7 g_StdCommands7[]={
{L"separator",IDS_SEPARATOR_ITEM,NULL,NULL,NULL,NULL,NULL,0,CStdCommand7::ITEM_SINGLE}, // must be first
{L"favorites",0,NULL,NULL,L"imageres.dll,1024",&FOLDERID_Favorites,NULL,StdMenuItem::MENU_TRACK},
{L"recent_documents",0,NULL,NULL,NULL,&FOLDERID_Recent},
{L"computer",0,NULL,NULL,NULL,&FOLDERID_ComputerFolder,NULL,0,CStdCommand7::ITEM_COMPUTER},
{L"help",IDS_HELP_ITEM,L"$Menu.Help",L"$Menu.HelpTip",L"imageres.dll,99",NULL,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"run",IDS_RUN_ITEM,L"$Menu.Run",L"$Menu.RunTip",L"imageres.dll,100",NULL,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"windows_security",IDS_SECURITY_ITEM,L"$Menu.Security",L"$Menu.SecurityTip",L"shell32.dll,48",NULL,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"user_files",IDS_SHOW_USERFILES,NULL,L"$Menu.UserFilesTip",NULL,&FOLDERID_UsersFiles},
{L"user_documents",0,NULL,L"$Menu.UserDocumentsTip",NULL,&FOLDERID_Documents},
{L"user_pictures",0,NULL,L"$Menu.UserPicturesTip",NULL,&FOLDERID_Pictures},
{L"user_music",0,NULL,L"$Menu.UserMusicTip",NULL,&FOLDERID_Music},
{L"user_videos",0,NULL,L"$Menu.UserVideosTip",NULL,&FOLDERID_Videos},
{L"control_panel",0,L"$Menu.ControlPanel",L"$Menu.ControlPanelTip",NULL,&FOLDERID_ControlPanelFolder,NULL,StdMenuItem::MENU_TRACK},
{L"pc_settings",IDS_PCSETTINGS,L"$Menu.PCSettings",L"",L"%windir%\\ImmersiveControlPanel\\SystemSettings.exe,10",NULL,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_SINGLE},
{L"network_connections",0,NULL,L"$Menu.NetworkTip",NULL,&FOLDERID_ConnectionsFolder,NULL,0,CStdCommand7::ITEM_NODRIVES},
{L"network",0,NULL,NULL,NULL,&FOLDERID_NetworkFolder,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"printers",0,NULL,L"$Menu.PrintersTip",NULL,&FOLDERID_PrintersFolder,NULL,0,CStdCommand7::ITEM_NODRIVES},
{L"fonts",0,NULL,NULL,NULL,&FOLDERID_Fonts},
{L"desktop",0,NULL,NULL,NULL,&FOLDERID_Desktop},
{L"admin",0,NULL,L"$Menu.AdminToolsTip",L"imageres.dll,114",&FOLDERID_CommonAdminTools,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_NODRIVES},
{L"startup",0,NULL,NULL,NULL,&FOLDERID_Startup,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_NODRIVES},
{L"downloads",0,NULL,L"$Menu.DownloadTip",NULL,&FOLDERID_Downloads},
{L"games",0,NULL,L"$Menu.GamesTip",NULL,&FOLDERID_Games,NULL,StdMenuItem::MENU_TRACK},
{L"links",0,NULL,NULL,NULL,&FOLDERID_Links},
{L"libraries",0,NULL,NULL,NULL,&FOLDERID_Libraries},
{L"lib_documents",IDS_LIB_DOCS_ITEM,NULL,L"$Menu.DocumentsLibTip",NULL,&FOLDERID_DocumentsLibrary},
{L"lib_music",IDS_LIB_MUSIC_ITEM,NULL,L"$Menu.MusicLibTip",NULL,&FOLDERID_MusicLibrary},
{L"lib_pictures",IDS_LIB_PICS_ITEM,NULL,L"$Menu.PicturesLibTip",NULL,&FOLDERID_PicturesLibrary},
{L"lib_videos",IDS_LIB_VIDEOS_ITEM,NULL,L"$Menu.VideosLibTip",NULL,&FOLDERID_VideosLibrary},
{L"lib_tv",IDS_LIB_TV_ITEM,NULL,L"$Menu.RecordingsLibTip",NULL,&FOLDERID_RecordedTVLibrary},
{L"homegroup",0,NULL,L"$Menu.HomegroupTip",NULL,&FOLDERID_HomeGroup,NULL,0,CStdCommand7::ITEM_SINGLE},
{L"devices",0,NULL,NULL,NULL,NULL,L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{A8A91A66-3A7D-4424-8D24-04E180695C7A}",0,CStdCommand7::ITEM_NODRIVES},
{L"defaults",0,NULL,NULL,NULL,NULL,L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\0\\::{17CD9488-1228-4B2F-88CE-4298E93E0966}",0,CStdCommand7::ITEM_SINGLE},
{L"apps",IDS_METRO_APPS,L"$Menu.Apps",NULL,L",2",NULL,NULL,StdMenuItem::MENU_TRACK,CStdCommand7::ITEM_FOLDER},
{L"",IDS_CUSTOM_ITEM} // must be last
};
const int g_StdCommands7Count=_countof(g_StdCommands7);
// This table defines folders that need special treatment
SpecialFolder g_SpecialFolders[]=
{
{&FOLDERID_Games,SpecialFolder::FOLDER_NONEWFOLDER},
{&FOLDERID_ComputerFolder,SpecialFolder::FOLDER_NONEWFOLDER},
{&FOLDERID_RecycleBinFolder,SpecialFolder::FOLDER_NOSUBFOLDERS|SpecialFolder::FOLDER_NODROP},
{&FOLDERID_NetworkFolder,SpecialFolder::FOLDER_NODROP},
{&FOLDERID_ConnectionsFolder,SpecialFolder::FOLDER_NODROP|SpecialFolder::FOLDER_NOPATH},
{&FOLDERID_Recent,SpecialFolder::FOLDER_NODROP},
{&FOLDERID_ControlPanelFolder,SpecialFolder::FOLDER_NODROP},
{&FOLDERID_PrintersFolder,SpecialFolder::FOLDER_NODROP},
{&FOLDERID_HomeGroup,SpecialFolder::FOLDER_NODROP},
{NULL}
};
static std::vector<StdMenuItem> g_CustomMenu;
static unsigned int g_RootSettings;
static unsigned int g_MenuItemsHash;
static CSettingsParser g_CustomMenuParser;
static bool g_bSpecialFoldersInitialized;
void InitializeSpecialFolders( void )
{
if (!g_bSpecialFoldersInitialized)
{
g_bSpecialFoldersInitialized=true;
for (int i=0;g_SpecialFolders[i].folder;i++)
{
CComPtr<IShellItem> pItem;
if (SUCCEEDED(ShGetKnownFolderItem(*g_SpecialFolders[i].folder,&pItem)) && pItem)
{
CComString pPath;
pItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING,&pPath);
pPath.MakeUpper();
Strcpy(g_SpecialFolders[i].PATH,_countof(g_SpecialFolders[i].PATH),pPath);
}
}
}
}
static const StdMenuItem *FindStdMenuItem( const wchar_t *command )
{
for (int i=0;i<_countof(g_StdMenu);i++)
{
const wchar_t *cmd=g_StdMenu[i].command;
if (*cmd=='*') cmd++;
if (_wcsicmp(cmd,command)==0)
return &g_StdMenu[i];
}
return NULL;
}
static unsigned int ParseItemSettings( const wchar_t *name )
{
wchar_t buf[256];
Sprintf(buf,_countof(buf),L"%s.Settings",name);
const wchar_t *str=g_CustomMenuParser.FindSetting(buf);
if (!str) return 0;
unsigned int settings=0;
while(*str)
{
wchar_t token[256];
str=GetToken(str,token,_countof(token),L", \t|;");
if (_wcsicmp(token,L"OPEN_UP")==0) settings|=StdMenuItem::MENU_OPENUP;
if (_wcsicmp(token,L"OPEN_UP_CHILDREN")==0) settings|=StdMenuItem::MENU_OPENUP_REC;
if (_wcsicmp(token,L"SORT_ZA")==0) settings|=StdMenuItem::MENU_SORTZA;
if (_wcsicmp(token,L"SORT_ZA_CHILDREN")==0) settings|=StdMenuItem::MENU_SORTZA_REC;
if (_wcsicmp(token,L"SORT_ONCE")==0) settings|=StdMenuItem::MENU_SORTONCE;
if (_wcsicmp(token,L"ITEMS_FIRST")==0) settings|=StdMenuItem::MENU_ITEMS_FIRST;
if (_wcsicmp(token,L"TRACK_RECENT")==0) settings|=StdMenuItem::MENU_TRACK;
if (_wcsicmp(token,L"NOTRACK_RECENT")==0) settings|=StdMenuItem::MENU_NOTRACK;
if (_wcsicmp(token,L"NOEXPAND")==0) settings|=StdMenuItem::MENU_NOEXPAND;
if (_wcsicmp(token,L"SINGLE_EXPAND")==0) settings|=StdMenuItem::MENU_SINGLE_EXPAND;
if (_wcsicmp(token,L"MULTICOLUMN")==0) settings|=StdMenuItem::MENU_MULTICOLUMN;
if (_wcsicmp(token,L"NOEXTENSIONS")==0) settings|=StdMenuItem::MENU_NOEXTENSIONS;
if (_wcsicmp(token,L"INLINE")==0) settings|=StdMenuItem::MENU_INLINE;
if (_wcsicmp(token,L"SPLIT")==0) settings|=StdMenuItem::MENU_SPLIT_BUTTON;
}
return settings;
}
static void ParseMenuItem( StdMenuItem &item, const wchar_t *name )
{
wchar_t buf[1024];
const wchar_t *str;
Sprintf(buf,_countof(buf),L"%s.Link",name);
str=g_CustomMenuParser.FindSetting(buf);
if (str)
{
// parse link
item.link=str;
const wchar_t *c=wcschr(item.link,'|');
if (c)
{
for (c++;*c==' ';)
c++;
item.link=c;
}
}
Sprintf(buf,_countof(buf),L"%s.Command",name);
str=g_CustomMenuParser.FindSetting(buf);
int custom7=-1;
if (str)
{
// parse command
const StdMenuItem *pItem=FindStdMenuItem(str);
if (pItem)
{
item.id=pItem->id;
item.folder1=pItem->folder1;
item.folder2=pItem->folder2;
if (item.id==MENU_CONTROLPANEL && GetSettingBool(L"ControlPanelCategories"))
item.command=L"::{26EE0668-A00A-44D7-9371-BEB064C98683}";
else if (item.id==MENU_SHUTDOWN_BOX && GetSettingInt(L"MenuStyle")==MENU_WIN7)
item.id=MENU_SHUTDOWN_BUTTON;
else if (*pItem->command!='*')
item.command=pItem->command;
}
else
{
item.id=MENU_CUSTOM;
item.command=str;
}
for (int i=0;i<g_StdCommands7Count;i++)
if (_wcsicmp(g_StdCommands7[i].command,str)==0)
{
custom7=i;
break;
}
}
Sprintf(buf,_countof(buf),L"%s.Label",name);
str=g_CustomMenuParser.FindSetting(buf);
if (str)
{
// parse name
if (*str=='$')
{
item.label=FindTranslation(str+1,NULL);
if (!item.label)
item.label=str;
}
else
item.label=str;
}
Sprintf(buf,_countof(buf),L"%s.Tip",name);
str=g_CustomMenuParser.FindSetting(buf);
if (str)
{
// parse name
if (*str=='$')
item.tip=FindTranslation(str+1,NULL);
else
item.tip=str;
}
Sprintf(buf,_countof(buf),L"%s.Icon",name);
item.iconPath=g_CustomMenuParser.FindSetting(buf);
item.settings=ParseItemSettings(name);
if (custom7>=0)
{
if (g_StdCommands7[custom7].flags&CStdCommand7::ITEM_SINGLE)
item.settings|=StdMenuItem::MENU_NOEXPAND;
if (g_StdCommands7[custom7].flags&CStdCommand7::ITEM_FOLDER)
item.settings&=~StdMenuItem::MENU_NOEXPAND;
}
}
const wchar_t *g_StartMenuItems7a=L"Items=COLUMN_PADDING, ProgramsMenu, SearchBoxItem, COLUMN_BREAK, ";
const wchar_t *g_StartMenuItems7b=
L" COLUMN_PADDING, ShutdownBoxItem\n"
L"ProgramsMenu.Command=programs\n"
L"ProgramsMenu.Label=$Menu.Programs\n"
L"ProgramsMenu.Tip=$Menu.ProgramsTip\n"
L"ProgramsMenu.Icon=none\n"
L"ProgramsMenu.Items=AppsMenu\n"
L"ProgramsMenu.Settings=ITEMS_FIRST\n"
L"AppsMenu.Command=apps\n"
L"AppsMenu.Label=$Menu.Apps\n"
L"AppsMenu.Icon=,2\n"
L"SearchBoxItem.Command=search_box\n"
L"SearchBoxItem.Label=$Menu.SearchPrograms\n"
L"SearchBoxItem.Icon=none\n"
L"SearchBoxItem.Settings=TRACK_RECENT, OPEN_UP\n"
L"ShutdownBoxItem.Command=shutdown_box\n"
L"ShutdownBoxItem.Label=shutdown\n"
L"ShutdownBoxItem.Icon=none\n"
L"ShutdownBoxItem.Items=SwitchUserItem, SecurityItem, LogOffItem, LockItem, DisconnectItem, UndockItem, SEPARATOR, RestartNUItem, RestartItem, SEPARATOR, SleepItem, HibernateItem, ShutdownNUItem, ShutdownItem\n"
L"ShutdownBoxItem.Settings=SPLIT\n"
L"SwitchUserItem.Command=switch_user\n"
L"SwitchUserItem.Label=$Menu.SwitchUser\n"
L"SwitchUserItem.Tip=$Menu.SwitchUserTip\n"
L"SwitchUserItem.Icon=none\n"
L"SecurityItem.Command=windows_security\n"
L"SecurityItem.Icon=none\n"
L"SecurityItem.Label=$Menu.Security\n"
L"SecurityItem.Tip=$Menu.SecurityTip\n"
L"LogOffItem.Command=logoff\n"
L"LogOffItem.Label=$Menu.LogOffShort\n"
L"LogOffItem.Tip=$Menu.LogOffTip\n"
L"LogOffItem.Icon=none\n"
L"LockItem.Command=lock\n"
L"LockItem.Label=$Menu.Lock\n"
L"LockItem.Tip=$Menu.LockTip\n"
L"LockItem.Icon=none\n"
L"DisconnectItem.Command=disconnect\n"
L"DisconnectItem.Label=$Menu.Disconnect\n"
L"DisconnectItem.Tip=$Menu.DisconnectTip\n"
L"DisconnectItem.Icon=none\n"
L"UndockItem.Command=undock\n"
L"UndockItem.Label=$Menu.Undock\n"
L"UndockItem.Tip=$Menu.UndockTip\n"
L"UndockItem.Icon=none\n"
L"RestartNUItem.Command=restart_noupdate\n"
L"RestartNUItem.Label=$Menu.Restart\n"
L"RestartNUItem.Tip=$Menu.RestartTip\n"
L"RestartNUItem.Icon=none\n"
L"RestartItem.Command=restart\n"
L"RestartItem.Label=$Menu.Restart\n"
L"RestartItem.Tip=$Menu.RestartTip\n"
L"RestartItem.Icon=none\n"
L"SleepItem.Command=sleep\n"
L"SleepItem.Label=$Menu.Sleep\n"
L"SleepItem.Tip=$Menu.SleepTip\n"
L"SleepItem.Icon=none\n"
L"HibernateItem.Command=hibernate\n"
L"HibernateItem.Label=$Menu.Hibernate\n"
L"HibernateItem.Tip=$Menu.HibernateTip\n"
L"HibernateItem.Icon=none\n"
L"ShutdownNUItem.Command=shutdown_noupdate\n"
L"ShutdownNUItem.Label=$Menu.Shutdown\n"
L"ShutdownNUItem.Tip=$Menu.ShutdownTip\n"
L"ShutdownNUItem.Icon=none\n"
L"ShutdownItem.Command=shutdown\n"
L"ShutdownItem.Label=$Menu.Shutdown\n"
L"ShutdownItem.Tip=$Menu.ShutdownTip\n"
L"ShutdownItem.Icon=none\n"
;
const StdMenuItem *ParseCustomMenu( unsigned int &rootSettings )
{
TMenuStyle menuStyle=(TMenuStyle)GetSettingInt(L"MenuStyle");
CString menuText;
if (menuStyle==MENU_CLASSIC1)
menuText=GetSettingString(L"MenuItems1");
else if (menuStyle==MENU_CLASSIC2)
menuText=GetSettingString(L"MenuItems2");
else
menuText=GetSettingString(L"MenuItems7");
unsigned int hash=FNV_HASH0;
if (GetSettingBool(L"ControlPanelCategories")) hash+=1;
if (GetSettingInt(L"ProgramsStyle")==PROGRAMS_INLINE) hash+=2;
if (GetSettingBool(L"AllProgramsMetro")) hash+=4;
hash=CalcFNVHash(menuText,hash);
if (hash!=g_MenuItemsHash)
{
if (GetSettingInt(L"MenuStyle")==MENU_WIN7)
{
wchar_t buf[16384];
int len=Strcpy(buf,_countof(buf),g_StartMenuItems7a);
CSettingsParser parser;
parser.LoadText(menuText,menuText.GetLength());
parser.ParseText();
for (int i=1;;i++)
{
wchar_t item[100];
Sprintf(item,_countof(item),L"Item%d.Settings",i);
const wchar_t *settings=parser.FindSetting(item);
if (settings && wcsstr(settings,L"ITEM_DISABLED"))
continue;
Sprintf(item,_countof(item),L"Item%d.Command",i);
const wchar_t *command=parser.FindSetting(item);
if (!command)
{
Sprintf(item,_countof(item),L"Item%d.Link",i);
if (!parser.FindSetting(item))
break;
}
if (command && (_wcsicmp(command,L"shutdown_box")==0 || _wcsicmp(command,L"recent_programs")==0 || _wcsicmp(command,L"search_box")==0 || _wcsicmp(command,L"programs")==0))
{
// these commands can't be in the right column because they are already in other parts of the menu
continue;
}
if (command && _wcsicmp(command,L"separator")==0)
{
len+=Sprintf(buf+len,_countof(buf)-len,L"SEPARATOR, ");
}
else
{
len+=Sprintf(buf+len,_countof(buf)-len,L"Item%d, ",i);
}
}
len+=Strcat(buf+len,_countof(buf)-len,g_StartMenuItems7b);
len+=Strcat(buf+len,_countof(buf)-len,menuText);
for (int i=1;;i++)
{
wchar_t item[100];
Sprintf(item,_countof(item),L"Item%d.Settings",i);
const wchar_t *settings=parser.FindSetting(item);
if (settings && wcsstr(settings,L"ITEM_DISABLED"))
continue;
Sprintf(item,_countof(item),L"Item%d.Command",i);
const wchar_t *command=parser.FindSetting(item);
Sprintf(item,_countof(item),L"Item%d.Link",i);
const wchar_t *link=parser.FindSetting(item);
if (!command)
{
if (!link)
break;
else
continue;
}
Sprintf(item,_countof(item),L"Item%d.Label",i);
const wchar_t *label=parser.FindSetting(item);
Sprintf(item,_countof(item),L"Item%d.icon",i);
const wchar_t *icon=parser.FindSetting(item);
Sprintf(item,_countof(item),L"Item%d.Tip",i);
const wchar_t *tip=parser.FindSetting(item);
// handle special items
for (int j=1;j<g_StdCommands7Count-1;j++)
{
const CStdCommand7 &stdCommand=g_StdCommands7[j];
if (_wcsicmp(command,stdCommand.command)==0)
{
if (!link && stdCommand.knownLink)
len+=Sprintf(buf+len,_countof(buf)-len,L"Item%d.Link=%s\n",i,stdCommand.knownLink);
if (!label && stdCommand.label)
len+=Sprintf(buf+len,_countof(buf)-len,L"Item%d.Label=%s\n",i,stdCommand.label);
if (!icon && stdCommand.icon)
len+=Sprintf(buf+len,_countof(buf)-len,L"Item%d.Icon=%s\n",i,stdCommand.icon);
if (!tip && stdCommand.tip)
len+=Sprintf(buf+len,_countof(buf)-len,L"Item%d.Tip=%s\n",i,stdCommand.tip);
}
}
}
if (GetWinVersion()<WIN_VER_WIN8 || GetSettingInt(L"ProgramsStyle")==PROGRAMS_INLINE || !GetSettingBool(L"AllProgramsMetro"))
len+=Strcpy(buf+len,_countof(buf)-len,L"ProgramsMenu.Items=\n");
menuText=buf;
}
g_RootSettings=0;
g_MenuItemsHash=hash;
g_CustomMenu.clear();
g_CustomMenuParser.Reset();
g_CustomMenuParser.LoadText(menuText,menuText.GetLength());
g_CustomMenuParser.ParseText();
std::vector<CSettingsParser::TreeItem> items;
g_CustomMenuParser.ParseTree(L"Items",items);
g_CustomMenu.resize(items.size());
for (size_t i=0;i<items.size();i++)
{
const wchar_t *name=items[i].name;
StdMenuItem &item=g_CustomMenu[i];
item.command=0;
item.id=MENU_NO;
item.folder1=item.folder2=NULL;
item.label=item.tip=item.iconPath=item.link=NULL;
item.settings=0;
item.submenu=NULL;
// handle special names
if (!*name)
{
item.id=MENU_LAST;
continue;
}
if (_wcsicmp(name,L"SEPARATOR")==0)
{
item.id=MENU_SEPARATOR;
continue;
}
if (_wcsicmp(name,L"COLUMN_PADDING")==0)
{
item.id=MENU_COLUMN_PADDING;
continue;
}
if (_wcsicmp(name,L"COLUMN_BREAK")==0)
{
item.id=MENU_COLUMN_BREAK;
continue;
}
// handle custom items
item.id=MENU_CUSTOM;
ParseMenuItem(item,name);
if (item.id==MENU_RECENT_PROGRAMS)
g_RootSettings|=StdMenuItem::MENU_NORECENT;
int idx=items[i].children;
if (idx>=0)
item.submenu=&g_CustomMenu[idx];
}
for (std::vector<StdMenuItem>::iterator it=g_CustomMenu.begin();it!=g_CustomMenu.end();++it)
if (it->id==MENU_RECENT_PROGRAMS)
{
g_RootSettings|=StdMenuItem::MENU_NORECENT;
break;
}
// if there is no break, add one after Programs
if (!g_CustomMenu.empty())
{
bool bBreak=false;
int after=-1;
for (int i=0;g_CustomMenu[i].id!=MENU_LAST;i++)
{
if (g_CustomMenu[i].id==MENU_COLUMN_BREAK)
bBreak=true;
if (g_CustomMenu[i].id==MENU_PROGRAMS)
after=i;
}
if (!bBreak && after>=0)
{
// add break
StdMenuItem br={NULL,MENU_COLUMN_BREAK};
const StdMenuItem *pBase=&g_CustomMenu[0];
g_CustomMenu.insert(g_CustomMenu.begin()+after+1,br);
// fix submenu pointers
for (std::vector<StdMenuItem>::iterator it=g_CustomMenu.begin();it!=g_CustomMenu.end();++it)
if (it->submenu)
{
int idx=(int)(it->submenu-pBase);
if (idx>after+1)
idx++;
it->submenu=&g_CustomMenu[idx];
}
}
}
// ignore extra search boxes
bool bSearchBox=false;
for (std::vector<StdMenuItem>::iterator it=g_CustomMenu.begin();it!=g_CustomMenu.end();++it)
{
if (it->id==MENU_SEARCH_BOX)
{
if (!bSearchBox)
bSearchBox=true;
else
it->id=MENU_IGNORE;
}
}
}
rootSettings=g_RootSettings;
return &g_CustomMenu[0];
}
void InitStdCommands7( void )
{
for (int i=0;i<g_StdCommands7Count;i++)
{
CStdCommand7 &command=g_StdCommands7[i];
if (command.nameID)
command.displayName=LoadStringEx(command.nameID);
else if (command.knownFolder)
{
CAbsolutePidl pidl;
if (SUCCEEDED(ShGetKnownFolderIDList(*command.knownFolder,&pidl)))
{
if (_wcsicmp(command.command,L"control_panel")==0)
{
ILRemoveLastID(pidl);
}
CComString pName;
if (SUCCEEDED(SHGetNameFromIDList(pidl,SIGDN_NORMALDISPLAY,&pName)))
command.displayName=pName;
}
}
else if (command.knownLink)
{
CAbsolutePidl pidl;
if (SUCCEEDED(MenuParseDisplayName(command.knownLink,&pidl,NULL,NULL)))
{
CComString pName;
if (SUCCEEDED(SHGetNameFromIDList(pidl,SIGDN_NORMALDISPLAY,&pName)))
command.displayName=pName;
}
}
if (command.displayName.IsEmpty())
command.displayName=command.command;
}
std::sort(g_StdCommands7+1,g_StdCommands7+g_StdCommands7Count-1);
}