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 WCHAR szText
[MAX_PATH
]; // text
141 INT nIconID
; // icon ID (See ADVANCED_ICON)
143 HKEY hkeyRoot
; // registry root key
144 WCHAR szRegPath
[MAX_PATH
]; // registry path
145 WCHAR szValueName
[64]; // registry value name
147 DWORD dwCheckedValue
; // checked value
148 DWORD dwUncheckedValue
; // unchecked value
149 DWORD dwDefaultValue
; // defalut value
150 BOOL bHasUncheckedValue
; // If FALSE, UncheckedValue is invalid
152 HTREEITEM hItem
; // for TreeView
153 BOOL bGrayed
; // disabled?
154 BOOL bChecked
; // checked?
155 } ADVANCED_ENTRY
, *PADVANCED_ENTRY
;
157 // definition of advanced entries
158 static ADVANCED_ENTRY
* s_Advanced
= NULL
;
159 static INT s_AdvancedCount
= 0;
162 Create24BppBitmap(HDC hDC
, INT cx
, INT cy
)
167 ZeroMemory(&bi
, sizeof(bi
));
168 bi
.bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
169 bi
.bmiHeader
.biWidth
= cx
;
170 bi
.bmiHeader
.biHeight
= cy
;
171 bi
.bmiHeader
.biPlanes
= 1;
172 bi
.bmiHeader
.biBitCount
= 24;
173 bi
.bmiHeader
.biCompression
= BI_RGB
;
175 HBITMAP hbm
= CreateDIBSection(hDC
, &bi
, DIB_RGB_COLORS
, &pvBits
, NULL
, 0);
180 CreateCheckImage(HDC hDC
, BOOL bCheck
, BOOL bEnabled
= TRUE
)
182 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
183 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
185 HBITMAP hbm
= Create24BppBitmap(hDC
, cxSmallIcon
, cySmallIcon
);
187 return NULL
; // failure
190 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
192 InflateRect(&BoxRect
, -1, -1);
194 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
196 UINT uState
= DFCS_BUTTONCHECK
| DFCS_FLAT
| DFCS_MONO
;
198 uState
|= DFCS_CHECKED
;
200 uState
|= DFCS_INACTIVE
;
201 DrawFrameControl(hDC
, &BoxRect
, DFC_BUTTON
, uState
);
203 SelectObject(hDC
, hbmOld
);
205 return hbm
; // success
209 CreateCheckMask(HDC hDC
)
211 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
212 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
214 HBITMAP hbm
= CreateBitmap(cxSmallIcon
, cySmallIcon
, 1, 1, NULL
);
216 return NULL
; // failure
219 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
221 InflateRect(&BoxRect
, -1, -1);
223 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
225 FillRect(hDC
, &Rect
, HBRUSH(GetStockObject(WHITE_BRUSH
)));
226 FillRect(hDC
, &BoxRect
, HBRUSH(GetStockObject(BLACK_BRUSH
)));
228 SelectObject(hDC
, hbmOld
);
230 return hbm
; // success
234 CreateRadioImage(HDC hDC
, BOOL bCheck
, BOOL bEnabled
= TRUE
)
236 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
237 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
239 HBITMAP hbm
= Create24BppBitmap(hDC
, cxSmallIcon
, cySmallIcon
);
241 return NULL
; // failure
244 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
246 InflateRect(&BoxRect
, -1, -1);
248 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
250 UINT uState
= DFCS_BUTTONRADIOIMAGE
| DFCS_FLAT
| DFCS_MONO
;
252 uState
|= DFCS_CHECKED
;
254 uState
|= DFCS_INACTIVE
;
255 DrawFrameControl(hDC
, &BoxRect
, DFC_BUTTON
, uState
);
257 SelectObject(hDC
, hbmOld
);
259 return hbm
; // success
263 CreateRadioMask(HDC hDC
)
265 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
266 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
268 HBITMAP hbm
= CreateBitmap(cxSmallIcon
, cySmallIcon
, 1, 1, NULL
);
270 return NULL
; // failure
273 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
275 InflateRect(&BoxRect
, -1, -1);
277 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
279 FillRect(hDC
, &Rect
, HBRUSH(GetStockObject(WHITE_BRUSH
)));
280 UINT uState
= DFCS_BUTTONRADIOMASK
| DFCS_FLAT
| DFCS_MONO
;
281 DrawFrameControl(hDC
, &BoxRect
, DFC_BUTTON
, uState
);
283 SelectObject(hDC
, hbmOld
);
285 return hbm
; // success
289 CreateTreeImageList(VOID
)
291 HIMAGELIST hImageList
;
292 hImageList
= ImageList_Create(16, 16, ILC_COLOR24
| ILC_MASK
, 9, 1);
293 if (hImageList
== NULL
)
294 return NULL
; // failure
299 free(s_AdvancedIcons
);
300 s_AdvancedIcons
= NULL
;
302 s_AdvancedIconCount
= 0;
305 ADVANCED_ICON
*pAllocated
;
306 size_t Size
= PREDEFINED_ICON_COUNT
* sizeof(ADVANCED_ICON
);
307 pAllocated
= (ADVANCED_ICON
*)calloc(1, Size
);
308 if (pAllocated
== NULL
)
309 return NULL
; // failure
311 s_AdvancedIconCount
= PREDEFINED_ICON_COUNT
;
312 s_AdvancedIcons
= pAllocated
;
314 // add the predefined icons
316 HDC hDC
= CreateCompatibleDC(NULL
);
317 HBITMAP hbmMask
= CreateCheckMask(hDC
);
319 HBITMAP hbmChecked
, hbmUnchecked
;
321 hbmChecked
= CreateCheckImage(hDC
, TRUE
);
322 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
323 DeleteObject(hbmChecked
);
325 hbmUnchecked
= CreateCheckImage(hDC
, FALSE
);
326 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
327 DeleteObject(hbmUnchecked
);
329 hbmChecked
= CreateCheckImage(hDC
, TRUE
, FALSE
);
330 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
331 DeleteObject(hbmChecked
);
333 hbmUnchecked
= CreateCheckImage(hDC
, FALSE
, FALSE
);
334 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
335 DeleteObject(hbmUnchecked
);
337 DeleteObject(hbmMask
);
338 hbmMask
= CreateRadioMask(hDC
);
340 hbmChecked
= CreateRadioImage(hDC
, TRUE
);
341 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
342 DeleteObject(hbmChecked
);
344 hbmUnchecked
= CreateRadioImage(hDC
, FALSE
);
345 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
346 DeleteObject(hbmUnchecked
);
348 hbmChecked
= CreateRadioImage(hDC
, TRUE
, FALSE
);
349 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
350 DeleteObject(hbmChecked
);
352 hbmUnchecked
= CreateRadioImage(hDC
, FALSE
, FALSE
);
353 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
354 DeleteObject(hbmUnchecked
);
356 DeleteObject(hbmMask
);
361 static ADVANCED_ENTRY
*
362 Advanced_GetItem(DWORD dwID
)
364 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
366 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
367 if (pEntry
->dwID
== dwID
)
370 return NULL
; // failure
374 Advanced_GetImage(ADVANCED_ENTRY
*pEntry
)
376 switch (pEntry
->dwType
)
379 return pEntry
->nIconID
;
381 case AETYPE_CHECKBOX
:
384 if (pEntry
->bChecked
)
385 return I_CHECKED_DISABLED
;
387 return I_UNCHECKED_DISABLED
;
391 if (pEntry
->bChecked
)
400 if (pEntry
->bChecked
)
401 return I_RADIO_CHECKED_DISABLED
;
403 return I_RADIO_UNCHECKED_DISABLED
;
407 if (pEntry
->bChecked
)
408 return I_RADIO_CHECKED
;
410 return I_RADIO_UNCHECKED
;
413 return -1; // failure
417 Advanced_InsertEntry(HWND hwndTreeView
, ADVANCED_ENTRY
*pEntry
)
419 ADVANCED_ENTRY
*pParent
= Advanced_GetItem(pEntry
->dwParentID
);
420 HTREEITEM hParent
= TVI_ROOT
;
422 hParent
= pParent
->hItem
;
424 TV_INSERTSTRUCT Insertion
;
425 ZeroMemory(&Insertion
, sizeof(Insertion
));
426 Insertion
.hParent
= hParent
;
427 Insertion
.hInsertAfter
= TVI_LAST
;
428 Insertion
.item
.mask
=
429 TVIF_TEXT
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
| TVIF_PARAM
;
430 Insertion
.item
.pszText
= pEntry
->szText
;
432 INT iImage
= Advanced_GetImage(pEntry
);
433 Insertion
.item
.iImage
= Insertion
.item
.iSelectedImage
= iImage
;
434 Insertion
.item
.lParam
= pEntry
->dwID
;
435 pEntry
->hItem
= TreeView_InsertItem(hwndTreeView
, &Insertion
);
439 Advanced_InsertAll(HWND hwndTreeView
)
441 TreeView_DeleteAllItems(hwndTreeView
);
443 // insert the entries
444 ADVANCED_ENTRY
*pEntry
;
445 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
447 pEntry
= &s_Advanced
[i
];
448 Advanced_InsertEntry(hwndTreeView
, pEntry
);
452 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
454 pEntry
= &s_Advanced
[i
];
455 if (pEntry
->dwType
== AETYPE_GROUP
)
457 TreeView_Expand(hwndTreeView
, pEntry
->hItem
, TVE_EXPAND
);
463 Advanced_LoadTree(HKEY hKey
, LPCWSTR pszKeyName
, DWORD dwParentID
)
466 WCHAR szKeyName
[64], szText
[MAX_PATH
], *pch
;
468 ADVANCED_ENTRY
*pAllocated
;
471 Size
= (s_AdvancedCount
+ 1) * sizeof(ADVANCED_ENTRY
);
472 pAllocated
= (ADVANCED_ENTRY
*)realloc(s_Advanced
, Size
);
473 if (pAllocated
== NULL
)
474 return FALSE
; // failure
476 s_Advanced
= pAllocated
;
478 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[s_AdvancedCount
];
480 // dwID, dwParentID, szKeyName
481 pEntry
->dwID
= s_AdvancedCount
;
482 pEntry
->dwParentID
= dwParentID
;
483 lstrcpynW(pEntry
->szKeyName
, pszKeyName
, _countof(pEntry
->szKeyName
));
486 pEntry
->szText
[0] = 0;
487 pEntry
->dwResourceID
= 0;
489 Size
= sizeof(szText
);
490 RegQueryValueExW(hKey
, L
"Text", NULL
, NULL
, LPBYTE(szText
), &Size
);
491 if (szText
[0] == L
'@')
493 pch
= wcsrchr(szText
, L
',');
497 dwIndex
= abs(_wtoi(pch
+ 1));
498 pEntry
->dwResourceID
= dwIndex
;
500 HINSTANCE hInst
= LoadLibraryW(&szText
[1]);
501 LoadStringW(hInst
, dwIndex
, szText
, _countof(szText
));
506 pEntry
->dwResourceID
= DWORD(-1);
508 lstrcpynW(pEntry
->szText
, szText
, _countof(pEntry
->szText
));
512 RegQueryValueExW(hKey
, L
"Type", NULL
, NULL
, LPBYTE(szText
), &Size
);
513 if (lstrcmpiW(szText
, L
"checkbox") == 0)
514 pEntry
->dwType
= AETYPE_CHECKBOX
;
515 else if (lstrcmpiW(szText
, L
"radio") == 0)
516 pEntry
->dwType
= AETYPE_RADIO
;
517 else if (lstrcmpiW(szText
, L
"group") == 0)
518 pEntry
->dwType
= AETYPE_GROUP
;
520 return FALSE
; // failure
522 pEntry
->nIconID
= -1;
523 if (pEntry
->dwType
== AETYPE_GROUP
)
527 Size
= sizeof(szText
);
529 RegQueryValueExW(hKey
, L
"Bitmap", NULL
, NULL
, LPBYTE(szText
), &Size
);
531 WCHAR szExpanded
[MAX_PATH
];
532 ExpandEnvironmentStringsW(szText
, szExpanded
, _countof(szExpanded
));
533 pch
= wcsrchr(szExpanded
, L
',');
537 nIconIndex
= abs(_wtoi(pch
+ 1));
539 pEntry
->nIconID
= Advanced_AddIcon(szExpanded
, nIconIndex
);
542 if (pEntry
->dwType
== AETYPE_GROUP
)
544 pEntry
->hkeyRoot
= NULL
;
545 pEntry
->szRegPath
[0] = 0;
546 pEntry
->szValueName
[0] = 0;
547 pEntry
->dwCheckedValue
= 0;
548 pEntry
->bHasUncheckedValue
= FALSE
;
549 pEntry
->dwUncheckedValue
= 0;
550 pEntry
->dwDefaultValue
= 0;
551 pEntry
->hItem
= NULL
;
552 pEntry
->bGrayed
= FALSE
;
553 pEntry
->bChecked
= FALSE
;
558 Value
= DWORD(HKEY_CURRENT_USER
);
559 Size
= sizeof(Value
);
560 RegQueryValueExW(hKey
, L
"HKeyRoot", NULL
, NULL
, LPBYTE(&Value
), &Size
);
561 pEntry
->hkeyRoot
= HKEY(Value
);
564 pEntry
->szRegPath
[0] = 0;
565 Size
= sizeof(szText
);
566 RegQueryValueExW(hKey
, L
"RegPath", NULL
, NULL
, LPBYTE(szText
), &Size
);
567 lstrcpynW(pEntry
->szRegPath
, szText
, _countof(pEntry
->szRegPath
));
570 pEntry
->szValueName
[0] = 0;
571 Size
= sizeof(szText
);
572 RegQueryValueExW(hKey
, L
"ValueName", NULL
, NULL
, LPBYTE(szText
), &Size
);
573 lstrcpynW(pEntry
->szValueName
, szText
, _countof(pEntry
->szValueName
));
576 Size
= sizeof(Value
);
578 RegQueryValueExW(hKey
, L
"CheckedValue", NULL
, NULL
, LPBYTE(&Value
), &Size
);
579 pEntry
->dwCheckedValue
= Value
;
582 Size
= sizeof(Value
);
584 pEntry
->bHasUncheckedValue
= TRUE
;
585 if (RegQueryValueExW(hKey
, L
"UncheckedValue", NULL
,
586 NULL
, LPBYTE(&Value
), &Size
) != ERROR_SUCCESS
)
588 pEntry
->bHasUncheckedValue
= FALSE
;
590 pEntry
->dwUncheckedValue
= Value
;
593 Size
= sizeof(Value
);
595 RegQueryValueExW(hKey
, L
"DefaultValue", NULL
, NULL
, LPBYTE(&Value
), &Size
);
596 pEntry
->dwDefaultValue
= Value
;
599 pEntry
->hItem
= NULL
;
603 Value
= pEntry
->dwDefaultValue
;
604 pEntry
->bGrayed
= TRUE
;
605 if (RegOpenKeyExW(HKEY(pEntry
->hkeyRoot
), pEntry
->szRegPath
, 0,
606 KEY_READ
, &hkeyTarget
) == ERROR_SUCCESS
)
608 Size
= sizeof(Value
);
609 if (RegQueryValueExW(hkeyTarget
, pEntry
->szValueName
, NULL
, NULL
,
610 LPBYTE(&Value
), &Size
) == ERROR_SUCCESS
)
612 pEntry
->bGrayed
= FALSE
;
614 RegCloseKey(hkeyTarget
);
616 pEntry
->bChecked
= (Value
== pEntry
->dwCheckedValue
);
619 // Grayed (ReactOS extension)
620 Size
= sizeof(Value
);
622 RegQueryValueExW(hKey
, L
"Grayed", NULL
, NULL
, LPBYTE(&Value
), &Size
);
623 if (!pEntry
->bGrayed
)
624 pEntry
->bGrayed
= Value
;
626 BOOL bIsGroup
= (pEntry
->dwType
== AETYPE_GROUP
);
627 dwParentID
= pEntry
->dwID
;
631 return TRUE
; // success
635 while (RegEnumKeyW(hKey
, dwIndex
, szKeyName
,
636 _countof(szKeyName
)) == ERROR_SUCCESS
)
639 if (RegOpenKeyExW(hKey
, szKeyName
, 0, KEY_READ
,
640 &hkeyChild
) != ERROR_SUCCESS
)
646 Advanced_LoadTree(hkeyChild
, szKeyName
, dwParentID
);
647 RegCloseKey(hkeyChild
);
652 return TRUE
; // success
656 Advanced_LoadAll(VOID
)
658 static const WCHAR s_szAdvanced
[] =
659 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced";
661 // free if already existed
670 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, s_szAdvanced
, 0,
671 KEY_READ
, &hKey
) != ERROR_SUCCESS
)
673 return FALSE
; // failure
679 while (RegEnumKeyW(hKey
, dwIndex
, szKeyName
,
680 _countof(szKeyName
)) == ERROR_SUCCESS
)
683 if (RegOpenKeyExW(hKey
, szKeyName
, 0, KEY_READ
,
684 &hkeyChild
) != ERROR_SUCCESS
)
690 Advanced_LoadTree(hkeyChild
, szKeyName
, DWORD(-1));
691 RegCloseKey(hkeyChild
);
698 return TRUE
; // success
702 Advanced_Compare(const void *x
, const void *y
)
704 ADVANCED_ENTRY
*pEntry1
= (ADVANCED_ENTRY
*)x
;
705 ADVANCED_ENTRY
*pEntry2
= (ADVANCED_ENTRY
*)y
;
706 DWORD dwParentID1
= pEntry1
->dwParentID
;
707 DWORD dwParentID2
= pEntry2
->dwParentID
;
708 while (dwParentID1
!= dwParentID2
)
710 ADVANCED_ENTRY
*pParent1
= Advanced_GetItem(dwParentID1
);
711 ADVANCED_ENTRY
*pParent2
= Advanced_GetItem(dwParentID2
);
712 if (!pParent1
&& !pParent2
)
714 if (!pParent1
&& pParent2
)
716 if (pParent1
&& !pParent2
)
718 INT nCompare
= lstrcmpi(pParent1
->szText
, pParent2
->szText
);
721 dwParentID1
= pParent1
->dwParentID
;
722 dwParentID2
= pParent2
->dwParentID
;
724 return lstrcmpi(pEntry1
->szText
, pEntry2
->szText
);
728 Advanced_SortAll(VOID
)
730 qsort(s_Advanced
, s_AdvancedCount
, sizeof(ADVANCED_ENTRY
), Advanced_Compare
);
733 EXTERN_C HPSXA WINAPI
SHCreatePropSheetExtArrayEx(HKEY hKey
, LPCWSTR pszSubKey
, UINT max_iface
, IDataObject
*pDataObj
);
736 UpdateGeneralIcons(HWND hDlg
)
738 HWND hwndTaskIcon
, hwndFolderIcon
, hwndClickIcon
;
739 HICON hTaskIcon
= NULL
, hFolderIcon
= NULL
, hClickIcon
= NULL
;
740 LPTSTR lpTaskIconName
= NULL
, lpFolderIconName
= NULL
, lpClickIconName
= NULL
;
742 // show task setting icon
743 if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_COMMONTASKS
) == BST_CHECKED
)
744 lpTaskIconName
= MAKEINTRESOURCE(IDI_SHELL_SHOW_COMMON_TASKS
);
745 else if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_CLASSICFOLDERS
) == BST_CHECKED
)
746 lpTaskIconName
= MAKEINTRESOURCE(IDI_SHELL_CLASSIC_FOLDERS
);
750 hTaskIcon
= (HICON
)LoadImage(shell32_hInstance
,
758 hwndTaskIcon
= GetDlgItem(hDlg
,
759 IDC_FOLDER_OPTIONS_TASKICON
);
762 SendMessage(hwndTaskIcon
,
770 // show Folder setting icons
771 if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_SAMEWINDOW
) == BST_CHECKED
)
772 lpFolderIconName
= MAKEINTRESOURCE(IDI_SHELL_OPEN_IN_SOME_WINDOW
);
773 else if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_OWNWINDOW
) == BST_CHECKED
)
774 lpFolderIconName
= MAKEINTRESOURCE(IDI_SHELL_OPEN_IN_NEW_WINDOW
);
776 if (lpFolderIconName
)
778 hFolderIcon
= (HICON
)LoadImage(shell32_hInstance
,
786 hwndFolderIcon
= GetDlgItem(hDlg
,
787 IDC_FOLDER_OPTIONS_FOLDERICON
);
790 SendMessage(hwndFolderIcon
,
793 (LPARAM
)hFolderIcon
);
798 // Show click setting icon
799 if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_SINGLECLICK
) == BST_CHECKED
)
800 lpClickIconName
= MAKEINTRESOURCE(IDI_SHELL_SINGLE_CLICK_TO_OPEN
);
801 else if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_DOUBLECLICK
) == BST_CHECKED
)
802 lpClickIconName
= MAKEINTRESOURCE(IDI_SHELL_DOUBLE_CLICK_TO_OPEN
);
806 hClickIcon
= (HICON
)LoadImage(shell32_hInstance
,
814 hwndClickIcon
= GetDlgItem(hDlg
,
815 IDC_FOLDER_OPTIONS_CLICKICON
);
818 SendMessage(hwndClickIcon
,
828 DeleteObject(hTaskIcon
);
830 DeleteObject(hFolderIcon
);
832 DeleteObject(hClickIcon
);
839 FolderOptionsGeneralDlg(
853 switch (LOWORD(wParam
))
855 case IDC_FOLDER_OPTIONS_COMMONTASKS
:
856 case IDC_FOLDER_OPTIONS_CLASSICFOLDERS
:
857 case IDC_FOLDER_OPTIONS_SAMEWINDOW
:
858 case IDC_FOLDER_OPTIONS_OWNWINDOW
:
859 case IDC_FOLDER_OPTIONS_SINGLECLICK
:
860 case IDC_FOLDER_OPTIONS_DOUBLECLICK
:
861 if (HIWORD(wParam
) == BN_CLICKED
)
863 UpdateGeneralIcons(hwndDlg
);
865 /* Enable the 'Apply' button */
866 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
874 LPNMHDR pnmh
= (LPNMHDR
)lParam
;
897 ViewDlg_OnInitDialog(HWND hwndDlg
)
899 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
901 s_hImageList
= CreateTreeImageList();
902 TreeView_SetImageList(hwndTreeView
, s_hImageList
, TVSIL_NORMAL
);
906 Advanced_InsertAll(hwndTreeView
);
908 return TRUE
; // set focus
912 ViewDlg_ToggleCheckItem(HWND hwndDlg
, HTREEITEM hItem
)
914 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
919 ZeroMemory(&Item
, sizeof(Item
));
920 Item
.mask
= TVIF_HANDLE
| TVIF_IMAGE
| TVIF_PARAM
;
922 if (!TreeView_GetItem(hwndTreeView
, &Item
))
923 return FALSE
; // no such item
925 ADVANCED_ENTRY
*pEntry
= Advanced_GetItem(Item
.lParam
);
927 return FALSE
; // no such item
929 return FALSE
; // disabled
932 Item
.mask
= TVIF_HANDLE
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
933 switch (pEntry
->dwType
)
935 case AETYPE_CHECKBOX
:
936 pEntry
->bChecked
= !pEntry
->bChecked
;
939 // reset all the entries of the same parent
940 for (i
= 0; i
< s_AdvancedCount
; ++i
)
942 ADVANCED_ENTRY
*pEntry2
= &s_Advanced
[i
];
943 if (pEntry
->dwParentID
== pEntry2
->dwParentID
)
945 pEntry2
->bChecked
= FALSE
;
947 Item
.hItem
= pEntry2
->hItem
;
948 INT iImage
= Advanced_GetImage(pEntry2
);
949 Item
.iImage
= Item
.iSelectedImage
= iImage
;
950 TreeView_SetItem(hwndTreeView
, &Item
);
953 pEntry
->bChecked
= TRUE
;
956 return FALSE
; // failure
958 Item
.iImage
= Item
.iSelectedImage
= Advanced_GetImage(pEntry
);
960 TreeView_SetItem(hwndTreeView
, &Item
);
964 TreeView_GetItemRect(hwndTreeView
, hItem
, &rcItem
, FALSE
);
965 InvalidateRect(hwndTreeView
, &rcItem
, TRUE
);
966 return TRUE
; // success
970 ViewDlg_OnTreeViewClick(HWND hwndDlg
)
972 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
974 // do hit test to get the clicked item
975 TV_HITTESTINFO HitTest
;
976 ZeroMemory(&HitTest
, sizeof(HitTest
));
977 DWORD dwPos
= GetMessagePos();
978 HitTest
.pt
.x
= LOWORD(dwPos
);
979 HitTest
.pt
.y
= HIWORD(dwPos
);
980 ScreenToClient(hwndTreeView
, &HitTest
.pt
);
981 HTREEITEM hItem
= TreeView_HitTest(hwndTreeView
, &HitTest
);
983 // toggle the check mark if possible
984 if (ViewDlg_ToggleCheckItem(hwndDlg
, hItem
))
986 // property sheet was changed
987 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
992 ViewDlg_OnTreeViewKeyDown(HWND hwndDlg
, TV_KEYDOWN
*KeyDown
)
994 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
996 if (KeyDown
->wVKey
== VK_SPACE
)
998 // [Space] key was pressed
999 HTREEITEM hItem
= TreeView_GetSelection(hwndTreeView
);
1000 if (ViewDlg_ToggleCheckItem(hwndDlg
, hItem
))
1002 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1008 ViewDlg_OnTreeCustomDraw(HWND hwndDlg
, NMTVCUSTOMDRAW
*Draw
)
1010 NMCUSTOMDRAW
& nmcd
= Draw
->nmcd
;
1011 switch (nmcd
.dwDrawStage
)
1014 return CDRF_NOTIFYITEMDRAW
; // for CDDS_ITEMPREPAINT
1016 case CDDS_ITEMPREPAINT
:
1017 if (!(nmcd
.uItemState
& CDIS_SELECTED
)) // not selected
1019 LPARAM lParam
= nmcd
.lItemlParam
;
1020 ADVANCED_ENTRY
*pEntry
= Advanced_GetItem(lParam
);
1021 if (pEntry
&& pEntry
->bGrayed
) // disabled
1024 Draw
->clrText
= GetSysColor(COLOR_GRAYTEXT
);
1025 Draw
->clrTextBk
= GetSysColor(COLOR_WINDOW
);
1026 return CDRF_NEWFONT
;
1034 return CDRF_DODEFAULT
;
1038 Advanced_RestoreDefaults(HWND hwndDlg
)
1040 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
1042 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
1044 // ignore if the type is group
1045 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
1046 if (pEntry
->dwType
== AETYPE_GROUP
)
1049 // set default value on registry
1051 if (RegOpenKeyExW(HKEY(pEntry
->hkeyRoot
), pEntry
->szRegPath
,
1052 0, KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
1056 RegSetValueExW(hKey
, pEntry
->szValueName
, 0, REG_DWORD
,
1057 LPBYTE(pEntry
->dwDefaultValue
), sizeof(DWORD
));
1060 // update check status
1061 pEntry
->bChecked
= (pEntry
->dwCheckedValue
== pEntry
->dwDefaultValue
);
1065 ZeroMemory(&Item
, sizeof(Item
));
1066 Item
.mask
= TVIF_HANDLE
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
1067 Item
.hItem
= pEntry
->hItem
;
1068 Item
.iImage
= Item
.iSelectedImage
= Advanced_GetImage(pEntry
);
1069 TreeView_SetItem(hwndTreeView
, &Item
);
1072 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1075 /* FIXME: These macros should not be defined here */
1076 #ifndef SSF_SHOWSUPERHIDDEN
1077 #define SSF_SHOWSUPERHIDDEN 0x00040000
1079 #ifndef SSF_SEPPROCESS
1080 #define SSF_SEPPROCESS 0x00080000
1084 ScanAdvancedSettings(SHELLSTATE
*pSS
, DWORD
*pdwMask
)
1086 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
1088 const ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
1089 if (pEntry
->dwType
== AETYPE_GROUP
|| pEntry
->bGrayed
)
1092 BOOL bChecked
= pEntry
->bChecked
;
1094 // FIXME: Add more items
1095 if (lstrcmpiW(pEntry
->szKeyName
, L
"SuperHidden") == 0)
1097 pSS
->fShowSuperHidden
= !bChecked
? 1 : 0;
1098 *pdwMask
|= SSF_SHOWSUPERHIDDEN
;
1101 if (lstrcmpiW(pEntry
->szKeyName
, L
"DesktopProcess") == 0)
1103 pSS
->fSepProcess
= bChecked
? 1 : 0;
1104 *pdwMask
|= SSF_SEPPROCESS
;
1107 if (lstrcmpiW(pEntry
->szKeyName
, L
"SHOWALL") == 0)
1109 pSS
->fShowAllObjects
= !bChecked
? 1 : 0;
1110 *pdwMask
|= SSF_SHOWALLOBJECTS
;
1113 if (lstrcmpiW(pEntry
->szKeyName
, L
"HideFileExt") == 0)
1115 pSS
->fShowExtensions
= !bChecked
? 1 : 0;
1116 *pdwMask
|= SSF_SHOWEXTENSIONS
;
1119 if (lstrcmpiW(pEntry
->szKeyName
, L
"ShowCompColor") == 0)
1121 pSS
->fShowCompColor
= bChecked
? 1 : 0;
1122 *pdwMask
|= SSF_SHOWCOMPCOLOR
;
1125 if (lstrcmpiW(pEntry
->szKeyName
, L
"ShowInfoTip") == 0)
1127 pSS
->fShowInfoTip
= bChecked
? 1 : 0;
1128 *pdwMask
|= SSF_SHOWINFOTIP
;
1135 VOID WINAPI
SHGetSetSettings(LPSHELLSTATE lpss
, DWORD dwMask
, BOOL bSet
);
1137 static BOOL CALLBACK
RefreshBrowsersCallback (HWND hWnd
, LPARAM msg
)
1139 WCHAR ClassName
[100];
1140 if (GetClassName(hWnd
, ClassName
, 100))
1142 if (!wcscmp(ClassName
, L
"Progman") ||
1143 !wcscmp(ClassName
, L
"CabinetWClass") ||
1144 !wcscmp(ClassName
, L
"ExploreWClass"))
1146 PostMessage(hWnd
, WM_COMMAND
, FCIDM_DESKBROWSER_REFRESH
, 0);
1153 ViewDlg_Apply(HWND hwndDlg
)
1155 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
1157 // ignore the entry if the type is group or the entry is grayed
1158 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
1159 if (pEntry
->dwType
== AETYPE_GROUP
|| pEntry
->bGrayed
)
1162 // open the registry key
1164 if (RegOpenKeyExW(HKEY(pEntry
->hkeyRoot
), pEntry
->szRegPath
, 0,
1165 KEY_WRITE
, &hkeyTarget
) != ERROR_SUCCESS
)
1170 // checked or unchecked?
1171 DWORD dwValue
, dwSize
;
1172 if (pEntry
->bChecked
)
1174 dwValue
= pEntry
->dwCheckedValue
;
1178 if (pEntry
->bHasUncheckedValue
)
1180 dwValue
= pEntry
->dwUncheckedValue
;
1184 // there is no unchecked value
1185 RegCloseKey(hkeyTarget
);
1191 dwSize
= sizeof(dwValue
);
1192 RegSetValueExW(hkeyTarget
, pEntry
->szValueName
, 0, REG_DWORD
,
1193 LPBYTE(&dwValue
), dwSize
);
1196 RegCloseKey(hkeyTarget
);
1199 // scan advanced settings for user's settings
1201 SHELLSTATE ShellState
;
1202 ZeroMemory(&ShellState
, sizeof(ShellState
));
1203 ScanAdvancedSettings(&ShellState
, &dwMask
);
1205 // update user's settings
1206 SHGetSetSettings(&ShellState
, dwMask
, TRUE
);
1209 SendMessage(HWND_BROADCAST
, WM_WININICHANGE
, 0, 0);
1211 EnumWindows(RefreshBrowsersCallback
, NULL
);
1215 FolderOptionsViewDlg(
1222 NMTVCUSTOMDRAW
*Draw
;
1227 return ViewDlg_OnInitDialog(hwndDlg
);
1229 switch (LOWORD(wParam
))
1231 case 14004: // Restore Defaults
1232 Advanced_RestoreDefaults(hwndDlg
);
1237 switch (LPNMHDR(lParam
)->code
)
1239 case NM_CLICK
: // clicked on treeview
1240 ViewDlg_OnTreeViewClick(hwndDlg
);
1242 case NM_CUSTOMDRAW
: // custom draw (for graying)
1243 Draw
= (NMTVCUSTOMDRAW
*)lParam
;
1244 Result
= ViewDlg_OnTreeCustomDraw(hwndDlg
, Draw
);
1245 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, Result
);
1247 case TVN_KEYDOWN
: // key is down
1248 ViewDlg_OnTreeViewKeyDown(hwndDlg
, (TV_KEYDOWN
*)lParam
);
1250 case PSN_APPLY
: // [Apply] is clicked
1251 ViewDlg_Apply(hwndDlg
);
1264 InitializeFileTypesListCtrlColumns(HWND hDlgCtrl
)
1270 int columnSize
= 140;
1273 if (!LoadStringW(shell32_hInstance
, IDS_COLUMN_EXTENSION
, szName
, sizeof(szName
) / sizeof(WCHAR
)))
1275 /* default to english */
1276 wcscpy(szName
, L
"Extensions");
1279 /* make sure its null terminated */
1280 szName
[(sizeof(szName
)/sizeof(WCHAR
))-1] = 0;
1282 GetClientRect(hDlgCtrl
, &clientRect
);
1283 ZeroMemory(&col
, sizeof(LV_COLUMN
));
1284 columnSize
= 140; //FIXME
1286 col
.mask
= LVCF_WIDTH
| LVCF_TEXT
| LVCF_SUBITEM
| LVCF_FMT
;
1287 col
.fmt
= LVCFMT_FIXED_WIDTH
;
1288 col
.cx
= columnSize
| LVCFMT_LEFT
;
1289 col
.cchTextMax
= wcslen(szName
);
1290 col
.pszText
= szName
;
1291 (void)SendMessageW(hDlgCtrl
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&col
);
1293 if (!LoadStringW(shell32_hInstance
, IDS_FILE_TYPES
, szName
, sizeof(szName
) / sizeof(WCHAR
)))
1295 /* default to english */
1296 wcscpy(szName
, L
"File Types");
1297 ERR("Failed to load localized string!\n");
1301 col
.cx
= clientRect
.right
- clientRect
.left
- columnSize
;
1302 col
.cchTextMax
= wcslen(szName
);
1303 col
.pszText
= szName
;
1304 (void)SendMessageW(hDlgCtrl
, LVM_INSERTCOLUMNW
, 1, (LPARAM
)&col
);
1306 /* set full select style */
1307 dwStyle
= (DWORD
) SendMessage(hDlgCtrl
, LVM_GETEXTENDEDLISTVIEWSTYLE
, 0, 0);
1308 dwStyle
= dwStyle
| LVS_EX_FULLROWSELECT
;
1309 SendMessage(hDlgCtrl
, LVM_SETEXTENDEDLISTVIEWSTYLE
, 0, dwStyle
);
1313 FindItem(HWND hDlgCtrl
, WCHAR
* ItemName
)
1315 LVFINDINFOW findInfo
;
1316 ZeroMemory(&findInfo
, sizeof(LVFINDINFOW
));
1318 findInfo
.flags
= LVFI_STRING
;
1319 findInfo
.psz
= ItemName
;
1320 return ListView_FindItem(hDlgCtrl
, 0, &findInfo
);
1325 InsertFileType(HWND hDlgCtrl
, WCHAR
* szName
, PINT iItem
, WCHAR
* szFile
)
1327 PFOLDER_FILE_TYPE_ENTRY Entry
;
1333 if (szName
[0] != L
'.')
1335 /* FIXME handle URL protocol handlers */
1339 /* allocate file type entry */
1340 Entry
= (PFOLDER_FILE_TYPE_ENTRY
)HeapAlloc(GetProcessHeap(), 0, sizeof(FOLDER_FILE_TYPE_ENTRY
));
1346 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, szName
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
1348 HeapFree(GetProcessHeap(), 0, Entry
);
1352 /* FIXME check for duplicates */
1354 /* query for the default key */
1355 dwSize
= sizeof(Entry
->ClassKey
);
1356 if (RegQueryValueExW(hKey
, NULL
, NULL
, NULL
, (LPBYTE
)Entry
->ClassKey
, &dwSize
) != ERROR_SUCCESS
)
1358 /* no link available */
1359 Entry
->ClassKey
[0] = 0;
1362 if (Entry
->ClassKey
[0])
1365 /* try open linked key */
1366 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, Entry
->ClassKey
, 0, KEY_READ
, &hTemp
) == ERROR_SUCCESS
)
1368 /* use linked key */
1374 /* read friendly type name */
1375 if (RegLoadMUIStringW(hKey
, L
"FriendlyTypeName", Entry
->FileDescription
, sizeof(Entry
->FileDescription
), NULL
, 0, NULL
) != ERROR_SUCCESS
)
1377 /* read file description */
1378 dwSize
= sizeof(Entry
->FileDescription
);
1379 Entry
->FileDescription
[0] = 0;
1381 /* read default key */
1382 RegQueryValueExW(hKey
, NULL
, NULL
, NULL
, (LPBYTE
)Entry
->FileDescription
, &dwSize
);
1385 /* Read the EditFlags value */
1386 Entry
->EditFlags
= 0;
1387 if (!RegQueryValueExW(hKey
, L
"EditFlags", NULL
, &dwType
, NULL
, &dwSize
))
1389 if ((dwType
== REG_DWORD
|| dwType
== REG_BINARY
) && dwSize
== sizeof(DWORD
))
1390 RegQueryValueExW(hKey
, L
"EditFlags", NULL
, NULL
, (LPBYTE
)&Entry
->EditFlags
, &dwSize
);
1396 /* Do not add excluded entries */
1397 if (Entry
->EditFlags
& 0x00000001) //FTA_Exclude
1399 HeapFree(GetProcessHeap(), 0, Entry
);
1403 /* convert extension to upper case */
1404 wcscpy(Entry
->FileExtension
, szName
);
1405 _wcsupr(Entry
->FileExtension
);
1407 if (!Entry
->FileDescription
[0])
1409 /* construct default 'FileExtensionFile' by formatting the uppercase extension
1410 with IDS_FILE_EXT_TYPE, outputting something like a l18n 'INI File' */
1412 StringCchPrintf(Entry
->FileDescription
, _countof(Entry
->FileDescription
), szFile
, &Entry
->FileExtension
[1]);
1415 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
1416 lvItem
.mask
= LVIF_TEXT
| LVIF_PARAM
;
1417 lvItem
.iSubItem
= 0;
1418 lvItem
.pszText
= &Entry
->FileExtension
[1];
1419 lvItem
.iItem
= *iItem
;
1420 lvItem
.lParam
= (LPARAM
)Entry
;
1421 (void)SendMessageW(hDlgCtrl
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
);
1423 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
1424 lvItem
.mask
= LVIF_TEXT
;
1425 lvItem
.pszText
= Entry
->FileDescription
;
1426 lvItem
.iItem
= *iItem
;
1427 lvItem
.iSubItem
= 1;
1428 ListView_SetItem(hDlgCtrl
, &lvItem
);
1436 ListViewCompareProc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
1438 PFOLDER_FILE_TYPE_ENTRY Entry1
, Entry2
;
1441 Entry1
= (PFOLDER_FILE_TYPE_ENTRY
)lParam1
;
1442 Entry2
= (PFOLDER_FILE_TYPE_ENTRY
)lParam2
;
1444 x
= wcsicmp(Entry1
->FileExtension
, Entry2
->FileExtension
);
1448 return wcsicmp(Entry1
->FileDescription
, Entry2
->FileDescription
);
1452 PFOLDER_FILE_TYPE_ENTRY
1453 InitializeFileTypesListCtrl(HWND hwndDlg
)
1463 hDlgCtrl
= GetDlgItem(hwndDlg
, 14000);
1464 InitializeFileTypesListCtrlColumns(hDlgCtrl
);
1467 if (!LoadStringW(shell32_hInstance
, IDS_FILE_EXT_TYPE
, szFile
, _countof(szFile
)))
1469 /* default to english */
1470 wcscpy(szFile
, L
"%s File");
1472 szFile
[(_countof(szFile
)) - 1] = 0;
1474 dwName
= _countof(szName
);
1476 while (RegEnumKeyExW(HKEY_CLASSES_ROOT
, dwIndex
++, szName
, &dwName
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
1478 InsertFileType(hDlgCtrl
, szName
, &iItem
, szFile
);
1479 dwName
= _countof(szName
);
1482 /* Leave if the list is empty */
1487 ListView_SortItems(hDlgCtrl
, ListViewCompareProc
, NULL
);
1489 /* select first item */
1490 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
1491 lvItem
.mask
= LVIF_STATE
;
1492 lvItem
.stateMask
= (UINT
)-1;
1493 lvItem
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
1495 ListView_SetItem(hDlgCtrl
, &lvItem
);
1497 lvItem
.mask
= LVIF_PARAM
;
1498 ListView_GetItem(hDlgCtrl
, &lvItem
);
1500 return (PFOLDER_FILE_TYPE_ENTRY
)lvItem
.lParam
;
1504 PFOLDER_FILE_TYPE_ENTRY
1511 Count
= ListView_GetItemCount(hDlgCtrl
);
1513 for (Index
= 0; Index
< Count
; Index
++)
1515 ZeroMemory(&lvItem
, sizeof(LVITEM
));
1516 lvItem
.mask
= LVIF_PARAM
| LVIF_STATE
;
1517 lvItem
.iItem
= Index
;
1518 lvItem
.stateMask
= (UINT
) - 1;
1520 if (ListView_GetItem(hDlgCtrl
, &lvItem
))
1522 if (lvItem
.state
& LVIS_SELECTED
)
1523 return (PFOLDER_FILE_TYPE_ENTRY
)lvItem
.lParam
;
1532 FolderOptionsFileTypesDlg(
1540 WCHAR Buffer
[255], FormatBuffer
[255];
1541 PFOLDER_FILE_TYPE_ENTRY pItem
;
1547 pItem
= InitializeFileTypesListCtrl(hwndDlg
);
1549 /* Disable the Delete button if the listview is empty or
1550 the selected item should not be deleted by the user */
1551 if (pItem
== NULL
|| (pItem
->EditFlags
& 0x00000010)) // FTA_NoRemove
1552 EnableWindow(GetDlgItem(hwndDlg
, 14002), FALSE
);
1556 switch(LOWORD(wParam
))
1559 pItem
= FindSelectedItem(GetDlgItem(hwndDlg
, 14000));
1562 Info
.oaifInFlags
= OAIF_ALLOW_REGISTRATION
| OAIF_REGISTER_EXT
;
1563 Info
.pcszClass
= pItem
->FileExtension
;
1564 SHOpenWithDialog(hwndDlg
, &Info
);
1571 lppl
= (LPNMLISTVIEW
) lParam
;
1573 if (lppl
->hdr
.code
== LVN_ITEMCHANGING
)
1575 ZeroMemory(&lvItem
, sizeof(LVITEM
));
1576 lvItem
.mask
= LVIF_PARAM
;
1577 lvItem
.iItem
= lppl
->iItem
;
1578 if (!SendMessageW(lppl
->hdr
.hwndFrom
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
))
1581 pItem
= (PFOLDER_FILE_TYPE_ENTRY
)lvItem
.lParam
;
1585 if (!(lppl
->uOldState
& LVIS_FOCUSED
) && (lppl
->uNewState
& LVIS_FOCUSED
))
1587 /* new focused item */
1588 if (!LoadStringW(shell32_hInstance
, IDS_FILE_DETAILS
, FormatBuffer
, sizeof(FormatBuffer
) / sizeof(WCHAR
)))
1590 /* use default english format string */
1591 wcscpy(FormatBuffer
, L
"Details for '%s' extension");
1595 swprintf(Buffer
, FormatBuffer
, &pItem
->FileExtension
[1]);
1597 SetDlgItemTextW(hwndDlg
, 14003, Buffer
);
1599 if (!LoadStringW(shell32_hInstance
, IDS_FILE_DETAILSADV
, FormatBuffer
, sizeof(FormatBuffer
) / sizeof(WCHAR
)))
1601 /* use default english format string */
1602 wcscpy(FormatBuffer
, L
"Files with extension '%s' are of type '%s'. To change settings that affect all '%s' files, click Advanced.");
1605 swprintf(Buffer
, FormatBuffer
, &pItem
->FileExtension
[1], &pItem
->FileDescription
[0], &pItem
->FileDescription
[0]);
1607 SetDlgItemTextW(hwndDlg
, 14007, Buffer
);
1609 /* Enable the Delete button */
1610 if (pItem
->EditFlags
& 0x00000010) // FTA_NoRemove
1611 EnableWindow(GetDlgItem(hwndDlg
, 14002), FALSE
);
1613 EnableWindow(GetDlgItem(hwndDlg
, 14002), TRUE
);
1616 else if (lppl
->hdr
.code
== PSN_SETACTIVE
)
1618 /* On page activation, set the focus to the listview */
1619 SetFocus(GetDlgItem(hwndDlg
, 14000));
1629 ShowFolderOptionsDialog(HWND hWnd
, HINSTANCE hInst
)
1631 PROPSHEETHEADERW pinfo
;
1632 HPROPSHEETPAGE hppages
[3];
1633 HPROPSHEETPAGE hpage
;
1635 WCHAR szOptions
[100];
1637 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_GENERAL
, FolderOptionsGeneralDlg
, 0, NULL
);
1639 hppages
[num_pages
++] = hpage
;
1641 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_VIEW
, FolderOptionsViewDlg
, 0, NULL
);
1643 hppages
[num_pages
++] = hpage
;
1645 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_FILETYPES
, FolderOptionsFileTypesDlg
, 0, NULL
);
1647 hppages
[num_pages
++] = hpage
;
1649 szOptions
[0] = L
'\0';
1650 LoadStringW(shell32_hInstance
, IDS_FOLDER_OPTIONS
, szOptions
, sizeof(szOptions
) / sizeof(WCHAR
));
1651 szOptions
[(sizeof(szOptions
)/sizeof(WCHAR
))-1] = L
'\0';
1653 memset(&pinfo
, 0x0, sizeof(PROPSHEETHEADERW
));
1654 pinfo
.dwSize
= sizeof(PROPSHEETHEADERW
);
1655 pinfo
.dwFlags
= PSH_NOCONTEXTHELP
;
1656 pinfo
.nPages
= num_pages
;
1657 pinfo
.phpage
= hppages
;
1658 pinfo
.pszCaption
= szOptions
;
1660 PropertySheetW(&pinfo
);
1665 Options_RunDLLCommon(HWND hWnd
, HINSTANCE hInst
, int fOptions
, DWORD nCmdShow
)
1670 ShowFolderOptionsDialog(hWnd
, hInst
);
1673 // show taskbar options dialog
1674 FIXME("notify explorer to show taskbar options dialog");
1675 //PostMessage(GetShellWindow(), WM_USER+22, fOptions, 0);
1678 FIXME("unrecognized options id %d\n", fOptions
);
1682 /*************************************************************************
1683 * Options_RunDLL (SHELL32.@)
1685 EXTERN_C VOID WINAPI
Options_RunDLL(HWND hWnd
, HINSTANCE hInst
, LPCSTR cmd
, DWORD nCmdShow
)
1687 Options_RunDLLCommon(hWnd
, hInst
, StrToIntA(cmd
), nCmdShow
);
1690 /*************************************************************************
1691 * Options_RunDLLA (SHELL32.@)
1693 EXTERN_C VOID WINAPI
Options_RunDLLA(HWND hWnd
, HINSTANCE hInst
, LPCSTR cmd
, DWORD nCmdShow
)
1695 Options_RunDLLCommon(hWnd
, hInst
, StrToIntA(cmd
), nCmdShow
);
1698 /*************************************************************************
1699 * Options_RunDLLW (SHELL32.@)
1701 EXTERN_C VOID WINAPI
Options_RunDLLW(HWND hWnd
, HINSTANCE hInst
, LPCWSTR cmd
, DWORD nCmdShow
)
1703 Options_RunDLLCommon(hWnd
, hInst
, StrToIntW(cmd
), nCmdShow
);