Merge freeldr from amd64 branch:
[reactos.git] / reactos / dll / win32 / shell32 / folder_options.c
1 /*
2 * Open With Context Menu extension
3 *
4 * Copyright 2007 Johannes Anderwald <janderwald@reactos.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include <precomp.h>
22
23
24 WINE_DEFAULT_DEBUG_CHANNEL (fprop);
25 #define MAX_PROPERTY_SHEET_PAGE (32)
26
27 /// Folder Options:
28 /// CLASSKEY = HKEY_CLASSES_ROOT\CLSID\{6DFD7C5C-2451-11d3-A299-00C04F8EF6AF}
29 /// DefaultIcon = %SystemRoot%\system32\SHELL32.dll,-210
30 /// Verbs: Open / RunAs
31 /// Cmd: rundll32.exe shell32.dll,Options_RunDLL 0
32
33 /// ShellFolder Attributes: 0x0
34
35 typedef struct
36 {
37 DWORD cFiles;
38 DWORD cFolder;
39 LARGE_INTEGER bSize;
40 HWND hwndDlg;
41 WCHAR szFolderPath[MAX_PATH];
42 }FOLDER_PROPERTIES_CONTEXT, *PFOLDER_PROPERTIES_CONTEXT;
43
44 typedef struct
45 {
46 LPCWSTR szKeyName;
47 UINT ResourceID;
48 }FOLDER_VIEW_ENTRY, PFOLDER_VIEW_ENTRY;
49 /*
50 static FOLDER_VIEW_ENTRY s_Options[] =
51 {
52 { L"AlwaysShowMenus", IDS_ALWAYSSHOWMENUS },
53 { L"AutoCheckSelect", -1 },
54 { L"ClassicViewState", -1 },
55 { L"DontPrettyPath", -1 },
56 { L"Filter", -1 },
57 { L"FolderContentsInfoTip", IDS_FOLDERCONTENTSTIP },
58 { L"FriendlyTree", -1 },
59 { L"Hidden", -1, },
60 { L"HideFileExt", IDS_HIDEFILEEXT },
61 { L"HideIcons", -1},
62 { L"IconsOnly", -1},
63 { L"ListviewAlphaSelect", -1},
64 { L"ListviewShadow", -1},
65 { L"ListviewWatermark", -1},
66 { L"MapNetDrvBtn", -1},
67 { L"PersistBrowsers", -1},
68 { L"SeperateProcess", IDS_SEPERATEPROCESS},
69 { L"ServerAdminUI", -1},
70 { L"SharingWizardOn", IDS_USESHAREWIZARD},
71 { L"ShowCompColor", IDS_COMPCOLOR},
72 { L"ShowInfoTip", IDS_SHOWINFOTIP},
73 { L"ShowPreviewHandlers", -1},
74 { L"ShowSuperHidden", IDS_HIDEOSFILES},
75 { L"ShowTypeOverlay", -1},
76 { L"Start_ShowMyGames", -1},
77 { L"StartMenuInit", -1},
78 { L"SuperHidden", -1},
79 { L"TypeAhead", -1},
80 { L"Webview", -1},
81 { NULL, -1}
82
83 };
84 */
85
86
87 INT_PTR
88 CALLBACK
89 FolderOptionsGeneralDlg(
90 HWND hwndDlg,
91 UINT uMsg,
92 WPARAM wParam,
93 LPARAM lParam
94 )
95 {
96
97
98
99 return FALSE;
100 }
101
102 static
103 VOID
104 InitializeFolderOptionsListCtrl(HWND hwndDlg)
105 {
106 RECT clientRect;
107 LVCOLUMNW col;
108 WCHAR szName[50];
109 HWND hDlgCtrl;
110
111 hDlgCtrl = GetDlgItem(hwndDlg, 14003);
112
113 if (!LoadStringW(shell32_hInstance, IDS_COLUMN_EXTENSION, szName, sizeof(szName) / sizeof(WCHAR)))
114 szName[0] = 0;
115 szName[(sizeof(szName)/sizeof(WCHAR))-1] = 0;
116
117 GetClientRect(hDlgCtrl, &clientRect);
118 ZeroMemory(&col, sizeof(LV_COLUMN));
119 col.mask = LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT;
120 col.iSubItem = 0;
121 col.pszText = szName;
122 col.fmt = LVCFMT_LEFT;
123 col.cx = (clientRect.right - clientRect.left) - GetSystemMetrics(SM_CXVSCROLL);
124 (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMN, 0, (LPARAM)&col);
125
126
127
128 }
129
130
131 INT_PTR
132 CALLBACK
133 FolderOptionsViewDlg(
134 HWND hwndDlg,
135 UINT uMsg,
136 WPARAM wParam,
137 LPARAM lParam
138 )
139 {
140 switch(uMsg)
141 {
142 case WM_INITDIALOG:
143 InitializeFolderOptionsListCtrl(hwndDlg);
144 return TRUE;
145 }
146
147 return FALSE;
148
149 }
150
151 VOID
152 InitializeFileTypesListCtrlColumns(HWND hDlgCtrl)
153 {
154 RECT clientRect;
155 LVCOLUMNW col;
156 WCHAR szName[50];
157
158 if (!LoadStringW(shell32_hInstance, IDS_COLUMN_EXTENSION, szName, sizeof(szName) / sizeof(WCHAR)))
159 szName[0] = 0;
160 szName[(sizeof(szName)/sizeof(WCHAR))-1] = 0;
161
162 GetClientRect(hDlgCtrl, &clientRect);
163 ZeroMemory(&col, sizeof(LV_COLUMN));
164 col.mask = LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT;
165 col.iSubItem = 0;
166 col.pszText = szName;
167 col.fmt = LVCFMT_LEFT;
168 col.cx = (clientRect.right - clientRect.left) - GetSystemMetrics(SM_CXVSCROLL);
169 (void)SendMessageW(hDlgCtrl, LVM_INSERTCOLUMNW, 0, (LPARAM)&col);
170 }
171 INT
172 FindItem(HWND hDlgCtrl, WCHAR * ItemName)
173 {
174 LVFINDINFOW findInfo;
175 ZeroMemory(&findInfo, sizeof(LVFINDINFOW));
176
177 findInfo.flags = LVFI_STRING;
178 findInfo.psz = ItemName;
179 return ListView_FindItem(hDlgCtrl, 0, &findInfo);
180 }
181
182 VOID
183 InsertFileType(HWND hDlgCtrl, WCHAR * szName, DWORD Size, INT iItem)
184 {
185 WCHAR szPath[100];
186 HKEY hKey;
187 LVITEMW lvItem;
188 DWORD dwSize;
189
190 if (FindItem(hDlgCtrl, szName) != -1)
191 return;
192
193 wcscpy(szPath, szName);
194 /* get the name */
195 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szPath, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
196 {
197 if (RegLoadMUIStringW(hKey, L"FriendlyTypeName", szName, Size, NULL, 0, NULL) != ERROR_SUCCESS)
198 {
199 dwSize = Size;
200 if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)szName, &dwSize) != ERROR_SUCCESS)
201 {
202 wcscpy(szName, szPath);
203 }
204 }
205 RegCloseKey(hKey);
206 szName[(Size/sizeof(WCHAR))-1] = 0;
207 }
208 wcscat(szPath, L"\\shell");
209
210 ZeroMemory(&lvItem, sizeof(LVITEMW));
211 lvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
212 lvItem.state = LVIS_SELECTED;
213 lvItem.pszText = szName;
214 lvItem.iItem = iItem;
215
216 if (RegOpenKeyExW(HKEY_CLASSES_ROOT, szPath, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
217 {
218 lvItem.lParam = 0;
219 (void)SendMessageW(hDlgCtrl, LVM_INSERTITEMW, 0, (LPARAM)&lvItem);
220 RegCloseKey(hKey);
221 }
222 }
223
224 BOOL
225 InitializeFileTypesListCtrl(HWND hwndDlg)
226 {
227 HWND hDlgCtrl;
228 DWORD dwIndex = 0;
229 WCHAR szName[50];
230 DWORD dwName;
231 INT iItem = 0;
232
233 hDlgCtrl = GetDlgItem(hwndDlg, 14000);
234 InitializeFileTypesListCtrlColumns(hDlgCtrl);
235
236 dwName = sizeof(szName) / sizeof(WCHAR);
237
238 while(RegEnumKeyExW(HKEY_CLASSES_ROOT, dwIndex++, szName, &dwName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
239 {
240 InsertFileType(hDlgCtrl, szName, sizeof(szName), iItem++);
241 dwName = sizeof(szName) / sizeof(WCHAR);
242 }
243 return TRUE;
244 }
245
246
247 INT_PTR
248 CALLBACK
249 FolderOptionsFileTypesDlg(
250 HWND hwndDlg,
251 UINT uMsg,
252 WPARAM wParam,
253 LPARAM lParam
254 )
255 {
256 switch(uMsg)
257 {
258 case WM_INITDIALOG:
259 InitializeFileTypesListCtrl(hwndDlg);
260 return TRUE;
261 }
262
263 return FALSE;
264 }
265
266
267 VOID
268 ShowFolderOptionsDialog(HWND hWnd, HINSTANCE hInst)
269 {
270 PROPSHEETHEADERW pinfo;
271 HPROPSHEETPAGE hppages[3];
272 HPROPSHEETPAGE hpage;
273 UINT num_pages = 0;
274 WCHAR szOptions[100];
275
276 hpage = SH_CreatePropertySheetPage("FOLDER_OPTIONS_GENERAL_DLG", FolderOptionsGeneralDlg, 0, NULL);
277 if (hpage)
278 hppages[num_pages++] = hpage;
279
280 hpage = SH_CreatePropertySheetPage("FOLDER_OPTIONS_VIEW_DLG", FolderOptionsViewDlg, 0, NULL);
281 if (hpage)
282 hppages[num_pages++] = hpage;
283
284 hpage = SH_CreatePropertySheetPage("FOLDER_OPTIONS_FILETYPES_DLG", FolderOptionsFileTypesDlg, 0, NULL);
285 if (hpage)
286 hppages[num_pages++] = hpage;
287
288 szOptions[0] = L'\0';
289 LoadStringW(shell32_hInstance, IDS_FOLDER_OPTIONS, szOptions, sizeof(szOptions) / sizeof(WCHAR));
290 szOptions[(sizeof(szOptions)/sizeof(WCHAR))-1] = L'\0';
291
292 memset(&pinfo, 0x0, sizeof(PROPSHEETHEADERW));
293 pinfo.dwSize = sizeof(PROPSHEETHEADERW);
294 pinfo.dwFlags = PSH_NOCONTEXTHELP;
295 pinfo.nPages = num_pages;
296 pinfo.u3.phpage = hppages;
297 pinfo.pszCaption = szOptions;
298
299 PropertySheetW(&pinfo);
300 }
301
302 VOID
303 Options_RunDLLCommon(HWND hWnd, HINSTANCE hInst, int fOptions, DWORD nCmdShow)
304 {
305 switch(fOptions)
306 {
307 case 0:
308 ShowFolderOptionsDialog(hWnd, hInst);
309 break;
310 case 1:
311 // show taskbar options dialog
312 FIXME("notify explorer to show taskbar options dialog");
313 //PostMessage(GetShellWindow(), WM_USER+22, fOptions, 0);
314 break;
315 default:
316 FIXME("unrecognized options id %d\n", fOptions);
317 }
318 }
319
320 /*************************************************************************
321 * Options_RunDLL (SHELL32.@)
322 */
323 VOID WINAPI Options_RunDLL(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
324 {
325 Options_RunDLLCommon(hWnd, hInst, StrToIntA(cmd), nCmdShow);
326 }
327 /*************************************************************************
328 * Options_RunDLLA (SHELL32.@)
329 */
330 VOID WINAPI Options_RunDLLA(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
331 {
332 Options_RunDLLCommon(hWnd, hInst, StrToIntA(cmd), nCmdShow);
333 }
334
335 /*************************************************************************
336 * Options_RunDLLW (SHELL32.@)
337 */
338 VOID WINAPI Options_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow)
339 {
340 Options_RunDLLCommon(hWnd, hInst, StrToIntW(cmd), nCmdShow);
341 }
342
343 static
344 DWORD WINAPI
345 CountFolderAndFiles(LPVOID lParam)
346 {
347 WIN32_FIND_DATAW FindData;
348 HANDLE hFile;
349 UINT Length;
350 LPWSTR pOffset;
351 BOOL ret;
352 PFOLDER_PROPERTIES_CONTEXT pContext = (PFOLDER_PROPERTIES_CONTEXT) lParam;
353
354 pOffset = PathAddBackslashW(pContext->szFolderPath);
355 if (!pOffset)
356 return 0;
357
358 Length = pOffset - pContext->szFolderPath;
359
360 wcscpy(pOffset, L"*.*");
361 hFile = FindFirstFileW(pContext->szFolderPath, &FindData);
362 if (hFile == INVALID_HANDLE_VALUE)
363 return 0;
364
365 do
366 {
367 ret = FindNextFileW(hFile, &FindData);
368 if (ret)
369 {
370 if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
371 {
372 if (FindData.cFileName[0] == L'.' && FindData.cFileName[1] == L'.' &&
373 FindData.cFileName[2] == L'\0')
374 continue;
375
376 pContext->cFolder++;
377 wcscpy(pOffset, FindData.cFileName);
378 CountFolderAndFiles((LPVOID)pContext);
379 pOffset[0] = L'\0';
380 }
381 else
382 {
383 pContext->cFiles++;
384 pContext->bSize.u.LowPart += FindData.nFileSizeLow;
385 pContext->bSize.u.HighPart += FindData.nFileSizeHigh;
386 }
387 }
388 else if (GetLastError() == ERROR_NO_MORE_FILES)
389 {
390 break;
391 }
392 }while(1);
393
394 FindClose(hFile);
395 return 1;
396 }
397
398 static
399 VOID
400 InitializeFolderGeneralDlg(PFOLDER_PROPERTIES_CONTEXT pContext)
401 {
402 LPWSTR pFolderName;
403 WIN32_FILE_ATTRIBUTE_DATA FolderAttribute;
404 FILETIME ft;
405 SYSTEMTIME dt;
406 WCHAR szBuffer[MAX_PATH+5];
407 WCHAR szFormat[30] = {0};
408
409 static const WCHAR wFormat[] = {'%','0','2','d','/','%','0','2','d','/','%','0','4','d',' ',' ','%','0','2','d',':','%','0','2','u',0};
410
411 pFolderName = wcsrchr(pContext->szFolderPath, L'\\');
412 if (!pFolderName)
413 return;
414
415 /* set folder name */
416 SendDlgItemMessageW(pContext->hwndDlg, 14001, WM_SETTEXT, 0, (LPARAM) (pFolderName + 1));
417 /* set folder location */
418 pFolderName[0] = L'\0';
419 if (wcslen(pContext->szFolderPath) == 2)
420 {
421 /* folder is located at root */
422 WCHAR szDrive[4] = {L'C',L':',L'\\',L'\0'};
423 szDrive[0] = pContext->szFolderPath[0];
424 SendDlgItemMessageW(pContext->hwndDlg, 14007, WM_SETTEXT, 0, (LPARAM) szDrive);
425 }
426 else
427 {
428 SendDlgItemMessageW(pContext->hwndDlg, 14007, WM_SETTEXT, 0, (LPARAM) pContext->szFolderPath);
429 }
430 pFolderName[0] = L'\\';
431 /* get folder properties */
432 if (GetFileAttributesExW(pContext->szFolderPath, GetFileExInfoStandard, (LPVOID)&FolderAttribute))
433 {
434 if (FolderAttribute.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
435 {
436 /* check readonly button */
437 SendDlgItemMessage(pContext->hwndDlg, 14021, BM_SETCHECK, BST_CHECKED, 0);
438 }
439
440 if (FolderAttribute.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
441 {
442 /* check hidden button */
443 SendDlgItemMessage(pContext->hwndDlg, 14022, BM_SETCHECK, BST_CHECKED, 0);
444 }
445
446 if (FileTimeToLocalFileTime(&FolderAttribute.ftCreationTime, &ft))
447 {
448 FileTimeToSystemTime(&ft, &dt);
449 swprintf (szBuffer, wFormat, dt.wDay, dt.wMonth, dt.wYear, dt.wHour, dt.wMinute);
450 SendDlgItemMessageW(pContext->hwndDlg, 14015, WM_SETTEXT, 0, (LPARAM) szBuffer);
451 }
452 }
453 /* now enumerate enumerate contents */
454 wcscpy(szBuffer, pContext->szFolderPath);
455 CountFolderAndFiles((LPVOID)pContext);
456 wcscpy(pContext->szFolderPath, szBuffer);
457 /* set folder details */
458 LoadStringW(shell32_hInstance, IDS_FILE_FOLDER, szFormat, sizeof(szFormat)/sizeof(WCHAR));
459 szFormat[(sizeof(szFormat)/sizeof(WCHAR))-1] = L'\0';
460 swprintf(szBuffer, szFormat, pContext->cFiles, pContext->cFolder);
461 SendDlgItemMessageW(pContext->hwndDlg, 14011, WM_SETTEXT, 0, (LPARAM) szBuffer);
462
463 if (StrFormatByteSizeW(pContext->bSize.QuadPart, szBuffer, sizeof(szBuffer)/sizeof(WCHAR)))
464 {
465 /* store folder size */
466 SendDlgItemMessageW(pContext->hwndDlg, 14009, WM_SETTEXT, 0, (LPARAM) szBuffer);
467 }
468 }
469
470
471 INT_PTR
472 CALLBACK
473 FolderPropertiesGeneralDlg(
474 HWND hwndDlg,
475 UINT uMsg,
476 WPARAM wParam,
477 LPARAM lParam
478 )
479 {
480 LPPROPSHEETPAGEW ppsp;
481 PFOLDER_PROPERTIES_CONTEXT pContext;
482 HICON hIcon;
483 WIN32_FILE_ATTRIBUTE_DATA FolderAttribute;
484 LONG res;
485 LPPSHNOTIFY lppsn;
486 DWORD Attribute;
487
488 switch(uMsg)
489 {
490 case WM_INITDIALOG:
491 ppsp = (LPPROPSHEETPAGEW)lParam;
492 if (ppsp == NULL)
493 break;
494 hIcon = LoadIconW(shell32_hInstance, MAKEINTRESOURCEW(IDI_SHELL_FOLDER_OPEN));
495 if (hIcon)
496 SendDlgItemMessageW(hwndDlg, 14000, STM_SETICON, (WPARAM)hIcon, 0);
497
498 pContext = SHAlloc(sizeof(FOLDER_PROPERTIES_CONTEXT));
499 if (pContext)
500 {
501 ZeroMemory(pContext, sizeof(FOLDER_PROPERTIES_CONTEXT));
502 pContext->hwndDlg = hwndDlg;
503 wcscpy(pContext->szFolderPath, (LPWSTR)ppsp->lParam);
504 SetWindowLongPtr(hwndDlg, DWL_USER, (LONG_PTR)pContext);
505 InitializeFolderGeneralDlg(pContext);
506 }
507 return TRUE;
508 case WM_COMMAND:
509 if (HIWORD(wParam) == BN_CLICKED)
510 {
511 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
512 }
513 break;
514 case WM_DESTROY:
515 pContext = (PFOLDER_PROPERTIES_CONTEXT)GetWindowLong(hwndDlg, DWL_USER);
516 SHFree((LPVOID)pContext);
517 break;
518 case WM_NOTIFY:
519 pContext = (PFOLDER_PROPERTIES_CONTEXT)GetWindowLong(hwndDlg, DWL_USER);
520 lppsn = (LPPSHNOTIFY) lParam;
521 if (lppsn->hdr.code == PSN_APPLY)
522 {
523 if (GetFileAttributesExW(pContext->szFolderPath, GetFileExInfoStandard, (LPVOID)&FolderAttribute))
524 {
525 res = SendDlgItemMessageW(hwndDlg, 14021, BM_GETCHECK, 0, 0);
526 if (res == BST_CHECKED)
527 FolderAttribute.dwFileAttributes |= FILE_ATTRIBUTE_READONLY;
528 else
529 FolderAttribute.dwFileAttributes &= (~FILE_ATTRIBUTE_READONLY);
530
531 res = SendDlgItemMessageW(hwndDlg, 14022, BM_GETCHECK, 0, 0);
532 if (res == BST_CHECKED)
533 FolderAttribute.dwFileAttributes |= FILE_ATTRIBUTE_HIDDEN;
534 else
535 FolderAttribute.dwFileAttributes &= (~FILE_ATTRIBUTE_HIDDEN);
536
537 Attribute = FolderAttribute.dwFileAttributes &
538 (FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_TEMPORARY);
539
540 SetFileAttributesW(pContext->szFolderPath, Attribute);
541 }
542 SetWindowLong( hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR );
543 return TRUE;
544 }
545 break;
546 }
547 return FALSE;
548 }
549
550 static
551 BOOL
552 CALLBACK
553 FolderAddPropSheetPageProc(HPROPSHEETPAGE hpage, LPARAM lParam)
554 {
555 PROPSHEETHEADERW *ppsh = (PROPSHEETHEADERW *)lParam;
556 if (ppsh != NULL && ppsh->nPages < MAX_PROPERTY_SHEET_PAGE)
557 {
558 ppsh->u3.phpage[ppsh->nPages++] = hpage;
559 return TRUE;
560 }
561 return FALSE;
562 }
563
564 BOOL
565 SH_ShowFolderProperties(LPWSTR pwszFolder)
566 {
567 HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE];
568 HPROPSHEETPAGE hpage;
569 PROPSHEETHEADERW psh;
570 BOOL ret;
571 WCHAR szName[MAX_PATH] = {0};
572 HPSXA hpsx;
573 LPWSTR pFolderName;
574
575 if (!PathIsDirectoryW(pwszFolder))
576 return FALSE;
577
578 pFolderName = wcsrchr(pwszFolder, L'\\');
579 if (!pFolderName)
580 return FALSE;
581
582 wcscpy(szName, pFolderName + 1);
583
584 hpage = SH_CreatePropertySheetPage("SHELL_FOLDER_GENERAL_DLG", FolderPropertiesGeneralDlg, (LPARAM)pwszFolder, NULL);
585 if (!hpage)
586 return FALSE;
587
588 ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));
589 hppages[psh.nPages] = hpage;
590 psh.nPages++;
591 psh.dwSize = sizeof(PROPSHEETHEADERW);
592 psh.dwFlags = PSH_PROPTITLE;
593 psh.hwndParent = NULL;
594 psh.u3.phpage = hppages;
595 psh.pszCaption = szName;
596
597 hpsx = SHCreatePropSheetExtArray(HKEY_CLASSES_ROOT,
598 L"Folder",
599 MAX_PROPERTY_SHEET_PAGE-1);
600
601 SHAddFromPropSheetExtArray(hpsx,
602 (LPFNADDPROPSHEETPAGE)FolderAddPropSheetPageProc,
603 (LPARAM)&psh);
604
605 ret = PropertySheetW(&psh);
606 if (ret < 0)
607 return FALSE;
608 else
609 return TRUE;
610 }
611
612