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 24 WINE_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 33 LPCWSTR g_pszShell32 = L"%SystemRoot%\\system32\\shell32.dll"; 34 35 // the space characters 36 LPCWSTR g_pszSpace = L" \t\n\r\f\v"; 37 38 ///////////////////////////////////////////////////////////////////////////// 39 // utility functions 40 41 HBITMAP 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 58 HBITMAP 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 HBITMAP CreateCheckImage(HDC hDC, BOOL bCheck, BOOL bEnabled) 87 { 88 INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON); 89 INT cySmallIcon = GetSystemMetrics(SM_CYSMICON); 90 91 HBITMAP hbm = Create24BppBitmap(hDC, cxSmallIcon, cySmallIcon); 92 if (hbm == NULL) 93 return NULL; // failure 94 95 RECT Rect, BoxRect; 96 SetRect(&Rect, 0, 0, cxSmallIcon, cySmallIcon); 97 BoxRect = Rect; 98 InflateRect(&BoxRect, -1, -1); 99 100 HGDIOBJ hbmOld = SelectObject(hDC, hbm); 101 { 102 UINT uState = DFCS_BUTTONCHECK | DFCS_FLAT | DFCS_MONO; 103 if (bCheck) 104 uState |= DFCS_CHECKED; 105 if (!bEnabled) 106 uState |= DFCS_INACTIVE; 107 DrawFrameControl(hDC, &BoxRect, DFC_BUTTON, uState); 108 } 109 SelectObject(hDC, hbmOld); 110 111 return hbm; // success 112 } 113 114 HBITMAP CreateCheckMask(HDC hDC) 115 { 116 INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON); 117 INT cySmallIcon = GetSystemMetrics(SM_CYSMICON); 118 119 HBITMAP hbm = CreateBitmap(cxSmallIcon, cySmallIcon, 1, 1, NULL); 120 if (hbm == NULL) 121 return NULL; // failure 122 123 RECT Rect, BoxRect; 124 SetRect(&Rect, 0, 0, cxSmallIcon, cySmallIcon); 125 BoxRect = Rect; 126 InflateRect(&BoxRect, -1, -1); 127 128 HGDIOBJ hbmOld = SelectObject(hDC, hbm); 129 { 130 FillRect(hDC, &Rect, HBRUSH(GetStockObject(WHITE_BRUSH))); 131 FillRect(hDC, &BoxRect, HBRUSH(GetStockObject(BLACK_BRUSH))); 132 } 133 SelectObject(hDC, hbmOld); 134 135 return hbm; // success 136 } 137 138 HBITMAP CreateRadioImage(HDC hDC, BOOL bCheck, BOOL bEnabled) 139 { 140 INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON); 141 INT cySmallIcon = GetSystemMetrics(SM_CYSMICON); 142 143 HBITMAP hbm = Create24BppBitmap(hDC, cxSmallIcon, cySmallIcon); 144 if (hbm == NULL) 145 return NULL; // failure 146 147 RECT Rect, BoxRect; 148 SetRect(&Rect, 0, 0, cxSmallIcon, cySmallIcon); 149 BoxRect = Rect; 150 InflateRect(&BoxRect, -1, -1); 151 152 HGDIOBJ hbmOld = SelectObject(hDC, hbm); 153 { 154 UINT uState = DFCS_BUTTONRADIOIMAGE | DFCS_FLAT | DFCS_MONO; 155 if (bCheck) 156 uState |= DFCS_CHECKED; 157 if (!bEnabled) 158 uState |= DFCS_INACTIVE; 159 DrawFrameControl(hDC, &BoxRect, DFC_BUTTON, uState); 160 } 161 SelectObject(hDC, hbmOld); 162 163 return hbm; // success 164 } 165 166 HBITMAP CreateRadioMask(HDC hDC) 167 { 168 INT cxSmallIcon = GetSystemMetrics(SM_CXSMICON); 169 INT cySmallIcon = GetSystemMetrics(SM_CYSMICON); 170 171 HBITMAP hbm = CreateBitmap(cxSmallIcon, cySmallIcon, 1, 1, NULL); 172 if (hbm == NULL) 173 return NULL; // failure 174 175 RECT Rect, BoxRect; 176 SetRect(&Rect, 0, 0, cxSmallIcon, cySmallIcon); 177 BoxRect = Rect; 178 InflateRect(&BoxRect, -1, -1); 179 180 HGDIOBJ hbmOld = SelectObject(hDC, hbm); 181 { 182 FillRect(hDC, &Rect, HBRUSH(GetStockObject(WHITE_BRUSH))); 183 UINT uState = DFCS_BUTTONRADIOMASK | DFCS_FLAT | DFCS_MONO; 184 DrawFrameControl(hDC, &BoxRect, DFC_BUTTON, uState); 185 } 186 SelectObject(hDC, hbmOld); 187 188 return hbm; // success 189 } 190 191 ///////////////////////////////////////////////////////////////////////////// 192 193 // CMSGlobalFolderOptionsStub --- The owner window of Folder Options. 194 // This window hides taskbar button of Folder Options. 195 class CMSGlobalFolderOptionsStub : public CWindowImpl<CMSGlobalFolderOptionsStub> 196 { 197 public: 198 DECLARE_WND_CLASS_EX(_T("MSGlobalFolderOptionsStub"), 0, COLOR_WINDOWTEXT) 199 200 BEGIN_MSG_MAP(CMSGlobalFolderOptionsStub) 201 END_MSG_MAP() 202 }; 203 204 ///////////////////////////////////////////////////////////////////////////// 205 206 EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj); 207 208 static int CALLBACK 209 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam) 210 { 211 // NOTE: This callback is needed to set large icon correctly. 212 HICON hIcon; 213 switch (uMsg) 214 { 215 case PSCB_INITIALIZED: 216 { 217 hIcon = LoadIconW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_FOLDER_OPTIONS)); 218 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon); 219 break; 220 } 221 } 222 return 0; 223 } 224 225 static VOID 226 ShowFolderOptionsDialog(HWND hWnd, HINSTANCE hInst) 227 { 228 PROPSHEETHEADERW pinfo; 229 HPROPSHEETPAGE hppages[3]; 230 HPROPSHEETPAGE hpage; 231 UINT num_pages = 0; 232 WCHAR szOptions[100]; 233 234 hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_GENERAL, FolderOptionsGeneralDlg, 0, NULL); 235 if (hpage) 236 hppages[num_pages++] = hpage; 237 238 hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_VIEW, FolderOptionsViewDlg, 0, NULL); 239 if (hpage) 240 hppages[num_pages++] = hpage; 241 242 hpage = SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_FILETYPES, FolderOptionsFileTypesDlg, 0, NULL); 243 if (hpage) 244 hppages[num_pages++] = hpage; 245 246 szOptions[0] = 0; 247 LoadStringW(shell32_hInstance, IDS_FOLDER_OPTIONS, szOptions, _countof(szOptions)); 248 szOptions[_countof(szOptions) - 1] = 0; 249 250 // the stub window to hide taskbar button 251 DWORD style = WS_DISABLED | WS_CLIPSIBLINGS | WS_CAPTION; 252 DWORD exstyle = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW; 253 CMSGlobalFolderOptionsStub stub; 254 if (!stub.Create(NULL, NULL, NULL, style, exstyle)) 255 { 256 ERR("stub.Create failed\n"); 257 return; 258 } 259 260 memset(&pinfo, 0x0, sizeof(PROPSHEETHEADERW)); 261 pinfo.dwSize = sizeof(PROPSHEETHEADERW); 262 pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_USEICONID | PSH_USECALLBACK; 263 pinfo.hwndParent = stub; 264 pinfo.nPages = num_pages; 265 pinfo.phpage = hppages; 266 pinfo.pszIcon = MAKEINTRESOURCEW(IDI_SHELL_FOLDER_OPTIONS); 267 pinfo.pszCaption = szOptions; 268 pinfo.pfnCallback = PropSheetProc; 269 270 PropertySheetW(&pinfo); 271 272 stub.DestroyWindow(); 273 } 274 275 static VOID 276 Options_RunDLLCommon(HWND hWnd, HINSTANCE hInst, int fOptions, DWORD nCmdShow) 277 { 278 switch(fOptions) 279 { 280 case 0: 281 ShowFolderOptionsDialog(hWnd, hInst); 282 break; 283 284 case 1: 285 // show taskbar options dialog 286 FIXME("notify explorer to show taskbar options dlg\n"); 287 //PostMessage(GetShellWindow(), WM_USER+22, fOptions, 0); 288 break; 289 290 default: 291 FIXME("unrecognized options id %d\n", fOptions); 292 } 293 } 294 295 /************************************************************************* 296 * Options_RunDLL (SHELL32.@) 297 */ 298 EXTERN_C VOID WINAPI 299 Options_RunDLL(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow) 300 { 301 Options_RunDLLCommon(hWnd, hInst, StrToIntA(cmd), nCmdShow); 302 } 303 304 /************************************************************************* 305 * Options_RunDLLA (SHELL32.@) 306 */ 307 EXTERN_C VOID WINAPI 308 Options_RunDLLA(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow) 309 { 310 Options_RunDLLCommon(hWnd, hInst, StrToIntA(cmd), nCmdShow); 311 } 312 313 /************************************************************************* 314 * Options_RunDLLW (SHELL32.@) 315 */ 316 EXTERN_C VOID WINAPI 317 Options_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow) 318 { 319 Options_RunDLLCommon(hWnd, hInst, StrToIntW(cmd), nCmdShow); 320 } 321