Reactos
at master 276 lines 8.5 kB view raw
1/* 2 * 'View' tab property sheet of Folder Options 3 * 4 * Copyright 2007 Johannes Anderwald <johannes.anderwald@reactos.org> 5 * Copyright 2016-2018 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22#include "precomp.h" 23 24WINE_DEFAULT_DEBUG_CHANNEL (fprop); 25 26static inline CFolderOptions* 27GetFolderOptions(HWND hwndDlg) 28{ 29 return (CFolderOptions*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 30} 31 32static inline IRegTreeOptions* 33GetRegTreeOptions(HWND hwndDlg) 34{ 35 return (IRegTreeOptions*)GetWindowLongPtr(hwndDlg, DWLP_USER); 36} 37 38static void 39ViewDlg_OnDestroy(HWND hwndDlg) 40{ 41 if (IRegTreeOptions *pRTO = GetRegTreeOptions(hwndDlg)) 42 { 43 pRTO->WalkTree(WALK_TREE_DESTROY); 44 pRTO->Release(); 45 SetWindowLongPtr(hwndDlg, DWLP_USER, 0); 46 } 47} 48 49static BOOL 50ViewDlg_OnInitDialog(HWND hwndDlg, LPPROPSHEETPAGE psp) 51{ 52 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, psp->lParam); 53 CFolderOptions *pFO = (CFolderOptions*)psp->lParam; 54 55 if (!pFO || !pFO->CanSetDefFolderSettings()) 56 { 57 // The global options (started from rundll32 or control panel) 58 // has no browser to copy the current settings from. 59 EnableWindow(GetDlgItem(hwndDlg, IDC_VIEW_APPLY_TO_ALL), FALSE); 60 } 61 62 IRegTreeOptions *pRTO = NULL; 63 if (SUCCEEDED(SHCoCreateInstance(NULL, &CLSID_CRegTreeOptions, NULL, IID_PPV_ARG(IRegTreeOptions, &pRTO)))) 64 { 65 SetWindowLongPtr(hwndDlg, DWLP_USER, (LPARAM)pRTO); 66 67 CHAR apath[MAX_PATH]; 68 SHUnicodeToAnsi(REGSTR_PATH_EXPLORER L"\\Advanced", apath, _countof(apath)); 69 HWND hwndTreeView = GetDlgItem(hwndDlg, IDC_VIEW_TREEVIEW); 70 pRTO->InitTree(hwndTreeView, HKEY_LOCAL_MACHINE, apath, NULL); 71 } 72 73 return TRUE; // Set focus 74} 75 76static BOOL 77ViewDlg_ToggleCheckItem(HWND hwndDlg, HTREEITEM hItem) 78{ 79 IRegTreeOptions *pRTO = GetRegTreeOptions(hwndDlg); 80 return pRTO && SUCCEEDED(pRTO->ToggleItem(hItem)); 81} 82 83static VOID 84ViewDlg_OnTreeViewClick(HWND hwndDlg) 85{ 86 HWND hwndTreeView = GetDlgItem(hwndDlg, IDC_VIEW_TREEVIEW); 87 88 // do hit test to get the clicked item 89 TV_HITTESTINFO HitTest; 90 ZeroMemory(&HitTest, sizeof(HitTest)); 91 DWORD dwPos = GetMessagePos(); 92 HitTest.pt.x = GET_X_LPARAM(dwPos); 93 HitTest.pt.y = GET_Y_LPARAM(dwPos); 94 ScreenToClient(hwndTreeView, &HitTest.pt); 95 HTREEITEM hItem = TreeView_HitTest(hwndTreeView, &HitTest); 96 97 // toggle the check mark if possible 98 if (ViewDlg_ToggleCheckItem(hwndDlg, hItem)) 99 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 100} 101 102static void 103ViewDlg_OnTreeViewKeyDown(HWND hwndDlg, TV_KEYDOWN *KeyDown) 104{ 105 HWND hwndTreeView = GetDlgItem(hwndDlg, IDC_VIEW_TREEVIEW); 106 107 if (KeyDown->wVKey == VK_SPACE) 108 { 109 HTREEITEM hItem = TreeView_GetSelection(hwndTreeView); 110 if (ViewDlg_ToggleCheckItem(hwndDlg, hItem)) 111 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 112 } 113 else if (KeyDown->wVKey == VK_F5) 114 { 115 IRegTreeOptions *pRTO = GetRegTreeOptions(hwndDlg); 116 if (pRTO) 117 pRTO->WalkTree(WALK_TREE_REFRESH); 118 } 119} 120 121static INT_PTR 122ViewDlg_OnTreeCustomDraw(HWND hwndDlg, NMTVCUSTOMDRAW *Draw) 123{ 124 NMCUSTOMDRAW& nmcd = Draw->nmcd; 125 switch (nmcd.dwDrawStage) 126 { 127 case CDDS_PREPAINT: 128 return CDRF_NOTIFYITEMDRAW; // for CDDS_ITEMPREPAINT 129 130 case CDDS_ITEMPREPAINT: 131 if (!(nmcd.uItemState & CDIS_SELECTED)) // not selected 132 { 133 LPARAM lParam = nmcd.lItemlParam; 134 if ((HKEY)lParam == HKEY_REGTREEOPTION_GRAYED) // disabled 135 { 136 // draw as grayed 137 Draw->clrText = GetSysColor(COLOR_GRAYTEXT); 138 Draw->clrTextBk = GetSysColor(COLOR_WINDOW); 139 return CDRF_NEWFONT; 140 } 141 } 142 break; 143 144 default: 145 break; 146 } 147 return CDRF_DODEFAULT; 148} 149 150static VOID 151ViewDlg_RestoreDefaults(HWND hwndDlg) 152{ 153 if (IRegTreeOptions *pRTO = GetRegTreeOptions(hwndDlg)) 154 { 155 pRTO->WalkTree(WALK_TREE_DEFAULT); 156 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 157 } 158} 159 160static BOOL CALLBACK 161PostCabinetMessageCallback(HWND hWnd, LPARAM param) 162{ 163 MSG &data = *(MSG*)param; 164 WCHAR ClassName[100]; 165 if (GetClassNameW(hWnd, ClassName, _countof(ClassName))) 166 { 167 if (!wcscmp(ClassName, L"Progman") || 168 !wcscmp(ClassName, L"CabinetWClass") || 169 !wcscmp(ClassName, L"ExploreWClass")) 170 { 171 PostMessage(hWnd, data.message, data.wParam, data.lParam); 172 } 173 } 174 return TRUE; 175} 176 177void 178PostCabinetMessage(UINT Msg, WPARAM wParam, LPARAM lParam) 179{ 180 MSG data; 181 data.message = Msg; 182 data.wParam = wParam; 183 data.lParam = lParam; 184 EnumWindows(PostCabinetMessageCallback, (LPARAM)&data); 185} 186 187static VOID 188ViewDlg_Apply(HWND hwndDlg) 189{ 190 IRegTreeOptions *pRTO = GetRegTreeOptions(hwndDlg); 191 if (!pRTO || FAILED(pRTO->WalkTree(WALK_TREE_SAVE))) 192 return; 193 194 SHSettingsChanged(0, 0); // Invalidate restrictions 195 SHGetSetSettings(NULL, 0, TRUE); // Invalidate SHELLSTATE 196 197 CABINETSTATE cs; 198 cs.cLength = sizeof(cs); 199 if (ReadCabinetState(&cs, sizeof(cs))) 200 WriteCabinetState(&cs); // Write the settings and invalidate global counter 201 202 SHSendMessageBroadcastW(WM_SETTINGCHANGE, 0, 0); 203 PostCabinetMessage(WM_COMMAND, FCIDM_DESKBROWSER_REFRESH, 0); 204} 205 206// IDD_FOLDER_OPTIONS_VIEW 207INT_PTR CALLBACK 208FolderOptionsViewDlg( 209 HWND hwndDlg, 210 UINT uMsg, 211 WPARAM wParam, 212 LPARAM lParam) 213{ 214 INT_PTR Result; 215 216 switch (uMsg) 217 { 218 case WM_INITDIALOG: 219 return ViewDlg_OnInitDialog(hwndDlg, (LPPROPSHEETPAGE)lParam); 220 221 case WM_DESTROY: 222 ViewDlg_OnDestroy(hwndDlg); 223 break; 224 225 case WM_COMMAND: 226 switch (LOWORD(wParam)) 227 { 228 case IDC_VIEW_RESTORE_DEFAULTS: // Restore Defaults 229 ViewDlg_RestoreDefaults(hwndDlg); 230 break; 231 232 case IDC_VIEW_APPLY_TO_ALL: 233 case IDC_VIEW_RESET_ALL: 234 { 235 HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); 236 bool ResetToDefault = LOWORD(wParam) == IDC_VIEW_RESET_ALL; 237 CFolderOptions *pFO = GetFolderOptions(hwndDlg); 238 if (pFO) 239 hr = pFO->ApplyDefFolderSettings(ResetToDefault); // Use IBrowserService2 240 if (ResetToDefault && hr == HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED)) 241 hr = CFolderOptions::ResetGlobalAndDefViewFolderSettings(); // No browser 242 if (FAILED(hr)) 243 SHELL_ErrorBox(hwndDlg, hr); 244 break; 245 } 246 } 247 break; 248 249 case WM_NOTIFY: 250 switch (LPNMHDR(lParam)->code) 251 { 252 case NM_CLICK: // clicked on treeview 253 ViewDlg_OnTreeViewClick(hwndDlg); 254 break; 255 256 case NM_CUSTOMDRAW: // custom draw (for graying) 257 Result = ViewDlg_OnTreeCustomDraw(hwndDlg, (NMTVCUSTOMDRAW*)lParam); 258 SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, Result); 259 return Result; 260 261 case TVN_KEYDOWN: // key is down 262 ViewDlg_OnTreeViewKeyDown(hwndDlg, (TV_KEYDOWN *)lParam); 263 break; 264 265 case PSN_APPLY: // [Apply] is clicked 266 ViewDlg_Apply(hwndDlg); 267 break; 268 269 default: 270 break; 271 } 272 break; 273 } 274 275 return FALSE; 276}