2 * Open With Context Menu extension
4 * Copyright 2007 Johannes Anderwald <johannes.anderwald@reactos.org>
5 * Copyright 2016-2017 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
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.
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.
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
24 WINE_DEFAULT_DEBUG_CHANNEL (fprop
);
26 #define MAX_PROPERTY_SHEET_PAGE (32)
29 /// CLASSKEY = HKEY_CLASSES_ROOT\CLSID\{6DFD7C5C-2451-11d3-A299-00C04F8EF6AF}
30 /// DefaultIcon = %SystemRoot%\system32\SHELL32.dll,-210
31 /// Verbs: Open / RunAs
32 /// Cmd: rundll32.exe shell32.dll,Options_RunDLL 0
34 /// ShellFolder Attributes: 0x0
38 WCHAR FileExtension
[30];
39 WCHAR FileDescription
[100];
40 WCHAR ClassKey
[MAX_PATH
];
42 } FOLDER_FILE_TYPE_ENTRY
, *PFOLDER_FILE_TYPE_ENTRY
;
44 // uniquely-defined icon entry for Advanced Settings
45 typedef struct ADVANCED_ICON
47 WCHAR szPath
[MAX_PATH
];
51 // predefined icon IDs (See CreateTreeImageList function below)
54 #define I_CHECKED_DISABLED 2
55 #define I_UNCHECKED_DISABLED 3
56 #define I_RADIO_CHECKED 4
57 #define I_RADIO_UNCHECKED 5
58 #define I_RADIO_CHECKED_DISABLED 6
59 #define I_RADIO_UNCHECKED_DISABLED 7
61 #define PREDEFINED_ICON_COUNT 8
63 // definition of icon stock
64 static ADVANCED_ICON
* s_AdvancedIcons
= NULL
;
65 static INT s_AdvancedIconCount
= 0;
66 static HIMAGELIST s_hImageList
= NULL
;
69 Advanced_FindIcon(LPCWSTR pszPath
, UINT nIconIndex
)
71 for (INT i
= PREDEFINED_ICON_COUNT
; i
< s_AdvancedIconCount
; ++i
)
73 ADVANCED_ICON
*pIcon
= &s_AdvancedIcons
[i
];
74 if (pIcon
->nIconIndex
== nIconIndex
&&
75 lstrcmpiW(pIcon
->szPath
, pszPath
) == 0)
80 return -1; // not found
84 Advanced_AddIcon(LPCWSTR pszPath
, UINT nIconIndex
)
86 ADVANCED_ICON
*pAllocated
;
88 // return the ID if already existed
89 INT nIconID
= Advanced_FindIcon(pszPath
, nIconIndex
);
91 return nIconID
; // already exists
93 // extract a small icon
94 HICON hIconSmall
= NULL
;
95 ExtractIconExW(pszPath
, nIconIndex
, NULL
, &hIconSmall
, 1);
96 if (hIconSmall
== NULL
)
99 // resize s_AdvancedIcons
100 size_t Size
= (s_AdvancedIconCount
+ 1) * sizeof(ADVANCED_ICON
);
101 pAllocated
= (ADVANCED_ICON
*)realloc(s_AdvancedIcons
, Size
);
102 if (pAllocated
== NULL
)
103 return -1; // failure
105 s_AdvancedIcons
= pAllocated
;
107 // save icon information
108 ADVANCED_ICON
*pIcon
= &s_AdvancedIcons
[s_AdvancedIconCount
];
109 lstrcpynW(pIcon
->szPath
, pszPath
, _countof(pIcon
->szPath
));
110 pIcon
->nIconIndex
= nIconIndex
;
112 // add the icon to the image list
113 ImageList_AddIcon(s_hImageList
, hIconSmall
);
115 // increment the counter
116 nIconID
= s_AdvancedIconCount
;
117 ++s_AdvancedIconCount
;
119 DestroyIcon(hIconSmall
);
121 return nIconID
; // newly-added icon ID
124 // types of Advanced Setting entry
125 typedef enum ADVANCED_ENTRY_TYPE
130 } ADVANCED_ENTRY_TYPE
;
132 // an entry info of Advanced Settings
133 typedef struct ADVANCED_ENTRY
135 DWORD dwID
; // entry ID
136 DWORD dwParentID
; // parent entry ID
137 DWORD dwResourceID
; // resource ID
138 WCHAR szKeyName
[64]; // entry key name
139 DWORD dwType
; // ADVANCED_ENTRY_TYPE
140 DWORD dwOrdinal
; // ordinal number
141 WCHAR szText
[MAX_PATH
]; // text
142 INT nIconID
; // icon ID (See ADVANCED_ICON)
144 HKEY hkeyRoot
; // registry root key
145 WCHAR szRegPath
[MAX_PATH
]; // registry path
146 WCHAR szValueName
[64]; // registry value name
148 DWORD dwCheckedValue
; // checked value
149 DWORD dwUncheckedValue
; // unchecked value
150 DWORD dwDefaultValue
; // defalut value
151 BOOL bHasUncheckedValue
; // If FALSE, UncheckedValue is invalid
153 HTREEITEM hItem
; // for TreeView
154 BOOL bGrayed
; // disabled?
155 BOOL bChecked
; // checked?
156 } ADVANCED_ENTRY
, *PADVANCED_ENTRY
;
158 // definition of advanced entries
159 static ADVANCED_ENTRY
* s_Advanced
= NULL
;
160 static INT s_AdvancedCount
= 0;
163 Create24BppBitmap(HDC hDC
, INT cx
, INT cy
)
168 ZeroMemory(&bi
, sizeof(bi
));
169 bi
.bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
170 bi
.bmiHeader
.biWidth
= cx
;
171 bi
.bmiHeader
.biHeight
= cy
;
172 bi
.bmiHeader
.biPlanes
= 1;
173 bi
.bmiHeader
.biBitCount
= 24;
174 bi
.bmiHeader
.biCompression
= BI_RGB
;
176 HBITMAP hbm
= CreateDIBSection(hDC
, &bi
, DIB_RGB_COLORS
, &pvBits
, NULL
, 0);
181 CreateCheckImage(HDC hDC
, BOOL bCheck
, BOOL bEnabled
= TRUE
)
183 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
184 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
186 HBITMAP hbm
= Create24BppBitmap(hDC
, cxSmallIcon
, cySmallIcon
);
188 return NULL
; // failure
191 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
193 InflateRect(&BoxRect
, -1, -1);
195 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
197 UINT uState
= DFCS_BUTTONCHECK
| DFCS_FLAT
| DFCS_MONO
;
199 uState
|= DFCS_CHECKED
;
201 uState
|= DFCS_INACTIVE
;
202 DrawFrameControl(hDC
, &BoxRect
, DFC_BUTTON
, uState
);
204 SelectObject(hDC
, hbmOld
);
206 return hbm
; // success
210 CreateCheckMask(HDC hDC
)
212 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
213 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
215 HBITMAP hbm
= CreateBitmap(cxSmallIcon
, cySmallIcon
, 1, 1, NULL
);
217 return NULL
; // failure
220 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
222 InflateRect(&BoxRect
, -1, -1);
224 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
226 FillRect(hDC
, &Rect
, HBRUSH(GetStockObject(WHITE_BRUSH
)));
227 FillRect(hDC
, &BoxRect
, HBRUSH(GetStockObject(BLACK_BRUSH
)));
229 SelectObject(hDC
, hbmOld
);
231 return hbm
; // success
235 CreateRadioImage(HDC hDC
, BOOL bCheck
, BOOL bEnabled
= TRUE
)
237 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
238 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
240 HBITMAP hbm
= Create24BppBitmap(hDC
, cxSmallIcon
, cySmallIcon
);
242 return NULL
; // failure
245 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
247 InflateRect(&BoxRect
, -1, -1);
249 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
251 UINT uState
= DFCS_BUTTONRADIOIMAGE
| DFCS_FLAT
| DFCS_MONO
;
253 uState
|= DFCS_CHECKED
;
255 uState
|= DFCS_INACTIVE
;
256 DrawFrameControl(hDC
, &BoxRect
, DFC_BUTTON
, uState
);
258 SelectObject(hDC
, hbmOld
);
260 return hbm
; // success
264 CreateRadioMask(HDC hDC
)
266 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
267 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
269 HBITMAP hbm
= CreateBitmap(cxSmallIcon
, cySmallIcon
, 1, 1, NULL
);
271 return NULL
; // failure
274 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
276 InflateRect(&BoxRect
, -1, -1);
278 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
280 FillRect(hDC
, &Rect
, HBRUSH(GetStockObject(WHITE_BRUSH
)));
281 UINT uState
= DFCS_BUTTONRADIOMASK
| DFCS_FLAT
| DFCS_MONO
;
282 DrawFrameControl(hDC
, &BoxRect
, DFC_BUTTON
, uState
);
284 SelectObject(hDC
, hbmOld
);
286 return hbm
; // success
290 CreateTreeImageList(VOID
)
292 HIMAGELIST hImageList
;
293 hImageList
= ImageList_Create(16, 16, ILC_COLOR24
| ILC_MASK
, 9, 1);
294 if (hImageList
== NULL
)
295 return NULL
; // failure
300 free(s_AdvancedIcons
);
301 s_AdvancedIcons
= NULL
;
303 s_AdvancedIconCount
= 0;
306 ADVANCED_ICON
*pAllocated
;
307 size_t Size
= PREDEFINED_ICON_COUNT
* sizeof(ADVANCED_ICON
);
308 pAllocated
= (ADVANCED_ICON
*)calloc(1, Size
);
309 if (pAllocated
== NULL
)
310 return NULL
; // failure
312 s_AdvancedIconCount
= PREDEFINED_ICON_COUNT
;
313 s_AdvancedIcons
= pAllocated
;
315 // add the predefined icons
317 HDC hDC
= CreateCompatibleDC(NULL
);
318 HBITMAP hbmMask
= CreateCheckMask(hDC
);
320 HBITMAP hbmChecked
, hbmUnchecked
;
322 hbmChecked
= CreateCheckImage(hDC
, TRUE
);
323 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
324 DeleteObject(hbmChecked
);
326 hbmUnchecked
= CreateCheckImage(hDC
, FALSE
);
327 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
328 DeleteObject(hbmUnchecked
);
330 hbmChecked
= CreateCheckImage(hDC
, TRUE
, FALSE
);
331 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
332 DeleteObject(hbmChecked
);
334 hbmUnchecked
= CreateCheckImage(hDC
, FALSE
, FALSE
);
335 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
336 DeleteObject(hbmUnchecked
);
338 DeleteObject(hbmMask
);
339 hbmMask
= CreateRadioMask(hDC
);
341 hbmChecked
= CreateRadioImage(hDC
, TRUE
);
342 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
343 DeleteObject(hbmChecked
);
345 hbmUnchecked
= CreateRadioImage(hDC
, FALSE
);
346 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
347 DeleteObject(hbmUnchecked
);
349 hbmChecked
= CreateRadioImage(hDC
, TRUE
, FALSE
);
350 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
351 DeleteObject(hbmChecked
);
353 hbmUnchecked
= CreateRadioImage(hDC
, FALSE
, FALSE
);
354 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
355 DeleteObject(hbmUnchecked
);
357 DeleteObject(hbmMask
);
362 static ADVANCED_ENTRY
*
363 Advanced_GetItem(DWORD dwID
)
365 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
367 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
368 if (pEntry
->dwID
== dwID
)
371 return NULL
; // failure
375 Advanced_GetImage(ADVANCED_ENTRY
*pEntry
)
377 switch (pEntry
->dwType
)
380 return pEntry
->nIconID
;
382 case AETYPE_CHECKBOX
:
385 if (pEntry
->bChecked
)
386 return I_CHECKED_DISABLED
;
388 return I_UNCHECKED_DISABLED
;
392 if (pEntry
->bChecked
)
401 if (pEntry
->bChecked
)
402 return I_RADIO_CHECKED_DISABLED
;
404 return I_RADIO_UNCHECKED_DISABLED
;
408 if (pEntry
->bChecked
)
409 return I_RADIO_CHECKED
;
411 return I_RADIO_UNCHECKED
;
414 return -1; // failure
418 Advanced_InsertEntry(HWND hwndTreeView
, ADVANCED_ENTRY
*pEntry
)
420 ADVANCED_ENTRY
*pParent
= Advanced_GetItem(pEntry
->dwParentID
);
421 HTREEITEM hParent
= TVI_ROOT
;
423 hParent
= pParent
->hItem
;
425 TV_INSERTSTRUCT Insertion
;
426 ZeroMemory(&Insertion
, sizeof(Insertion
));
427 Insertion
.hParent
= hParent
;
428 Insertion
.hInsertAfter
= TVI_LAST
;
429 Insertion
.item
.mask
=
430 TVIF_TEXT
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
| TVIF_PARAM
;
431 Insertion
.item
.pszText
= pEntry
->szText
;
433 INT iImage
= Advanced_GetImage(pEntry
);
434 Insertion
.item
.iImage
= Insertion
.item
.iSelectedImage
= iImage
;
435 Insertion
.item
.lParam
= pEntry
->dwID
;
436 pEntry
->hItem
= TreeView_InsertItem(hwndTreeView
, &Insertion
);
440 Advanced_InsertAll(HWND hwndTreeView
)
442 TreeView_DeleteAllItems(hwndTreeView
);
444 // insert the entries
445 ADVANCED_ENTRY
*pEntry
;
446 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
448 pEntry
= &s_Advanced
[i
];
449 Advanced_InsertEntry(hwndTreeView
, pEntry
);
453 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
455 pEntry
= &s_Advanced
[i
];
456 if (pEntry
->dwType
== AETYPE_GROUP
)
458 TreeView_Expand(hwndTreeView
, pEntry
->hItem
, TVE_EXPAND
);
464 Advanced_LoadTree(HKEY hKey
, LPCWSTR pszKeyName
, DWORD dwParentID
)
467 WCHAR szKeyName
[64], szText
[MAX_PATH
], *pch
;
469 ADVANCED_ENTRY
*pAllocated
;
472 Size
= (s_AdvancedCount
+ 1) * sizeof(ADVANCED_ENTRY
);
473 pAllocated
= (ADVANCED_ENTRY
*)realloc(s_Advanced
, Size
);
474 if (pAllocated
== NULL
)
475 return FALSE
; // failure
477 s_Advanced
= pAllocated
;
479 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[s_AdvancedCount
];
481 // dwID, dwParentID, szKeyName
482 pEntry
->dwID
= s_AdvancedCount
;
483 pEntry
->dwParentID
= dwParentID
;
484 lstrcpynW(pEntry
->szKeyName
, pszKeyName
, _countof(pEntry
->szKeyName
));
487 pEntry
->szText
[0] = 0;
488 pEntry
->dwResourceID
= 0;
490 Size
= sizeof(szText
);
491 RegQueryValueExW(hKey
, L
"Text", NULL
, NULL
, LPBYTE(szText
), &Size
);
492 if (szText
[0] == L
'@')
494 pch
= wcsrchr(szText
, L
',');
498 dwIndex
= abs(_wtoi(pch
+ 1));
499 pEntry
->dwResourceID
= dwIndex
;
501 HINSTANCE hInst
= LoadLibraryW(&szText
[1]);
502 LoadStringW(hInst
, dwIndex
, szText
, _countof(szText
));
507 pEntry
->dwResourceID
= DWORD(-1);
509 lstrcpynW(pEntry
->szText
, szText
, _countof(pEntry
->szText
));
513 RegQueryValueExW(hKey
, L
"Type", NULL
, NULL
, LPBYTE(szText
), &Size
);
514 if (lstrcmpiW(szText
, L
"checkbox") == 0)
515 pEntry
->dwType
= AETYPE_CHECKBOX
;
516 else if (lstrcmpiW(szText
, L
"radio") == 0)
517 pEntry
->dwType
= AETYPE_RADIO
;
518 else if (lstrcmpiW(szText
, L
"group") == 0)
519 pEntry
->dwType
= AETYPE_GROUP
;
521 return FALSE
; // failure
523 pEntry
->nIconID
= -1;
524 if (pEntry
->dwType
== AETYPE_GROUP
)
528 Size
= sizeof(szText
);
530 RegQueryValueExW(hKey
, L
"Bitmap", NULL
, NULL
, LPBYTE(szText
), &Size
);
532 WCHAR szExpanded
[MAX_PATH
];
533 ExpandEnvironmentStringsW(szText
, szExpanded
, _countof(szExpanded
));
534 pch
= wcsrchr(szExpanded
, L
',');
538 nIconIndex
= abs(_wtoi(pch
+ 1));
540 pEntry
->nIconID
= Advanced_AddIcon(szExpanded
, nIconIndex
);
543 // Ordinal (ReactOS extension)
544 Size
= sizeof(Value
);
546 RegQueryValueExW(hKey
, L
"Ordinal", NULL
, NULL
, LPBYTE(&Value
), &Size
);
547 pEntry
->dwOrdinal
= Value
;
549 if (pEntry
->dwType
== AETYPE_GROUP
)
551 pEntry
->hkeyRoot
= NULL
;
552 pEntry
->szRegPath
[0] = 0;
553 pEntry
->szValueName
[0] = 0;
554 pEntry
->dwCheckedValue
= 0;
555 pEntry
->bHasUncheckedValue
= FALSE
;
556 pEntry
->dwUncheckedValue
= 0;
557 pEntry
->dwDefaultValue
= 0;
558 pEntry
->hItem
= NULL
;
559 pEntry
->bGrayed
= FALSE
;
560 pEntry
->bChecked
= FALSE
;
565 Value
= DWORD(HKEY_CURRENT_USER
);
566 Size
= sizeof(Value
);
567 RegQueryValueExW(hKey
, L
"HKeyRoot", NULL
, NULL
, LPBYTE(&Value
), &Size
);
568 pEntry
->hkeyRoot
= HKEY(Value
);
571 pEntry
->szRegPath
[0] = 0;
572 Size
= sizeof(szText
);
573 RegQueryValueExW(hKey
, L
"RegPath", NULL
, NULL
, LPBYTE(szText
), &Size
);
574 lstrcpynW(pEntry
->szRegPath
, szText
, _countof(pEntry
->szRegPath
));
577 pEntry
->szValueName
[0] = 0;
578 Size
= sizeof(szText
);
579 RegQueryValueExW(hKey
, L
"ValueName", NULL
, NULL
, LPBYTE(szText
), &Size
);
580 lstrcpynW(pEntry
->szValueName
, szText
, _countof(pEntry
->szValueName
));
583 Size
= sizeof(Value
);
585 RegQueryValueExW(hKey
, L
"CheckedValue", NULL
, NULL
, LPBYTE(&Value
), &Size
);
586 pEntry
->dwCheckedValue
= Value
;
589 Size
= sizeof(Value
);
591 pEntry
->bHasUncheckedValue
= TRUE
;
592 if (RegQueryValueExW(hKey
, L
"UncheckedValue", NULL
,
593 NULL
, LPBYTE(&Value
), &Size
) != ERROR_SUCCESS
)
595 pEntry
->bHasUncheckedValue
= FALSE
;
597 pEntry
->dwUncheckedValue
= Value
;
600 Size
= sizeof(Value
);
602 RegQueryValueExW(hKey
, L
"DefaultValue", NULL
, NULL
, LPBYTE(&Value
), &Size
);
603 pEntry
->dwDefaultValue
= Value
;
606 pEntry
->hItem
= NULL
;
610 Value
= pEntry
->dwDefaultValue
;
611 pEntry
->bGrayed
= TRUE
;
612 if (RegOpenKeyExW(HKEY(pEntry
->hkeyRoot
), pEntry
->szRegPath
, 0,
613 KEY_READ
, &hkeyTarget
) == ERROR_SUCCESS
)
615 Size
= sizeof(Value
);
616 if (RegQueryValueExW(hkeyTarget
, pEntry
->szValueName
, NULL
, NULL
,
617 LPBYTE(&Value
), &Size
) == ERROR_SUCCESS
)
619 pEntry
->bGrayed
= FALSE
;
621 RegCloseKey(hkeyTarget
);
623 pEntry
->bChecked
= (Value
== pEntry
->dwCheckedValue
);
626 // Grayed (ReactOS extension)
627 Size
= sizeof(Value
);
629 RegQueryValueExW(hKey
, L
"Grayed", NULL
, NULL
, LPBYTE(&Value
), &Size
);
630 if (!pEntry
->bGrayed
)
631 pEntry
->bGrayed
= Value
;
633 BOOL bIsGroup
= (pEntry
->dwType
== AETYPE_GROUP
);
634 dwParentID
= pEntry
->dwID
;
638 return TRUE
; // success
642 while (RegEnumKeyW(hKey
, dwIndex
, szKeyName
,
643 _countof(szKeyName
)) == ERROR_SUCCESS
)
646 if (RegOpenKeyExW(hKey
, szKeyName
, 0, KEY_READ
,
647 &hkeyChild
) != ERROR_SUCCESS
)
653 Advanced_LoadTree(hkeyChild
, szKeyName
, dwParentID
);
654 RegCloseKey(hkeyChild
);
659 return TRUE
; // success
663 Advanced_LoadAll(VOID
)
665 static const WCHAR s_szAdvanced
[] =
666 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced";
668 // free if already existed
677 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, s_szAdvanced
, 0,
678 KEY_READ
, &hKey
) != ERROR_SUCCESS
)
680 return FALSE
; // failure
686 while (RegEnumKeyW(hKey
, dwIndex
, szKeyName
,
687 _countof(szKeyName
)) == ERROR_SUCCESS
)
690 if (RegOpenKeyExW(hKey
, szKeyName
, 0, KEY_READ
,
691 &hkeyChild
) != ERROR_SUCCESS
)
697 Advanced_LoadTree(hkeyChild
, szKeyName
, DWORD(-1));
698 RegCloseKey(hkeyChild
);
705 return TRUE
; // success
709 Advanced_Compare(const void *x
, const void *y
)
711 ADVANCED_ENTRY
*pEntry1
= (ADVANCED_ENTRY
*)x
;
712 ADVANCED_ENTRY
*pEntry2
= (ADVANCED_ENTRY
*)y
;
713 if (pEntry1
->dwOrdinal
< pEntry2
->dwOrdinal
)
715 if (pEntry1
->dwOrdinal
> pEntry2
->dwOrdinal
)
721 Advanced_SortAll(VOID
)
723 qsort(s_Advanced
, s_AdvancedCount
, sizeof(ADVANCED_ENTRY
), Advanced_Compare
);
726 EXTERN_C HPSXA WINAPI
SHCreatePropSheetExtArrayEx(HKEY hKey
, LPCWSTR pszSubKey
, UINT max_iface
, IDataObject
*pDataObj
);
729 UpdateGeneralIcons(HWND hDlg
)
731 HWND hwndTaskIcon
, hwndFolderIcon
, hwndClickIcon
;
732 HICON hTaskIcon
= NULL
, hFolderIcon
= NULL
, hClickIcon
= NULL
;
733 LPTSTR lpTaskIconName
= NULL
, lpFolderIconName
= NULL
, lpClickIconName
= NULL
;
735 // show task setting icon
736 if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_COMMONTASKS
) == BST_CHECKED
)
737 lpTaskIconName
= MAKEINTRESOURCE(IDI_SHELL_SHOW_COMMON_TASKS
);
738 else if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_CLASSICFOLDERS
) == BST_CHECKED
)
739 lpTaskIconName
= MAKEINTRESOURCE(IDI_SHELL_CLASSIC_FOLDERS
);
743 hTaskIcon
= (HICON
)LoadImage(shell32_hInstance
,
751 hwndTaskIcon
= GetDlgItem(hDlg
,
752 IDC_FOLDER_OPTIONS_TASKICON
);
755 SendMessage(hwndTaskIcon
,
763 // show Folder setting icons
764 if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_SAMEWINDOW
) == BST_CHECKED
)
765 lpFolderIconName
= MAKEINTRESOURCE(IDI_SHELL_OPEN_IN_SOME_WINDOW
);
766 else if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_OWNWINDOW
) == BST_CHECKED
)
767 lpFolderIconName
= MAKEINTRESOURCE(IDI_SHELL_OPEN_IN_NEW_WINDOW
);
769 if (lpFolderIconName
)
771 hFolderIcon
= (HICON
)LoadImage(shell32_hInstance
,
779 hwndFolderIcon
= GetDlgItem(hDlg
,
780 IDC_FOLDER_OPTIONS_FOLDERICON
);
783 SendMessage(hwndFolderIcon
,
786 (LPARAM
)hFolderIcon
);
791 // Show click setting icon
792 if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_SINGLECLICK
) == BST_CHECKED
)
793 lpClickIconName
= MAKEINTRESOURCE(IDI_SHELL_SINGLE_CLICK_TO_OPEN
);
794 else if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_DOUBLECLICK
) == BST_CHECKED
)
795 lpClickIconName
= MAKEINTRESOURCE(IDI_SHELL_DOUBLE_CLICK_TO_OPEN
);
799 hClickIcon
= (HICON
)LoadImage(shell32_hInstance
,
807 hwndClickIcon
= GetDlgItem(hDlg
,
808 IDC_FOLDER_OPTIONS_CLICKICON
);
811 SendMessage(hwndClickIcon
,
821 DeleteObject(hTaskIcon
);
823 DeleteObject(hFolderIcon
);
825 DeleteObject(hClickIcon
);
832 FolderOptionsGeneralDlg(
846 switch (LOWORD(wParam
))
848 case IDC_FOLDER_OPTIONS_COMMONTASKS
:
849 case IDC_FOLDER_OPTIONS_CLASSICFOLDERS
:
850 case IDC_FOLDER_OPTIONS_SAMEWINDOW
:
851 case IDC_FOLDER_OPTIONS_OWNWINDOW
:
852 case IDC_FOLDER_OPTIONS_SINGLECLICK
:
853 case IDC_FOLDER_OPTIONS_DOUBLECLICK
:
854 if (HIWORD(wParam
) == BN_CLICKED
)
856 UpdateGeneralIcons(hwndDlg
);
858 /* Enable the 'Apply' button */
859 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
867 LPNMHDR pnmh
= (LPNMHDR
)lParam
;
890 ViewDlg_OnInitDialog(HWND hwndDlg
)
892 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
894 s_hImageList
= CreateTreeImageList();
895 TreeView_SetImageList(hwndTreeView
, s_hImageList
, TVSIL_NORMAL
);
899 Advanced_InsertAll(hwndTreeView
);
901 return TRUE
; // set focus
905 ViewDlg_ToggleCheckItem(HWND hwndDlg
, HTREEITEM hItem
)
907 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
912 ZeroMemory(&Item
, sizeof(Item
));
913 Item
.mask
= TVIF_HANDLE
| TVIF_IMAGE
| TVIF_PARAM
;
915 if (!TreeView_GetItem(hwndTreeView
, &Item
))
916 return FALSE
; // no such item
918 ADVANCED_ENTRY
*pEntry
= Advanced_GetItem(Item
.lParam
);
920 return FALSE
; // no such item
922 return FALSE
; // disabled
925 Item
.mask
= TVIF_HANDLE
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
926 switch (pEntry
->dwType
)
928 case AETYPE_CHECKBOX
:
929 pEntry
->bChecked
= !pEntry
->bChecked
;
932 // reset all the entries of the same parent
933 for (i
= 0; i
< s_AdvancedCount
; ++i
)
935 ADVANCED_ENTRY
*pEntry2
= &s_Advanced
[i
];
936 if (pEntry
->dwParentID
== pEntry2
->dwParentID
)
938 pEntry2
->bChecked
= FALSE
;
940 Item
.hItem
= pEntry2
->hItem
;
941 INT iImage
= Advanced_GetImage(pEntry2
);
942 Item
.iImage
= Item
.iSelectedImage
= iImage
;
943 TreeView_SetItem(hwndTreeView
, &Item
);
946 pEntry
->bChecked
= TRUE
;
949 return FALSE
; // failure
951 Item
.iImage
= Item
.iSelectedImage
= Advanced_GetImage(pEntry
);
953 TreeView_SetItem(hwndTreeView
, &Item
);
957 TreeView_GetItemRect(hwndTreeView
, hItem
, &rcItem
, FALSE
);
958 InvalidateRect(hwndTreeView
, &rcItem
, TRUE
);
959 return TRUE
; // success
963 ViewDlg_OnTreeViewClick(HWND hwndDlg
)
965 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
967 // do hit test to get the clicked item
968 TV_HITTESTINFO HitTest
;
969 ZeroMemory(&HitTest
, sizeof(HitTest
));
970 DWORD dwPos
= GetMessagePos();
971 HitTest
.pt
.x
= LOWORD(dwPos
);
972 HitTest
.pt
.y
= HIWORD(dwPos
);
973 ScreenToClient(hwndTreeView
, &HitTest
.pt
);
974 HTREEITEM hItem
= TreeView_HitTest(hwndTreeView
, &HitTest
);
976 // toggle the check mark if possible
977 if (ViewDlg_ToggleCheckItem(hwndDlg
, hItem
))
979 // property sheet was changed
980 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
985 ViewDlg_OnTreeViewKeyDown(HWND hwndDlg
, TV_KEYDOWN
*KeyDown
)
987 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
989 if (KeyDown
->wVKey
== VK_SPACE
)
991 // [Space] key was pressed
992 HTREEITEM hItem
= TreeView_GetSelection(hwndTreeView
);
993 if (ViewDlg_ToggleCheckItem(hwndDlg
, hItem
))
995 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1001 ViewDlg_OnTreeCustomDraw(HWND hwndDlg
, NMTVCUSTOMDRAW
*Draw
)
1003 NMCUSTOMDRAW
& nmcd
= Draw
->nmcd
;
1004 switch (nmcd
.dwDrawStage
)
1007 return CDRF_NOTIFYITEMDRAW
; // for CDDS_ITEMPREPAINT
1009 case CDDS_ITEMPREPAINT
:
1010 if (!(nmcd
.uItemState
& CDIS_SELECTED
)) // not selected
1012 LPARAM lParam
= nmcd
.lItemlParam
;
1013 ADVANCED_ENTRY
*pEntry
= Advanced_GetItem(lParam
);
1014 if (pEntry
&& pEntry
->bGrayed
) // disabled
1017 Draw
->clrText
= GetSysColor(COLOR_GRAYTEXT
);
1018 Draw
->clrTextBk
= GetSysColor(COLOR_WINDOW
);
1019 return CDRF_NEWFONT
;
1027 return CDRF_DODEFAULT
;
1031 Advanced_RestoreDefaults(HWND hwndDlg
)
1033 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
1035 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
1037 // ignore if the type is group
1038 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
1039 if (pEntry
->dwType
== AETYPE_GROUP
)
1042 // set default value on registry
1044 if (RegOpenKeyExW(HKEY(pEntry
->hkeyRoot
), pEntry
->szRegPath
,
1045 0, KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
1049 RegSetValueExW(hKey
, pEntry
->szValueName
, 0, REG_DWORD
,
1050 LPBYTE(pEntry
->dwDefaultValue
), sizeof(DWORD
));
1053 // update check status
1054 pEntry
->bChecked
= (pEntry
->dwCheckedValue
== pEntry
->dwDefaultValue
);
1058 ZeroMemory(&Item
, sizeof(Item
));
1059 Item
.mask
= TVIF_HANDLE
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
1060 Item
.hItem
= pEntry
->hItem
;
1061 Item
.iImage
= Item
.iSelectedImage
= Advanced_GetImage(pEntry
);
1062 TreeView_SetItem(hwndTreeView
, &Item
);
1065 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1068 /* FIXME: These macros should not be defined here */
1069 #ifndef SSF_SHOWSUPERHIDDEN
1070 #define SSF_SHOWSUPERHIDDEN 0x00040000
1072 #ifndef SSF_SEPPROCESS
1073 #define SSF_SEPPROCESS 0x00080000
1077 ScanAdvancedSettings(SHELLSTATE
*pSS
, DWORD
*pdwMask
)
1079 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
1081 const ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
1082 if (pEntry
->dwType
== AETYPE_GROUP
|| pEntry
->bGrayed
)
1085 BOOL bChecked
= pEntry
->bChecked
;
1087 // FIXME: Add more items
1088 if (lstrcmpiW(pEntry
->szKeyName
, L
"SuperHidden") == 0)
1090 pSS
->fShowSuperHidden
= !bChecked
? 1 : 0;
1091 *pdwMask
|= SSF_SHOWSUPERHIDDEN
;
1094 if (lstrcmpiW(pEntry
->szKeyName
, L
"DesktopProcess") == 0)
1096 pSS
->fSepProcess
= bChecked
? 1 : 0;
1097 *pdwMask
|= SSF_SEPPROCESS
;
1100 if (lstrcmpiW(pEntry
->szKeyName
, L
"SHOWALL") == 0)
1102 pSS
->fShowAllObjects
= !bChecked
? 1 : 0;
1103 *pdwMask
|= SSF_SHOWALLOBJECTS
;
1106 if (lstrcmpiW(pEntry
->szKeyName
, L
"HideFileExt") == 0)
1108 pSS
->fShowExtensions
= !bChecked
? 1 : 0;
1109 *pdwMask
|= SSF_SHOWEXTENSIONS
;
1112 if (lstrcmpiW(pEntry
->szKeyName
, L
"ShowCompColor") == 0)
1114 pSS
->fShowCompColor
= bChecked
? 1 : 0;
1115 *pdwMask
|= SSF_SHOWCOMPCOLOR
;
1118 if (lstrcmpiW(pEntry
->szKeyName
, L
"ShowInfoTip") == 0)
1120 pSS
->fShowInfoTip
= bChecked
? 1 : 0;
1121 *pdwMask
|= SSF_SHOWINFOTIP
;
1128 VOID WINAPI
SHGetSetSettings(LPSHELLSTATE lpss
, DWORD dwMask
, BOOL bSet
);
1130 static BOOL CALLBACK
RefreshBrowsersCallback (HWND hWnd
, LPARAM msg
)
1132 WCHAR ClassName
[100];
1133 if (GetClassName(hWnd
, ClassName
, 100))
1135 if (!wcscmp(ClassName
, L
"Progman") ||
1136 !wcscmp(ClassName
, L
"CabinetWClass") ||
1137 !wcscmp(ClassName
, L
"ExploreWClass"))
1139 PostMessage(hWnd
, WM_COMMAND
, FCIDM_DESKBROWSER_REFRESH
, 0);
1146 ViewDlg_Apply(HWND hwndDlg
)
1148 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
1150 // ignore the entry if the type is group or the entry is grayed
1151 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
1152 if (pEntry
->dwType
== AETYPE_GROUP
|| pEntry
->bGrayed
)
1155 // open the registry key
1157 if (RegOpenKeyExW(HKEY(pEntry
->hkeyRoot
), pEntry
->szRegPath
, 0,
1158 KEY_WRITE
, &hkeyTarget
) != ERROR_SUCCESS
)
1163 // checked or unchecked?
1164 DWORD dwValue
, dwSize
;
1165 if (pEntry
->bChecked
)
1167 dwValue
= pEntry
->dwCheckedValue
;
1171 if (pEntry
->bHasUncheckedValue
)
1173 dwValue
= pEntry
->dwUncheckedValue
;
1177 // there is no unchecked value
1178 RegCloseKey(hkeyTarget
);
1184 dwSize
= sizeof(dwValue
);
1185 RegSetValueExW(hkeyTarget
, pEntry
->szValueName
, 0, REG_DWORD
,
1186 LPBYTE(&dwValue
), dwSize
);
1189 RegCloseKey(hkeyTarget
);
1192 // scan advanced settings for user's settings
1194 SHELLSTATE ShellState
;
1195 ZeroMemory(&ShellState
, sizeof(ShellState
));
1196 ScanAdvancedSettings(&ShellState
, &dwMask
);
1198 // update user's settings
1199 SHGetSetSettings(&ShellState
, dwMask
, TRUE
);
1202 SendMessage(HWND_BROADCAST
, WM_WININICHANGE
, 0, 0);
1204 EnumWindows(RefreshBrowsersCallback
, NULL
);
1208 FolderOptionsViewDlg(
1215 NMTVCUSTOMDRAW
*Draw
;
1220 return ViewDlg_OnInitDialog(hwndDlg
);
1222 switch (LOWORD(wParam
))
1224 case 14004: // Restore Defaults
1225 Advanced_RestoreDefaults(hwndDlg
);
1230 switch (LPNMHDR(lParam
)->code
)
1232 case NM_CLICK
: // clicked on treeview
1233 ViewDlg_OnTreeViewClick(hwndDlg
);
1235 case NM_CUSTOMDRAW
: // custom draw (for graying)
1236 Draw
= (NMTVCUSTOMDRAW
*)lParam
;
1237 Result
= ViewDlg_OnTreeCustomDraw(hwndDlg
, Draw
);
1238 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, Result
);
1240 case TVN_KEYDOWN
: // key is down
1241 ViewDlg_OnTreeViewKeyDown(hwndDlg
, (TV_KEYDOWN
*)lParam
);
1243 case PSN_APPLY
: // [Apply] is clicked
1244 ViewDlg_Apply(hwndDlg
);
1257 InitializeFileTypesListCtrlColumns(HWND hDlgCtrl
)
1263 int columnSize
= 140;
1266 if (!LoadStringW(shell32_hInstance
, IDS_COLUMN_EXTENSION
, szName
, sizeof(szName
) / sizeof(WCHAR
)))
1268 /* default to english */
1269 wcscpy(szName
, L
"Extensions");
1272 /* make sure its null terminated */
1273 szName
[(sizeof(szName
)/sizeof(WCHAR
))-1] = 0;
1275 GetClientRect(hDlgCtrl
, &clientRect
);
1276 ZeroMemory(&col
, sizeof(LV_COLUMN
));
1277 columnSize
= 140; //FIXME
1279 col
.mask
= LVCF_WIDTH
| LVCF_TEXT
| LVCF_SUBITEM
| LVCF_FMT
;
1280 col
.fmt
= LVCFMT_FIXED_WIDTH
;
1281 col
.cx
= columnSize
| LVCFMT_LEFT
;
1282 col
.cchTextMax
= wcslen(szName
);
1283 col
.pszText
= szName
;
1284 (void)SendMessageW(hDlgCtrl
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&col
);
1286 if (!LoadStringW(shell32_hInstance
, IDS_FILE_TYPES
, szName
, sizeof(szName
) / sizeof(WCHAR
)))
1288 /* default to english */
1289 wcscpy(szName
, L
"File Types");
1290 ERR("Failed to load localized string!\n");
1294 col
.cx
= clientRect
.right
- clientRect
.left
- columnSize
;
1295 col
.cchTextMax
= wcslen(szName
);
1296 col
.pszText
= szName
;
1297 (void)SendMessageW(hDlgCtrl
, LVM_INSERTCOLUMNW
, 1, (LPARAM
)&col
);
1299 /* set full select style */
1300 dwStyle
= (DWORD
) SendMessage(hDlgCtrl
, LVM_GETEXTENDEDLISTVIEWSTYLE
, 0, 0);
1301 dwStyle
= dwStyle
| LVS_EX_FULLROWSELECT
;
1302 SendMessage(hDlgCtrl
, LVM_SETEXTENDEDLISTVIEWSTYLE
, 0, dwStyle
);
1306 FindItem(HWND hDlgCtrl
, WCHAR
* ItemName
)
1308 LVFINDINFOW findInfo
;
1309 ZeroMemory(&findInfo
, sizeof(LVFINDINFOW
));
1311 findInfo
.flags
= LVFI_STRING
;
1312 findInfo
.psz
= ItemName
;
1313 return ListView_FindItem(hDlgCtrl
, 0, &findInfo
);
1318 InsertFileType(HWND hDlgCtrl
, WCHAR
* szName
, PINT iItem
, WCHAR
* szFile
)
1320 PFOLDER_FILE_TYPE_ENTRY Entry
;
1326 if (szName
[0] != L
'.')
1328 /* FIXME handle URL protocol handlers */
1332 /* allocate file type entry */
1333 Entry
= (PFOLDER_FILE_TYPE_ENTRY
)HeapAlloc(GetProcessHeap(), 0, sizeof(FOLDER_FILE_TYPE_ENTRY
));
1339 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, szName
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
1341 HeapFree(GetProcessHeap(), 0, Entry
);
1345 /* FIXME check for duplicates */
1347 /* query for the default key */
1348 dwSize
= sizeof(Entry
->ClassKey
);
1349 if (RegQueryValueExW(hKey
, NULL
, NULL
, NULL
, (LPBYTE
)Entry
->ClassKey
, &dwSize
) != ERROR_SUCCESS
)
1351 /* no link available */
1352 Entry
->ClassKey
[0] = 0;
1355 if (Entry
->ClassKey
[0])
1358 /* try open linked key */
1359 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, Entry
->ClassKey
, 0, KEY_READ
, &hTemp
) == ERROR_SUCCESS
)
1361 /* use linked key */
1367 /* read friendly type name */
1368 if (RegLoadMUIStringW(hKey
, L
"FriendlyTypeName", Entry
->FileDescription
, sizeof(Entry
->FileDescription
), NULL
, 0, NULL
) != ERROR_SUCCESS
)
1370 /* read file description */
1371 dwSize
= sizeof(Entry
->FileDescription
);
1372 Entry
->FileDescription
[0] = 0;
1374 /* read default key */
1375 RegQueryValueExW(hKey
, NULL
, NULL
, NULL
, (LPBYTE
)Entry
->FileDescription
, &dwSize
);
1378 /* Read the EditFlags value */
1379 Entry
->EditFlags
= 0;
1380 if (!RegQueryValueExW(hKey
, L
"EditFlags", NULL
, &dwType
, NULL
, &dwSize
))
1382 if ((dwType
== REG_DWORD
|| dwType
== REG_BINARY
) && dwSize
== sizeof(DWORD
))
1383 RegQueryValueExW(hKey
, L
"EditFlags", NULL
, NULL
, (LPBYTE
)&Entry
->EditFlags
, &dwSize
);
1389 /* Do not add excluded entries */
1390 if (Entry
->EditFlags
& 0x00000001) //FTA_Exclude
1392 HeapFree(GetProcessHeap(), 0, Entry
);
1396 /* convert extension to upper case */
1397 wcscpy(Entry
->FileExtension
, szName
);
1398 _wcsupr(Entry
->FileExtension
);
1400 if (!Entry
->FileDescription
[0])
1402 /* construct default 'FileExtensionFile' by formatting the uppercase extension
1403 with IDS_FILE_EXT_TYPE, outputting something like a l18n 'INI File' */
1405 StringCchPrintf(Entry
->FileDescription
, _countof(Entry
->FileDescription
), szFile
, &Entry
->FileExtension
[1]);
1408 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
1409 lvItem
.mask
= LVIF_TEXT
| LVIF_PARAM
;
1410 lvItem
.iSubItem
= 0;
1411 lvItem
.pszText
= &Entry
->FileExtension
[1];
1412 lvItem
.iItem
= *iItem
;
1413 lvItem
.lParam
= (LPARAM
)Entry
;
1414 (void)SendMessageW(hDlgCtrl
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
);
1416 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
1417 lvItem
.mask
= LVIF_TEXT
;
1418 lvItem
.pszText
= Entry
->FileDescription
;
1419 lvItem
.iItem
= *iItem
;
1420 lvItem
.iSubItem
= 1;
1421 ListView_SetItem(hDlgCtrl
, &lvItem
);
1429 ListViewCompareProc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
1431 PFOLDER_FILE_TYPE_ENTRY Entry1
, Entry2
;
1434 Entry1
= (PFOLDER_FILE_TYPE_ENTRY
)lParam1
;
1435 Entry2
= (PFOLDER_FILE_TYPE_ENTRY
)lParam2
;
1437 x
= wcsicmp(Entry1
->FileExtension
, Entry2
->FileExtension
);
1441 return wcsicmp(Entry1
->FileDescription
, Entry2
->FileDescription
);
1445 PFOLDER_FILE_TYPE_ENTRY
1446 InitializeFileTypesListCtrl(HWND hwndDlg
)
1456 hDlgCtrl
= GetDlgItem(hwndDlg
, 14000);
1457 InitializeFileTypesListCtrlColumns(hDlgCtrl
);
1460 if (!LoadStringW(shell32_hInstance
, IDS_FILE_EXT_TYPE
, szFile
, _countof(szFile
)))
1462 /* default to english */
1463 wcscpy(szFile
, L
"%s File");
1465 szFile
[(_countof(szFile
)) - 1] = 0;
1467 dwName
= _countof(szName
);
1469 while (RegEnumKeyExW(HKEY_CLASSES_ROOT
, dwIndex
++, szName
, &dwName
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
1471 InsertFileType(hDlgCtrl
, szName
, &iItem
, szFile
);
1472 dwName
= _countof(szName
);
1475 /* Leave if the list is empty */
1480 ListView_SortItems(hDlgCtrl
, ListViewCompareProc
, NULL
);
1482 /* select first item */
1483 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
1484 lvItem
.mask
= LVIF_STATE
;
1485 lvItem
.stateMask
= (UINT
)-1;
1486 lvItem
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
1488 ListView_SetItem(hDlgCtrl
, &lvItem
);
1490 lvItem
.mask
= LVIF_PARAM
;
1491 ListView_GetItem(hDlgCtrl
, &lvItem
);
1493 return (PFOLDER_FILE_TYPE_ENTRY
)lvItem
.lParam
;
1497 PFOLDER_FILE_TYPE_ENTRY
1504 Count
= ListView_GetItemCount(hDlgCtrl
);
1506 for (Index
= 0; Index
< Count
; Index
++)
1508 ZeroMemory(&lvItem
, sizeof(LVITEM
));
1509 lvItem
.mask
= LVIF_PARAM
| LVIF_STATE
;
1510 lvItem
.iItem
= Index
;
1511 lvItem
.stateMask
= (UINT
) - 1;
1513 if (ListView_GetItem(hDlgCtrl
, &lvItem
))
1515 if (lvItem
.state
& LVIS_SELECTED
)
1516 return (PFOLDER_FILE_TYPE_ENTRY
)lvItem
.lParam
;
1525 FolderOptionsFileTypesDlg(
1533 WCHAR Buffer
[255], FormatBuffer
[255];
1534 PFOLDER_FILE_TYPE_ENTRY pItem
;
1540 pItem
= InitializeFileTypesListCtrl(hwndDlg
);
1542 /* Disable the Delete button if the listview is empty or
1543 the selected item should not be deleted by the user */
1544 if (pItem
== NULL
|| (pItem
->EditFlags
& 0x00000010)) // FTA_NoRemove
1545 EnableWindow(GetDlgItem(hwndDlg
, 14002), FALSE
);
1549 switch(LOWORD(wParam
))
1552 pItem
= FindSelectedItem(GetDlgItem(hwndDlg
, 14000));
1555 Info
.oaifInFlags
= OAIF_ALLOW_REGISTRATION
| OAIF_REGISTER_EXT
;
1556 Info
.pcszClass
= pItem
->FileExtension
;
1557 SHOpenWithDialog(hwndDlg
, &Info
);
1564 lppl
= (LPNMLISTVIEW
) lParam
;
1566 if (lppl
->hdr
.code
== LVN_ITEMCHANGING
)
1568 ZeroMemory(&lvItem
, sizeof(LVITEM
));
1569 lvItem
.mask
= LVIF_PARAM
;
1570 lvItem
.iItem
= lppl
->iItem
;
1571 if (!SendMessageW(lppl
->hdr
.hwndFrom
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
))
1574 pItem
= (PFOLDER_FILE_TYPE_ENTRY
)lvItem
.lParam
;
1578 if (!(lppl
->uOldState
& LVIS_FOCUSED
) && (lppl
->uNewState
& LVIS_FOCUSED
))
1580 /* new focused item */
1581 if (!LoadStringW(shell32_hInstance
, IDS_FILE_DETAILS
, FormatBuffer
, sizeof(FormatBuffer
) / sizeof(WCHAR
)))
1583 /* use default english format string */
1584 wcscpy(FormatBuffer
, L
"Details for '%s' extension");
1588 swprintf(Buffer
, FormatBuffer
, &pItem
->FileExtension
[1]);
1590 SetDlgItemTextW(hwndDlg
, 14003, Buffer
);
1592 if (!LoadStringW(shell32_hInstance
, IDS_FILE_DETAILSADV
, FormatBuffer
, sizeof(FormatBuffer
) / sizeof(WCHAR
)))
1594 /* use default english format string */
1595 wcscpy(FormatBuffer
, L
"Files with extension '%s' are of type '%s'. To change settings that affect all '%s' files, click Advanced.");
1598 swprintf(Buffer
, FormatBuffer
, &pItem
->FileExtension
[1], &pItem
->FileDescription
[0], &pItem
->FileDescription
[0]);
1600 SetDlgItemTextW(hwndDlg
, 14007, Buffer
);
1602 /* Enable the Delete button */
1603 if (pItem
->EditFlags
& 0x00000010) // FTA_NoRemove
1604 EnableWindow(GetDlgItem(hwndDlg
, 14002), FALSE
);
1606 EnableWindow(GetDlgItem(hwndDlg
, 14002), TRUE
);
1609 else if (lppl
->hdr
.code
== PSN_SETACTIVE
)
1611 /* On page activation, set the focus to the listview */
1612 SetFocus(GetDlgItem(hwndDlg
, 14000));
1622 ShowFolderOptionsDialog(HWND hWnd
, HINSTANCE hInst
)
1624 PROPSHEETHEADERW pinfo
;
1625 HPROPSHEETPAGE hppages
[3];
1626 HPROPSHEETPAGE hpage
;
1628 WCHAR szOptions
[100];
1630 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_GENERAL
, FolderOptionsGeneralDlg
, 0, NULL
);
1632 hppages
[num_pages
++] = hpage
;
1634 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_VIEW
, FolderOptionsViewDlg
, 0, NULL
);
1636 hppages
[num_pages
++] = hpage
;
1638 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_FILETYPES
, FolderOptionsFileTypesDlg
, 0, NULL
);
1640 hppages
[num_pages
++] = hpage
;
1642 szOptions
[0] = L
'\0';
1643 LoadStringW(shell32_hInstance
, IDS_FOLDER_OPTIONS
, szOptions
, sizeof(szOptions
) / sizeof(WCHAR
));
1644 szOptions
[(sizeof(szOptions
)/sizeof(WCHAR
))-1] = L
'\0';
1646 memset(&pinfo
, 0x0, sizeof(PROPSHEETHEADERW
));
1647 pinfo
.dwSize
= sizeof(PROPSHEETHEADERW
);
1648 pinfo
.dwFlags
= PSH_NOCONTEXTHELP
;
1649 pinfo
.nPages
= num_pages
;
1650 pinfo
.phpage
= hppages
;
1651 pinfo
.pszCaption
= szOptions
;
1653 PropertySheetW(&pinfo
);
1658 Options_RunDLLCommon(HWND hWnd
, HINSTANCE hInst
, int fOptions
, DWORD nCmdShow
)
1663 ShowFolderOptionsDialog(hWnd
, hInst
);
1666 // show taskbar options dialog
1667 FIXME("notify explorer to show taskbar options dialog");
1668 //PostMessage(GetShellWindow(), WM_USER+22, fOptions, 0);
1671 FIXME("unrecognized options id %d\n", fOptions
);
1675 /*************************************************************************
1676 * Options_RunDLL (SHELL32.@)
1678 EXTERN_C VOID WINAPI
Options_RunDLL(HWND hWnd
, HINSTANCE hInst
, LPCSTR cmd
, DWORD nCmdShow
)
1680 Options_RunDLLCommon(hWnd
, hInst
, StrToIntA(cmd
), nCmdShow
);
1683 /*************************************************************************
1684 * Options_RunDLLA (SHELL32.@)
1686 EXTERN_C VOID WINAPI
Options_RunDLLA(HWND hWnd
, HINSTANCE hInst
, LPCSTR cmd
, DWORD nCmdShow
)
1688 Options_RunDLLCommon(hWnd
, hInst
, StrToIntA(cmd
), nCmdShow
);
1691 /*************************************************************************
1692 * Options_RunDLLW (SHELL32.@)
1694 EXTERN_C VOID WINAPI
Options_RunDLLW(HWND hWnd
, HINSTANCE hInst
, LPCWSTR cmd
, DWORD nCmdShow
)
1696 Options_RunDLLCommon(hWnd
, hInst
, StrToIntW(cmd
), nCmdShow
);