Reactos

[EXPLORER][SHELL32] Fix and improve Start Menu customization (#6596)

Correct the details of Start Menu customization.
JIRA issue: CORE-16956
- Hide the setting item if the item is restricted.
- Don't change restriction in Explorer.
- Fix Start Menu settings for restriction and registry.
- Fix and simplify code.

authored by

Katayama Hirofumi MZ and committed by
GitHub
8bd071a5 0241b5c4

+139 -139
-1
base/shell/explorer/precomp.h
··· 110 110 BOOL SetRegDword(IN LPCWSTR pszSubKey, IN LPCWSTR pszValueName, IN DWORD dwValue); 111 111 BOOL GetAdvancedBool(IN LPCWSTR pszValueName, IN BOOL bDefaultValue); 112 112 BOOL SetAdvancedDword(IN LPCWSTR pszValueName, IN DWORD dwValue); 113 - BOOL SetRestriction(IN LPCWSTR pszKey, IN LPCWSTR pszValueName, IN DWORD dwValue); 114 113 115 114 /* 116 115 * rshell.c
+51 -38
base/shell/explorer/startmnucust.cpp
··· 21 21 22 22 #include "precomp.h" 23 23 24 + #define I_UNCHECKED 1 24 25 #define I_CHECKED 2 25 26 26 27 // TODO: Windows Explorer appears to be calling NewLinkHere / ConfigStartMenu directly for both items. ··· 82 83 { 83 84 LPARAM id; 84 85 LPCWSTR name; 85 - FN_CUSTOMIZE_READ fnRead; 86 - FN_CUSTOMIZE_WRITE fnWrite; 86 + BOOL bDefaultValue; 87 + RESTRICTIONS policy1, policy2; 87 88 }; 88 89 89 - static DWORD CALLBACK CustomizeReadAdvanced(const CUSTOMIZE_ENTRY *entry) 90 - { 91 - return GetAdvancedBool(entry->name, FALSE); 92 - } 93 - 94 - static BOOL CALLBACK CustomizeWriteAdvanced(const CUSTOMIZE_ENTRY *entry, DWORD dwValue) 95 - { 96 - return SetAdvancedDword(entry->name, dwValue); 97 - } 98 - 99 - static DWORD CALLBACK CustomizeReadRun(const CUSTOMIZE_ENTRY *entry) 100 - { 101 - return !SHRestricted(REST_NORUN); 102 - } 103 - 104 - static BOOL CALLBACK CustomizeWriteRest(const CUSTOMIZE_ENTRY *entry, DWORD dwValue) 105 - { 106 - SetRestriction(L"Explorer", entry->name, !dwValue); 107 - return TRUE; 108 - } 109 - 110 90 static const CUSTOMIZE_ENTRY s_CustomizeEntries[] = 111 91 { 112 - // FIXME: Make "StartMenuAdminTools" effective 113 - //{ IDS_ADVANCED_DISPLAY_ADMINTOOLS, L"StartMenuAdminTools", CustomizeRead1, CustomizeWrite1 }, // FIXME 114 - 115 - { IDS_ADVANCED_DISPLAY_FAVORITES, L"StartMenuFavorites", CustomizeReadAdvanced, CustomizeWriteAdvanced }, 116 - { IDS_ADVANCED_DISPLAY_LOG_OFF, L"StartMenuLogoff", CustomizeReadAdvanced, CustomizeWriteAdvanced }, 117 - { IDS_ADVANCED_DISPLAY_RUN, L"NoRun", CustomizeReadRun, CustomizeWriteRest }, 118 - { IDS_ADVANCED_EXPAND_MY_DOCUMENTS, L"CascadeMyDocuments", CustomizeReadAdvanced, CustomizeWriteAdvanced }, 119 - { IDS_ADVANCED_EXPAND_MY_PICTURES, L"CascadeMyPictures", CustomizeReadAdvanced, CustomizeWriteAdvanced }, 120 - { IDS_ADVANCED_EXPAND_CONTROL_PANEL, L"CascadeControlPanel", CustomizeReadAdvanced, CustomizeWriteAdvanced }, 121 - { IDS_ADVANCED_EXPAND_PRINTERS, L"CascadePrinters", CustomizeReadAdvanced, CustomizeWriteAdvanced }, 122 - { IDS_ADVANCED_EXPAND_NET_CONNECTIONS, L"CascadeNetworkConnections", CustomizeReadAdvanced, CustomizeWriteAdvanced }, 92 + // FIXME: Make "StartMenuAdminTools" effective for IDS_ADVANCED_DISPLAY_ADMINTOOLS 93 + { 94 + IDS_ADVANCED_DISPLAY_FAVORITES, L"StartMenuFavorites", FALSE, 95 + REST_NOFAVORITESMENU 96 + }, 97 + { 98 + IDS_ADVANCED_DISPLAY_LOG_OFF, L"StartMenuLogoff", FALSE, 99 + REST_STARTMENULOGOFF 100 + }, 101 + { 102 + IDS_ADVANCED_DISPLAY_RUN, L"StartMenuRun", TRUE, 103 + REST_NORUN 104 + }, 105 + { 106 + IDS_ADVANCED_EXPAND_MY_DOCUMENTS, L"CascadeMyDocuments", FALSE, 107 + REST_NOSMMYDOCS 108 + }, 109 + { 110 + IDS_ADVANCED_EXPAND_MY_PICTURES, L"CascadeMyPictures", FALSE, 111 + REST_NOSMMYPICS 112 + }, 113 + { 114 + IDS_ADVANCED_EXPAND_CONTROL_PANEL, L"CascadeControlPanel", FALSE, 115 + REST_NOSETFOLDERS, REST_NOCONTROLPANEL, 116 + }, 117 + { 118 + IDS_ADVANCED_EXPAND_PRINTERS, L"CascadePrinters", FALSE, 119 + REST_NOSETFOLDERS 120 + }, 121 + { 122 + IDS_ADVANCED_EXPAND_NET_CONNECTIONS, L"CascadeNetworkConnections", FALSE, 123 + REST_NOSETFOLDERS, REST_NONETWORKCONNECTIONS 124 + }, 123 125 }; 124 126 125 127 static VOID AddCustomizeItem(HWND hTreeView, const CUSTOMIZE_ENTRY *entry) 126 128 { 129 + if (SHRestricted(entry->policy1) || SHRestricted(entry->policy2)) 130 + { 131 + TRACE("%p: Restricted\n", entry->id); 132 + return; // Restricted. Don't show 133 + } 134 + 127 135 TV_INSERTSTRUCT Insert = { TVI_ROOT, TVI_LAST }; 128 136 Insert.item.mask = TVIF_TEXT | TVIF_STATE | TVIF_PARAM; 129 137 ··· 132 140 Insert.item.pszText = szText; 133 141 Insert.item.lParam = entry->id; 134 142 Insert.item.stateMask = TVIS_STATEIMAGEMASK; 135 - if (entry->fnRead(entry)) 136 - Insert.item.state = INDEXTOSTATEIMAGEMASK(I_CHECKED); 143 + BOOL bChecked = GetAdvancedBool(entry->name, entry->bDefaultValue); 144 + Insert.item.state = INDEXTOSTATEIMAGEMASK(bChecked ? I_CHECKED : I_UNCHECKED); 145 + TRACE("%p: %d\n", entry->id, bChecked); 137 146 TreeView_InsertItem(hTreeView, &Insert); 138 147 } 139 148 ··· 165 174 item.stateMask = TVIS_STATEIMAGEMASK; 166 175 TreeView_GetItem(hTreeView, &item); 167 176 168 - BOOL bChecked = (item.state & INDEXTOSTATEIMAGEMASK(I_CHECKED)); 177 + BOOL bChecked = !!(item.state & INDEXTOSTATEIMAGEMASK(I_CHECKED)); 169 178 for (auto& entry : s_CustomizeEntries) 170 179 { 180 + if (SHRestricted(entry.policy1) || SHRestricted(entry.policy2)) 181 + continue; 182 + 171 183 if (item.lParam == entry.id) 172 184 { 173 - entry.fnWrite(&entry, bChecked); 185 + TRACE("%p: %d\n", item.lParam, bChecked); 186 + SetAdvancedDword(entry.name, bChecked); 174 187 break; 175 188 } 176 189 }
+64 -85
base/shell/explorer/startmnusite.cpp
··· 130 130 131 131 /* Remove menu items that don't apply */ 132 132 133 - dwLogoff = SHRestricted(REST_STARTMENULOGOFF); 134 - bWantLogoff = (dwLogoff == 2 || 135 - SHRestricted(REST_FORCESTARTMENULOGOFF) || 136 - GetAdvancedBool(L"StartMenuLogoff", FALSE)); 137 - 138 133 /* Favorites */ 139 - if (!GetAdvancedBool(L"StartMenuFavorites", FALSE)) 134 + if (SHRestricted(REST_NOFAVORITESMENU) || 135 + !GetAdvancedBool(L"StartMenuFavorites", FALSE)) 140 136 { 141 - DeleteMenu(hMenu, 142 - IDM_FAVORITES, 143 - MF_BYCOMMAND); 137 + DeleteMenu(hMenu, IDM_FAVORITES, MF_BYCOMMAND); 144 138 } 145 139 146 140 /* Documents */ 147 - if (SHRestricted(REST_NORECENTDOCSMENU)) 141 + if (SHRestricted(REST_NORECENTDOCSMENU) || 142 + !GetAdvancedBool(L"Start_ShowRecentDocs", TRUE)) 148 143 { 149 - DeleteMenu(hMenu, 150 - IDM_DOCUMENTS, 151 - MF_BYCOMMAND); 144 + DeleteMenu(hMenu, IDM_DOCUMENTS, MF_BYCOMMAND); 152 145 } 153 146 154 147 /* Settings */ 155 - hSettingsMenu = FindSubMenu(hMenu, 156 - IDM_SETTINGS, 157 - FALSE); 158 - if (hSettingsMenu != NULL) 148 + hSettingsMenu = FindSubMenu(hMenu, IDM_SETTINGS, FALSE); 149 + 150 + /* Control Panel */ 151 + if (SHRestricted(REST_NOSETFOLDERS) || 152 + SHRestricted(REST_NOCONTROLPANEL) || 153 + !GetAdvancedBool(L"Start_ShowControlPanel", TRUE)) 159 154 { 160 - if (SHRestricted(REST_NOSETFOLDERS)) 161 - { 162 - /* Control Panel */ 163 - if (SHRestricted(REST_NOCONTROLPANEL)) 164 - { 165 - DeleteMenu(hSettingsMenu, 166 - IDM_CONTROLPANEL, 167 - MF_BYCOMMAND); 155 + DeleteMenu(hSettingsMenu, IDM_CONTROLPANEL, MF_BYCOMMAND); 168 156 169 - /* Delete the separator below it */ 170 - DeleteMenu(hSettingsMenu, 171 - 0, 172 - MF_BYPOSITION); 173 - } 157 + /* Delete the separator below it */ 158 + DeleteMenu(hSettingsMenu, 0, MF_BYPOSITION); 159 + } 174 160 175 - /* Network Connections */ 176 - if (SHRestricted(REST_NONETWORKCONNECTIONS)) 177 - { 178 - DeleteMenu(hSettingsMenu, 179 - IDM_NETWORKCONNECTIONS, 180 - MF_BYCOMMAND); 181 - } 161 + /* Network Connections */ 162 + if (SHRestricted(REST_NOSETFOLDERS) || 163 + SHRestricted(REST_NONETWORKCONNECTIONS) || 164 + !GetAdvancedBool(L"Start_ShowNetConn", TRUE)) 165 + { 166 + DeleteMenu(hSettingsMenu, IDM_NETWORKCONNECTIONS, MF_BYCOMMAND); 167 + } 182 168 183 - /* Printers and Faxes */ 184 - DeleteMenu(hSettingsMenu, 185 - IDM_PRINTERSANDFAXES, 186 - MF_BYCOMMAND); 187 - } 169 + /* Printers and Faxes */ 170 + if (SHRestricted(REST_NOSETFOLDERS) || 171 + !GetAdvancedBool(L"Start_ShowPrinters", TRUE)) 172 + { 173 + DeleteMenu(hSettingsMenu, IDM_PRINTERSANDFAXES, MF_BYCOMMAND); 174 + } 188 175 189 - /* Security */ 190 - if (GetSystemMetrics(SM_REMOTECONTROL) == 0 || 191 - SHRestricted(REST_NOSECURITY)) 192 - { 193 - DeleteMenu(hSettingsMenu, 194 - IDM_SECURITY, 195 - MF_BYCOMMAND); 196 - } 176 + /* Security */ 177 + if (SHRestricted(REST_NOSETFOLDERS) || 178 + GetSystemMetrics(SM_REMOTECONTROL) == 0 || 179 + SHRestricted(REST_NOSECURITY)) 180 + { 181 + DeleteMenu(hSettingsMenu, IDM_SECURITY, MF_BYCOMMAND); 182 + } 197 183 198 - if (GetMenuItemCount(hSettingsMenu) == 0) 199 - { 200 - DeleteMenu(hMenu, 201 - IDM_SETTINGS, 202 - MF_BYCOMMAND); 203 - } 184 + /* Delete Settings menu if it was empty */ 185 + if (GetMenuItemCount(hSettingsMenu) == 0) 186 + { 187 + DeleteMenu(hMenu, IDM_SETTINGS, MF_BYCOMMAND); 204 188 } 205 189 206 190 /* Search */ 207 - if (SHRestricted(REST_NOFIND)) 191 + if (SHRestricted(REST_NOFIND) || 192 + !GetAdvancedBool(L"Start_ShowSearch", TRUE)) 208 193 { 209 - DeleteMenu(hMenu, 210 - IDM_SEARCH, 211 - MF_BYCOMMAND); 194 + DeleteMenu(hMenu, IDM_SEARCH, MF_BYCOMMAND); 212 195 } 213 196 214 - /* FIXME: Help */ 197 + /* Help */ 198 + if (SHRestricted(REST_NOSMHELP) || 199 + !GetAdvancedBool(L"Start_ShowHelp", TRUE)) 200 + { 201 + DeleteMenu(hMenu, IDM_HELPANDSUPPORT, MF_BYCOMMAND); 202 + } 215 203 216 204 /* Run */ 217 - if (SHRestricted(REST_NORUN)) 205 + if (SHRestricted(REST_NORUN) || 206 + !GetAdvancedBool(L"StartMenuRun", TRUE)) 218 207 { 219 208 DeleteMenu(hMenu, IDM_RUN, MF_BYCOMMAND); 220 209 } ··· 222 211 /* Synchronize */ 223 212 if (!ShowSynchronizeMenuItem()) 224 213 { 225 - DeleteMenu(hMenu, 226 - IDM_SYNCHRONIZE, 227 - MF_BYCOMMAND); 214 + DeleteMenu(hMenu, IDM_SYNCHRONIZE, MF_BYCOMMAND); 228 215 uLastItemsCount--; 229 216 } 230 217 231 218 /* Log off */ 219 + dwLogoff = SHRestricted(REST_STARTMENULOGOFF); 220 + bWantLogoff = (dwLogoff == 2 || 221 + SHRestricted(REST_FORCESTARTMENULOGOFF) || 222 + GetAdvancedBool(L"StartMenuLogoff", FALSE)); 232 223 if (dwLogoff != 1 && bWantLogoff) 233 224 { 234 225 /* FIXME: We need a more sophisticated way to determine whether to show ··· 246 237 szUser)) 247 238 { 248 239 /* We couldn't update the menu item, delete it... */ 249 - DeleteMenu(hMenu, 250 - IDM_LOGOFF, 251 - MF_BYCOMMAND); 240 + DeleteMenu(hMenu, IDM_LOGOFF, MF_BYCOMMAND); 252 241 } 253 242 } 254 243 else 255 244 { 256 - DeleteMenu(hMenu, 257 - IDM_LOGOFF, 258 - MF_BYCOMMAND); 245 + DeleteMenu(hMenu, IDM_LOGOFF, MF_BYCOMMAND); 259 246 uLastItemsCount--; 260 247 } 261 248 262 - 263 249 /* Disconnect */ 264 - if (GetSystemMetrics(SM_REMOTECONTROL) == 0) 250 + if (SHRestricted(REST_NODISCONNECT) || 251 + GetSystemMetrics(SM_REMOTECONTROL) == 0) 265 252 { 266 - DeleteMenu(hMenu, 267 - IDM_DISCONNECT, 268 - MF_BYCOMMAND); 253 + DeleteMenu(hMenu, IDM_DISCONNECT, MF_BYCOMMAND); 269 254 uLastItemsCount--; 270 255 } 271 256 272 257 /* Undock computer */ 273 258 if (!ShowUndockMenuItem()) 274 259 { 275 - DeleteMenu(hMenu, 276 - IDM_UNDOCKCOMPUTER, 277 - MF_BYCOMMAND); 260 + DeleteMenu(hMenu, IDM_UNDOCKCOMPUTER, MF_BYCOMMAND); 278 261 uLastItemsCount--; 279 262 } 280 263 281 264 /* Shut down */ 282 265 if (SHRestricted(REST_NOCLOSE)) 283 266 { 284 - DeleteMenu(hMenu, 285 - IDM_SHUTDOWN, 286 - MF_BYCOMMAND); 267 + DeleteMenu(hMenu, IDM_SHUTDOWN, MF_BYCOMMAND); 287 268 uLastItemsCount--; 288 269 } 289 270 290 271 if (uLastItemsCount == 0) 291 272 { 292 273 /* Remove the separator at the end of the menu */ 293 - DeleteMenu(hMenu, 294 - IDM_LASTSTARTMENU_SEPARATOR, 295 - MF_BYCOMMAND); 274 + DeleteMenu(hMenu, IDM_LASTSTARTMENU_SEPARATOR, MF_BYCOMMAND); 296 275 } 297 276 298 277 return S_OK;
-9
base/shell/explorer/util.cpp
··· 163 163 return SetRegDword(REGKEY_ADVANCED, pszValueName, dwValue); 164 164 } 165 165 166 - BOOL SetRestriction(IN LPCWSTR pszKey, IN LPCWSTR pszValueName, IN DWORD dwValue) 167 - { 168 - WCHAR szSubKey[MAX_PATH] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies"; 169 - PathAppendW(szSubKey, pszKey); 170 - SHSetValueW(HKEY_CURRENT_USER, szSubKey, pszValueName, REG_DWORD, &dwValue, sizeof(dwValue)); 171 - SHSettingsChanged(NULL, NULL); 172 - return TRUE; 173 - } 174 - 175 166 BOOL 176 167 GetVersionInfoString(IN LPCWSTR szFileName, 177 168 IN LPCWSTR szVersionInfo,
+24 -6
dll/win32/shell32/shellmenu/CStartMenu.cpp
··· 196 196 197 197 HMENU CreateRecentMenu() const 198 198 { 199 - BOOL bExpandMyDocuments = GetAdvancedValue(L"CascadeMyDocuments", FALSE); 200 - BOOL bExpandMyPictures = GetAdvancedValue(L"CascadeMyPictures", FALSE); 201 199 HMENU hMenu = ::CreateMenu(); 202 - AddOrSetMenuItem(hMenu, IDM_MYDOCUMENTS, CSIDL_MYDOCUMENTS, bExpandMyDocuments); 203 - AddOrSetMenuItem(hMenu, IDM_MYPICTURES, CSIDL_MYPICTURES, bExpandMyPictures); 204 - AppendMenuW(hMenu, MF_SEPARATOR, 0, NULL); 200 + BOOL bAdded = FALSE; 201 + 202 + // My Documents 203 + if (!SHRestricted(REST_NOSMMYDOCS) && 204 + GetAdvancedValue(L"Start_ShowMyDocs", TRUE)) 205 + { 206 + BOOL bExpand = GetAdvancedValue(L"CascadeMyDocuments", FALSE); 207 + AddOrSetMenuItem(hMenu, IDM_MYDOCUMENTS, CSIDL_MYDOCUMENTS, bExpand); 208 + bAdded = TRUE; 209 + } 210 + 211 + // My Pictures 212 + if (!SHRestricted(REST_NOSMMYPICS) && 213 + GetAdvancedValue(L"Start_ShowMyPics", TRUE)) 214 + { 215 + BOOL bExpand = GetAdvancedValue(L"CascadeMyPictures", FALSE); 216 + AddOrSetMenuItem(hMenu, IDM_MYPICTURES, CSIDL_MYPICTURES, bExpand); 217 + bAdded = TRUE; 218 + } 219 + 220 + if (bAdded) 221 + AppendMenuW(hMenu, MF_SEPARATOR, 0, NULL); 222 + 205 223 return hMenu; 206 224 } 207 225 ··· 221 239 222 240 HRESULT AddStartMenuItems(IShellMenu *pShellMenu, INT csidl, DWORD dwFlags) 223 241 { 224 - LPITEMIDLIST pidlMenu; 242 + CComHeapPtr<ITEMIDLIST> pidlMenu; 225 243 CComPtr<IShellFolder> psfDesktop; 226 244 CComPtr<IShellFolder> pShellFolder; 227 245 HRESULT hr;