Reactos
at master 253 lines 7.5 kB view raw
1/* 2 * 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 26// Folder Options: 27// CLASSKEY = HKEY_CLASSES_ROOT\CLSID\{6DFD7C5C-2451-11d3-A299-00C04F8EF6AF} 28 29///////////////////////////////////////////////////////////////////////////// 30// strings 31 32// path to shell32 33LPCWSTR g_pszShell32 = L"%SystemRoot%\\system32\\shell32.dll"; 34 35// the space characters 36LPCWSTR g_pszSpace = L" \t\n\r\f\v"; 37 38///////////////////////////////////////////////////////////////////////////// 39// utility functions 40 41HBITMAP Create24BppBitmap(HDC hDC, INT cx, INT cy) 42{ 43 BITMAPINFO bi; 44 LPVOID pvBits; 45 46 ZeroMemory(&bi, sizeof(bi)); 47 bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 48 bi.bmiHeader.biWidth = cx; 49 bi.bmiHeader.biHeight = cy; 50 bi.bmiHeader.biPlanes = 1; 51 bi.bmiHeader.biBitCount = 24; 52 bi.bmiHeader.biCompression = BI_RGB; 53 54 HBITMAP hbm = CreateDIBSection(hDC, &bi, DIB_RGB_COLORS, &pvBits, NULL, 0); 55 return hbm; 56} 57 58HBITMAP BitmapFromIcon(HICON hIcon, INT cx, INT cy) 59{ 60 HDC hDC = CreateCompatibleDC(NULL); 61 if (!hDC) 62 return NULL; 63 64 HBITMAP hbm = Create24BppBitmap(hDC, cx, cy); 65 if (!hbm) 66 { 67 DeleteDC(hDC); 68 return NULL; 69 } 70 71 HGDIOBJ hbmOld = SelectObject(hDC, hbm); 72 { 73 RECT rc = { 0, 0, cx, cy }; 74 FillRect(hDC, &rc, HBRUSH(COLOR_3DFACE + 1)); 75 if (hIcon) 76 { 77 DrawIconEx(hDC, 0, 0, hIcon, cx, cy, 0, NULL, DI_NORMAL); 78 } 79 } 80 SelectObject(hDC, hbmOld); 81 DeleteDC(hDC); 82 83 return hbm; 84} 85 86 87///////////////////////////////////////////////////////////////////////////// 88 89// CMSGlobalFolderOptionsStub --- The owner window of Folder Options. 90// This window hides taskbar button of Folder Options. 91 92#define GlobalFolderOptionsClassName _T("MSGlobalFolderOptionsStub") 93 94class CMSGlobalFolderOptionsStub : public CWindowImpl<CMSGlobalFolderOptionsStub> 95{ 96public: 97 DECLARE_WND_CLASS_EX(GlobalFolderOptionsClassName, 0, COLOR_WINDOWTEXT) 98 99 BEGIN_MSG_MAP(CMSGlobalFolderOptionsStub) 100 END_MSG_MAP() 101}; 102 103///////////////////////////////////////////////////////////////////////////// 104 105EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj); 106 107static int CALLBACK 108PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) 109{ 110 // NOTE: This callback is needed to set large icon correctly. 111 HICON hIcon; 112 switch (uMsg) 113 { 114 case PSCB_INITIALIZED: 115 { 116 hIcon = LoadIconW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_FOLDER_OPTIONS)); 117 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 118 break; 119 } 120 } 121 return 0; 122} 123 124enum { 125 PAGE_GENERAL, 126 PAGE_VIEW, 127 PAGE_FILETYPES 128}; 129 130static DWORD CALLBACK 131ShowFolderOptionsDialogThreadProc(LPVOID param) 132{ 133 CCoInit com; // Required when started from rundll32 (IRegTreeOptions, SHAutoComplete (in PickIconDlg)) 134 PROPSHEETHEADERW pinfo; 135 HPROPSHEETPAGE hppages[3]; 136 HPROPSHEETPAGE hpage; 137 UINT num_pages = 0; 138 139 hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_GENERAL, FolderOptionsGeneralDlg, 0, NULL); 140 if (hpage) 141 hppages[num_pages++] = hpage; 142 143 hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_VIEW, FolderOptionsViewDlg, 0, NULL); 144 if (hpage) 145 hppages[num_pages++] = hpage; 146 147 hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_FILETYPES, FolderOptionsFileTypesDlg, 0, NULL); 148 if (hpage) 149 hppages[num_pages++] = hpage; 150 151 // the stub window to hide taskbar button 152 DWORD style = WS_DISABLED | WS_CLIPSIBLINGS | WS_CAPTION; 153 DWORD exstyle = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW; 154 CMSGlobalFolderOptionsStub stub; 155 if (!stub.Create(NULL, NULL, NULL, style, exstyle)) 156 { 157 ERR("stub.Create failed\n"); 158 return 0; 159 } 160 161 memset(&pinfo, 0x0, sizeof(PROPSHEETHEADERW)); 162 pinfo.dwSize = sizeof(PROPSHEETHEADERW); 163 pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_USEICONID | PSH_USECALLBACK; 164 pinfo.hwndParent = stub; 165 pinfo.nPages = num_pages; 166 pinfo.phpage = hppages; 167 pinfo.hInstance = shell32_hInstance; 168 pinfo.pszIcon = MAKEINTRESOURCEW(IDI_SHELL_FOLDER_OPTIONS); 169 pinfo.pszCaption = MAKEINTRESOURCEW(IDS_FOLDER_OPTIONS); 170 pinfo.pfnCallback = PropSheetProc; 171 pinfo.nStartPage = PtrToUlong(param); 172 173 PropertySheetW(&pinfo); 174 175 stub.DestroyWindow(); 176 return 0; 177} 178 179VOID WINAPI 180ShowFolderOptionsDialog(UINT Page, BOOL Async = FALSE) 181{ 182 HWND hWnd = FindWindow(GlobalFolderOptionsClassName, NULL); 183 if (hWnd) 184 { 185 HWND hPop = GetLastActivePopup(hWnd); 186 if (hWnd == GetParent(hPop)) 187 { 188 PostMessage(hPop, PSM_SETCURSEL, Page, 0); 189 } 190 SetForegroundWindow(hPop); 191 return; 192 } 193 194 LPVOID param = UlongToPtr(Page); 195 if (Async) 196 SHCreateThread(ShowFolderOptionsDialogThreadProc, param, 0, 0); 197 else 198 ShowFolderOptionsDialogThreadProc(param); // Rundll32 caller cannot be async! 199} 200 201static VOID 202Options_RunDLLCommon(HWND hWnd, HINSTANCE hInst, int fOptions, DWORD nCmdShow) 203{ 204 switch(fOptions) 205 { 206 case 0: 207 ShowFolderOptionsDialog(PAGE_GENERAL); 208 break; 209 210 case 1: // Taskbar settings 211#if (NTDDI_VERSION >= NTDDI_VISTA) 212 case 3: // Start menu settings 213 case 4: // Tray icon settings 214 case 6: // Taskbar toolbars 215#endif 216 PostMessage(GetShellWindow(), WM_PROGMAN_OPENSHELLSETTINGS, fOptions, 0); 217 break; 218 219 case 7: // Windows 8, 10 220 ShowFolderOptionsDialog(PAGE_VIEW); 221 break; 222 223 default: 224 FIXME("unrecognized options id %d\n", fOptions); 225 } 226} 227 228/************************************************************************* 229 * Options_RunDLL (SHELL32.@) 230 */ 231EXTERN_C VOID WINAPI 232Options_RunDLL(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow) 233{ 234 Options_RunDLLCommon(hWnd, hInst, StrToIntA(cmd), nCmdShow); 235} 236 237/************************************************************************* 238 * Options_RunDLLA (SHELL32.@) 239 */ 240EXTERN_C VOID WINAPI 241Options_RunDLLA(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow) 242{ 243 Options_RunDLLCommon(hWnd, hInst, StrToIntA(cmd), nCmdShow); 244} 245 246/************************************************************************* 247 * Options_RunDLLW (SHELL32.@) 248 */ 249EXTERN_C VOID WINAPI 250Options_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow) 251{ 252 Options_RunDLLCommon(hWnd, hInst, StrToIntW(cmd), nCmdShow); 253}