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
);
27 /// CLASSKEY = HKEY_CLASSES_ROOT\CLSID\{6DFD7C5C-2451-11d3-A299-00C04F8EF6AF}
28 /// DefaultIcon = %SystemRoot%\system32\SHELL32.dll,-210
29 /// Verbs: Open / RunAs
30 /// Cmd: rundll32.exe shell32.dll,Options_RunDLL 0
32 /// ShellFolder Attributes: 0x0
36 WCHAR FileExtension
[30];
37 WCHAR FileDescription
[100];
38 WCHAR ClassKey
[MAX_PATH
];
40 } FOLDER_FILE_TYPE_ENTRY
, *PFOLDER_FILE_TYPE_ENTRY
;
42 // uniquely-defined icon entry for Advanced Settings
43 typedef struct ADVANCED_ICON
45 WCHAR szPath
[MAX_PATH
];
49 // predefined icon IDs (See CreateTreeImageList function below)
52 #define I_CHECKED_DISABLED 2
53 #define I_UNCHECKED_DISABLED 3
54 #define I_RADIO_CHECKED 4
55 #define I_RADIO_UNCHECKED 5
56 #define I_RADIO_CHECKED_DISABLED 6
57 #define I_RADIO_UNCHECKED_DISABLED 7
59 #define PREDEFINED_ICON_COUNT 8
61 // definition of icon stock
62 static ADVANCED_ICON
* s_AdvancedIcons
= NULL
;
63 static INT s_AdvancedIconCount
= 0;
64 static HIMAGELIST s_hImageList
= NULL
;
67 Advanced_FindIcon(LPCWSTR pszPath
, UINT nIconIndex
)
69 for (INT i
= PREDEFINED_ICON_COUNT
; i
< s_AdvancedIconCount
; ++i
)
71 ADVANCED_ICON
*pIcon
= &s_AdvancedIcons
[i
];
72 if (pIcon
->nIconIndex
== nIconIndex
&&
73 lstrcmpiW(pIcon
->szPath
, pszPath
) == 0)
78 return -1; // not found
82 Advanced_AddIcon(LPCWSTR pszPath
, UINT nIconIndex
)
84 ADVANCED_ICON
*pAllocated
;
86 // return the ID if already existed
87 INT nIconID
= Advanced_FindIcon(pszPath
, nIconIndex
);
89 return nIconID
; // already exists
91 // extract a small icon
92 HICON hIconSmall
= NULL
;
93 ExtractIconExW(pszPath
, nIconIndex
, NULL
, &hIconSmall
, 1);
94 if (hIconSmall
== NULL
)
97 // resize s_AdvancedIcons
98 size_t Size
= (s_AdvancedIconCount
+ 1) * sizeof(ADVANCED_ICON
);
99 pAllocated
= (ADVANCED_ICON
*)realloc(s_AdvancedIcons
, Size
);
100 if (pAllocated
== NULL
)
101 return -1; // failure
103 s_AdvancedIcons
= pAllocated
;
105 // save icon information
106 ADVANCED_ICON
*pIcon
= &s_AdvancedIcons
[s_AdvancedIconCount
];
107 lstrcpynW(pIcon
->szPath
, pszPath
, _countof(pIcon
->szPath
));
108 pIcon
->nIconIndex
= nIconIndex
;
110 // add the icon to the image list
111 ImageList_AddIcon(s_hImageList
, hIconSmall
);
113 // increment the counter
114 nIconID
= s_AdvancedIconCount
;
115 ++s_AdvancedIconCount
;
117 DestroyIcon(hIconSmall
);
119 return nIconID
; // newly-added icon ID
122 // types of Advanced Setting entry
123 typedef enum ADVANCED_ENTRY_TYPE
128 } ADVANCED_ENTRY_TYPE
;
130 // an entry info of Advanced Settings
131 typedef struct ADVANCED_ENTRY
133 DWORD dwID
; // entry ID
134 DWORD dwParentID
; // parent entry ID
135 DWORD dwResourceID
; // resource ID
136 WCHAR szKeyName
[64]; // entry key name
137 DWORD dwType
; // ADVANCED_ENTRY_TYPE
138 WCHAR szText
[MAX_PATH
]; // text
139 INT nIconID
; // icon ID (See ADVANCED_ICON)
141 HKEY hkeyRoot
; // registry root key
142 WCHAR szRegPath
[MAX_PATH
]; // registry path
143 WCHAR szValueName
[64]; // registry value name
145 DWORD dwCheckedValue
; // checked value
146 DWORD dwUncheckedValue
; // unchecked value
147 DWORD dwDefaultValue
; // defalut value
148 BOOL bHasUncheckedValue
; // If FALSE, UncheckedValue is invalid
150 HTREEITEM hItem
; // for TreeView
151 BOOL bGrayed
; // disabled?
152 BOOL bChecked
; // checked?
153 } ADVANCED_ENTRY
, *PADVANCED_ENTRY
;
155 // definition of advanced entries
156 static ADVANCED_ENTRY
* s_Advanced
= NULL
;
157 static INT s_AdvancedCount
= 0;
160 Create24BppBitmap(HDC hDC
, INT cx
, INT cy
)
165 ZeroMemory(&bi
, sizeof(bi
));
166 bi
.bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
167 bi
.bmiHeader
.biWidth
= cx
;
168 bi
.bmiHeader
.biHeight
= cy
;
169 bi
.bmiHeader
.biPlanes
= 1;
170 bi
.bmiHeader
.biBitCount
= 24;
171 bi
.bmiHeader
.biCompression
= BI_RGB
;
173 HBITMAP hbm
= CreateDIBSection(hDC
, &bi
, DIB_RGB_COLORS
, &pvBits
, NULL
, 0);
178 CreateCheckImage(HDC hDC
, BOOL bCheck
, BOOL bEnabled
= TRUE
)
180 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
181 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
183 HBITMAP hbm
= Create24BppBitmap(hDC
, cxSmallIcon
, cySmallIcon
);
185 return NULL
; // failure
188 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
190 InflateRect(&BoxRect
, -1, -1);
192 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
194 UINT uState
= DFCS_BUTTONCHECK
| DFCS_FLAT
| DFCS_MONO
;
196 uState
|= DFCS_CHECKED
;
198 uState
|= DFCS_INACTIVE
;
199 DrawFrameControl(hDC
, &BoxRect
, DFC_BUTTON
, uState
);
201 SelectObject(hDC
, hbmOld
);
203 return hbm
; // success
207 CreateCheckMask(HDC hDC
)
209 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
210 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
212 HBITMAP hbm
= CreateBitmap(cxSmallIcon
, cySmallIcon
, 1, 1, NULL
);
214 return NULL
; // failure
217 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
219 InflateRect(&BoxRect
, -1, -1);
221 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
223 FillRect(hDC
, &Rect
, HBRUSH(GetStockObject(WHITE_BRUSH
)));
224 FillRect(hDC
, &BoxRect
, HBRUSH(GetStockObject(BLACK_BRUSH
)));
226 SelectObject(hDC
, hbmOld
);
228 return hbm
; // success
232 CreateRadioImage(HDC hDC
, BOOL bCheck
, BOOL bEnabled
= TRUE
)
234 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
235 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
237 HBITMAP hbm
= Create24BppBitmap(hDC
, cxSmallIcon
, cySmallIcon
);
239 return NULL
; // failure
242 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
244 InflateRect(&BoxRect
, -1, -1);
246 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
248 UINT uState
= DFCS_BUTTONRADIOIMAGE
| DFCS_FLAT
| DFCS_MONO
;
250 uState
|= DFCS_CHECKED
;
252 uState
|= DFCS_INACTIVE
;
253 DrawFrameControl(hDC
, &BoxRect
, DFC_BUTTON
, uState
);
255 SelectObject(hDC
, hbmOld
);
257 return hbm
; // success
261 CreateRadioMask(HDC hDC
)
263 INT cxSmallIcon
= GetSystemMetrics(SM_CXSMICON
);
264 INT cySmallIcon
= GetSystemMetrics(SM_CYSMICON
);
266 HBITMAP hbm
= CreateBitmap(cxSmallIcon
, cySmallIcon
, 1, 1, NULL
);
268 return NULL
; // failure
271 SetRect(&Rect
, 0, 0, cxSmallIcon
, cySmallIcon
);
273 InflateRect(&BoxRect
, -1, -1);
275 HGDIOBJ hbmOld
= SelectObject(hDC
, hbm
);
277 FillRect(hDC
, &Rect
, HBRUSH(GetStockObject(WHITE_BRUSH
)));
278 UINT uState
= DFCS_BUTTONRADIOMASK
| DFCS_FLAT
| DFCS_MONO
;
279 DrawFrameControl(hDC
, &BoxRect
, DFC_BUTTON
, uState
);
281 SelectObject(hDC
, hbmOld
);
283 return hbm
; // success
287 CreateTreeImageList(VOID
)
289 HIMAGELIST hImageList
;
290 hImageList
= ImageList_Create(16, 16, ILC_COLOR24
| ILC_MASK
, 9, 1);
291 if (hImageList
== NULL
)
292 return NULL
; // failure
297 free(s_AdvancedIcons
);
298 s_AdvancedIcons
= NULL
;
300 s_AdvancedIconCount
= 0;
303 ADVANCED_ICON
*pAllocated
;
304 size_t Size
= PREDEFINED_ICON_COUNT
* sizeof(ADVANCED_ICON
);
305 pAllocated
= (ADVANCED_ICON
*)calloc(1, Size
);
306 if (pAllocated
== NULL
)
307 return NULL
; // failure
309 s_AdvancedIconCount
= PREDEFINED_ICON_COUNT
;
310 s_AdvancedIcons
= pAllocated
;
312 // add the predefined icons
314 HDC hDC
= CreateCompatibleDC(NULL
);
315 HBITMAP hbmMask
= CreateCheckMask(hDC
);
317 HBITMAP hbmChecked
, hbmUnchecked
;
319 hbmChecked
= CreateCheckImage(hDC
, TRUE
);
320 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
321 DeleteObject(hbmChecked
);
323 hbmUnchecked
= CreateCheckImage(hDC
, FALSE
);
324 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
325 DeleteObject(hbmUnchecked
);
327 hbmChecked
= CreateCheckImage(hDC
, TRUE
, FALSE
);
328 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
329 DeleteObject(hbmChecked
);
331 hbmUnchecked
= CreateCheckImage(hDC
, FALSE
, FALSE
);
332 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
333 DeleteObject(hbmUnchecked
);
335 DeleteObject(hbmMask
);
336 hbmMask
= CreateRadioMask(hDC
);
338 hbmChecked
= CreateRadioImage(hDC
, TRUE
);
339 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
340 DeleteObject(hbmChecked
);
342 hbmUnchecked
= CreateRadioImage(hDC
, FALSE
);
343 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
344 DeleteObject(hbmUnchecked
);
346 hbmChecked
= CreateRadioImage(hDC
, TRUE
, FALSE
);
347 ImageList_Add(hImageList
, hbmChecked
, hbmMask
);
348 DeleteObject(hbmChecked
);
350 hbmUnchecked
= CreateRadioImage(hDC
, FALSE
, FALSE
);
351 ImageList_Add(hImageList
, hbmUnchecked
, hbmMask
);
352 DeleteObject(hbmUnchecked
);
354 DeleteObject(hbmMask
);
359 static ADVANCED_ENTRY
*
360 Advanced_GetItem(DWORD dwID
)
362 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
364 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
365 if (pEntry
->dwID
== dwID
)
368 return NULL
; // failure
372 Advanced_GetImage(ADVANCED_ENTRY
*pEntry
)
374 switch (pEntry
->dwType
)
377 return pEntry
->nIconID
;
379 case AETYPE_CHECKBOX
:
382 if (pEntry
->bChecked
)
383 return I_CHECKED_DISABLED
;
385 return I_UNCHECKED_DISABLED
;
389 if (pEntry
->bChecked
)
398 if (pEntry
->bChecked
)
399 return I_RADIO_CHECKED_DISABLED
;
401 return I_RADIO_UNCHECKED_DISABLED
;
405 if (pEntry
->bChecked
)
406 return I_RADIO_CHECKED
;
408 return I_RADIO_UNCHECKED
;
411 return -1; // failure
415 Advanced_InsertEntry(HWND hwndTreeView
, ADVANCED_ENTRY
*pEntry
)
417 ADVANCED_ENTRY
*pParent
= Advanced_GetItem(pEntry
->dwParentID
);
418 HTREEITEM hParent
= TVI_ROOT
;
420 hParent
= pParent
->hItem
;
422 TV_INSERTSTRUCT Insertion
;
423 ZeroMemory(&Insertion
, sizeof(Insertion
));
424 Insertion
.hParent
= hParent
;
425 Insertion
.hInsertAfter
= TVI_LAST
;
426 Insertion
.item
.mask
=
427 TVIF_TEXT
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
| TVIF_PARAM
;
428 Insertion
.item
.pszText
= pEntry
->szText
;
430 INT iImage
= Advanced_GetImage(pEntry
);
431 Insertion
.item
.iImage
= Insertion
.item
.iSelectedImage
= iImage
;
432 Insertion
.item
.lParam
= pEntry
->dwID
;
433 pEntry
->hItem
= TreeView_InsertItem(hwndTreeView
, &Insertion
);
437 Advanced_InsertAll(HWND hwndTreeView
)
439 TreeView_DeleteAllItems(hwndTreeView
);
441 // insert the entries
442 ADVANCED_ENTRY
*pEntry
;
443 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
445 pEntry
= &s_Advanced
[i
];
446 Advanced_InsertEntry(hwndTreeView
, pEntry
);
450 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
452 pEntry
= &s_Advanced
[i
];
453 if (pEntry
->dwType
== AETYPE_GROUP
)
455 TreeView_Expand(hwndTreeView
, pEntry
->hItem
, TVE_EXPAND
);
461 Advanced_LoadTree(HKEY hKey
, LPCWSTR pszKeyName
, DWORD dwParentID
)
464 WCHAR szKeyName
[64], szText
[MAX_PATH
], *pch
;
466 ADVANCED_ENTRY
*pAllocated
;
469 Size
= (s_AdvancedCount
+ 1) * sizeof(ADVANCED_ENTRY
);
470 pAllocated
= (ADVANCED_ENTRY
*)realloc(s_Advanced
, Size
);
471 if (pAllocated
== NULL
)
472 return FALSE
; // failure
474 s_Advanced
= pAllocated
;
476 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[s_AdvancedCount
];
478 // dwID, dwParentID, szKeyName
479 pEntry
->dwID
= s_AdvancedCount
;
480 pEntry
->dwParentID
= dwParentID
;
481 lstrcpynW(pEntry
->szKeyName
, pszKeyName
, _countof(pEntry
->szKeyName
));
484 pEntry
->szText
[0] = 0;
485 pEntry
->dwResourceID
= 0;
487 Size
= sizeof(szText
);
488 RegQueryValueExW(hKey
, L
"Text", NULL
, NULL
, LPBYTE(szText
), &Size
);
489 if (szText
[0] == L
'@')
491 pch
= wcsrchr(szText
, L
',');
495 dwIndex
= abs(_wtoi(pch
+ 1));
496 pEntry
->dwResourceID
= dwIndex
;
498 HINSTANCE hInst
= LoadLibraryW(&szText
[1]);
499 LoadStringW(hInst
, dwIndex
, szText
, _countof(szText
));
504 pEntry
->dwResourceID
= DWORD(-1);
506 lstrcpynW(pEntry
->szText
, szText
, _countof(pEntry
->szText
));
510 RegQueryValueExW(hKey
, L
"Type", NULL
, NULL
, LPBYTE(szText
), &Size
);
511 if (lstrcmpiW(szText
, L
"checkbox") == 0)
512 pEntry
->dwType
= AETYPE_CHECKBOX
;
513 else if (lstrcmpiW(szText
, L
"radio") == 0)
514 pEntry
->dwType
= AETYPE_RADIO
;
515 else if (lstrcmpiW(szText
, L
"group") == 0)
516 pEntry
->dwType
= AETYPE_GROUP
;
518 return FALSE
; // failure
520 pEntry
->nIconID
= -1;
521 if (pEntry
->dwType
== AETYPE_GROUP
)
525 Size
= sizeof(szText
);
527 RegQueryValueExW(hKey
, L
"Bitmap", NULL
, NULL
, LPBYTE(szText
), &Size
);
529 WCHAR szExpanded
[MAX_PATH
];
530 ExpandEnvironmentStringsW(szText
, szExpanded
, _countof(szExpanded
));
531 pch
= wcsrchr(szExpanded
, L
',');
535 nIconIndex
= abs(_wtoi(pch
+ 1));
537 pEntry
->nIconID
= Advanced_AddIcon(szExpanded
, nIconIndex
);
540 if (pEntry
->dwType
== AETYPE_GROUP
)
542 pEntry
->hkeyRoot
= NULL
;
543 pEntry
->szRegPath
[0] = 0;
544 pEntry
->szValueName
[0] = 0;
545 pEntry
->dwCheckedValue
= 0;
546 pEntry
->bHasUncheckedValue
= FALSE
;
547 pEntry
->dwUncheckedValue
= 0;
548 pEntry
->dwDefaultValue
= 0;
549 pEntry
->hItem
= NULL
;
550 pEntry
->bGrayed
= FALSE
;
551 pEntry
->bChecked
= FALSE
;
556 Value
= DWORD(HKEY_CURRENT_USER
);
557 Size
= sizeof(Value
);
558 RegQueryValueExW(hKey
, L
"HKeyRoot", NULL
, NULL
, LPBYTE(&Value
), &Size
);
559 pEntry
->hkeyRoot
= HKEY(Value
);
562 pEntry
->szRegPath
[0] = 0;
563 Size
= sizeof(szText
);
564 RegQueryValueExW(hKey
, L
"RegPath", NULL
, NULL
, LPBYTE(szText
), &Size
);
565 lstrcpynW(pEntry
->szRegPath
, szText
, _countof(pEntry
->szRegPath
));
568 pEntry
->szValueName
[0] = 0;
569 Size
= sizeof(szText
);
570 RegQueryValueExW(hKey
, L
"ValueName", NULL
, NULL
, LPBYTE(szText
), &Size
);
571 lstrcpynW(pEntry
->szValueName
, szText
, _countof(pEntry
->szValueName
));
574 Size
= sizeof(Value
);
576 RegQueryValueExW(hKey
, L
"CheckedValue", NULL
, NULL
, LPBYTE(&Value
), &Size
);
577 pEntry
->dwCheckedValue
= Value
;
580 Size
= sizeof(Value
);
582 pEntry
->bHasUncheckedValue
= TRUE
;
583 if (RegQueryValueExW(hKey
, L
"UncheckedValue", NULL
,
584 NULL
, LPBYTE(&Value
), &Size
) != ERROR_SUCCESS
)
586 pEntry
->bHasUncheckedValue
= FALSE
;
588 pEntry
->dwUncheckedValue
= Value
;
591 Size
= sizeof(Value
);
593 RegQueryValueExW(hKey
, L
"DefaultValue", NULL
, NULL
, LPBYTE(&Value
), &Size
);
594 pEntry
->dwDefaultValue
= Value
;
597 pEntry
->hItem
= NULL
;
601 Value
= pEntry
->dwDefaultValue
;
602 pEntry
->bGrayed
= TRUE
;
603 if (RegOpenKeyExW(HKEY(pEntry
->hkeyRoot
), pEntry
->szRegPath
, 0,
604 KEY_READ
, &hkeyTarget
) == ERROR_SUCCESS
)
606 Size
= sizeof(Value
);
607 if (RegQueryValueExW(hkeyTarget
, pEntry
->szValueName
, NULL
, NULL
,
608 LPBYTE(&Value
), &Size
) == ERROR_SUCCESS
)
610 pEntry
->bGrayed
= FALSE
;
612 RegCloseKey(hkeyTarget
);
614 pEntry
->bChecked
= (Value
== pEntry
->dwCheckedValue
);
617 // Grayed (ReactOS extension)
618 Size
= sizeof(Value
);
620 RegQueryValueExW(hKey
, L
"Grayed", NULL
, NULL
, LPBYTE(&Value
), &Size
);
621 if (!pEntry
->bGrayed
)
622 pEntry
->bGrayed
= Value
;
624 BOOL bIsGroup
= (pEntry
->dwType
== AETYPE_GROUP
);
625 dwParentID
= pEntry
->dwID
;
629 return TRUE
; // success
633 while (RegEnumKeyW(hKey
, dwIndex
, szKeyName
,
634 _countof(szKeyName
)) == ERROR_SUCCESS
)
637 if (RegOpenKeyExW(hKey
, szKeyName
, 0, KEY_READ
,
638 &hkeyChild
) != ERROR_SUCCESS
)
644 Advanced_LoadTree(hkeyChild
, szKeyName
, dwParentID
);
645 RegCloseKey(hkeyChild
);
650 return TRUE
; // success
654 Advanced_LoadAll(VOID
)
656 static const WCHAR s_szAdvanced
[] =
657 L
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced";
659 // free if already existed
668 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, s_szAdvanced
, 0,
669 KEY_READ
, &hKey
) != ERROR_SUCCESS
)
671 return FALSE
; // failure
677 while (RegEnumKeyW(hKey
, dwIndex
, szKeyName
,
678 _countof(szKeyName
)) == ERROR_SUCCESS
)
681 if (RegOpenKeyExW(hKey
, szKeyName
, 0, KEY_READ
,
682 &hkeyChild
) != ERROR_SUCCESS
)
688 Advanced_LoadTree(hkeyChild
, szKeyName
, DWORD(-1));
689 RegCloseKey(hkeyChild
);
696 return TRUE
; // success
700 Advanced_Compare(const void *x
, const void *y
)
702 ADVANCED_ENTRY
*pEntry1
= (ADVANCED_ENTRY
*)x
;
703 ADVANCED_ENTRY
*pEntry2
= (ADVANCED_ENTRY
*)y
;
704 DWORD dwParentID1
= pEntry1
->dwParentID
;
705 DWORD dwParentID2
= pEntry2
->dwParentID
;
706 while (dwParentID1
!= dwParentID2
)
708 ADVANCED_ENTRY
*pParent1
= Advanced_GetItem(dwParentID1
);
709 ADVANCED_ENTRY
*pParent2
= Advanced_GetItem(dwParentID2
);
710 if (!pParent1
&& !pParent2
)
712 if (!pParent1
&& pParent2
)
714 if (pParent1
&& !pParent2
)
716 INT nCompare
= lstrcmpi(pParent1
->szText
, pParent2
->szText
);
719 dwParentID1
= pParent1
->dwParentID
;
720 dwParentID2
= pParent2
->dwParentID
;
722 return lstrcmpi(pEntry1
->szText
, pEntry2
->szText
);
726 Advanced_SortAll(VOID
)
728 qsort(s_Advanced
, s_AdvancedCount
, sizeof(ADVANCED_ENTRY
), Advanced_Compare
);
731 EXTERN_C HPSXA WINAPI
SHCreatePropSheetExtArrayEx(HKEY hKey
, LPCWSTR pszSubKey
, UINT max_iface
, IDataObject
*pDataObj
);
734 UpdateGeneralIcons(HWND hDlg
)
736 HWND hwndTaskIcon
, hwndFolderIcon
, hwndClickIcon
;
737 HICON hTaskIcon
= NULL
, hFolderIcon
= NULL
, hClickIcon
= NULL
;
738 LPTSTR lpTaskIconName
= NULL
, lpFolderIconName
= NULL
, lpClickIconName
= NULL
;
740 // show task setting icon
741 if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_COMMONTASKS
) == BST_CHECKED
)
742 lpTaskIconName
= MAKEINTRESOURCE(IDI_SHELL_SHOW_COMMON_TASKS
);
743 else if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_CLASSICFOLDERS
) == BST_CHECKED
)
744 lpTaskIconName
= MAKEINTRESOURCE(IDI_SHELL_CLASSIC_FOLDERS
);
748 hTaskIcon
= (HICON
)LoadImage(shell32_hInstance
,
756 hwndTaskIcon
= GetDlgItem(hDlg
,
757 IDC_FOLDER_OPTIONS_TASKICON
);
760 SendMessage(hwndTaskIcon
,
768 // show Folder setting icons
769 if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_SAMEWINDOW
) == BST_CHECKED
)
770 lpFolderIconName
= MAKEINTRESOURCE(IDI_SHELL_OPEN_IN_SOME_WINDOW
);
771 else if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_OWNWINDOW
) == BST_CHECKED
)
772 lpFolderIconName
= MAKEINTRESOURCE(IDI_SHELL_OPEN_IN_NEW_WINDOW
);
774 if (lpFolderIconName
)
776 hFolderIcon
= (HICON
)LoadImage(shell32_hInstance
,
784 hwndFolderIcon
= GetDlgItem(hDlg
,
785 IDC_FOLDER_OPTIONS_FOLDERICON
);
788 SendMessage(hwndFolderIcon
,
791 (LPARAM
)hFolderIcon
);
796 // Show click setting icon
797 if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_SINGLECLICK
) == BST_CHECKED
)
798 lpClickIconName
= MAKEINTRESOURCE(IDI_SHELL_SINGLE_CLICK_TO_OPEN
);
799 else if(IsDlgButtonChecked(hDlg
, IDC_FOLDER_OPTIONS_DOUBLECLICK
) == BST_CHECKED
)
800 lpClickIconName
= MAKEINTRESOURCE(IDI_SHELL_DOUBLE_CLICK_TO_OPEN
);
804 hClickIcon
= (HICON
)LoadImage(shell32_hInstance
,
812 hwndClickIcon
= GetDlgItem(hDlg
,
813 IDC_FOLDER_OPTIONS_CLICKICON
);
816 SendMessage(hwndClickIcon
,
826 DeleteObject(hTaskIcon
);
828 DeleteObject(hFolderIcon
);
830 DeleteObject(hClickIcon
);
837 FolderOptionsGeneralDlg(
851 switch (LOWORD(wParam
))
853 case IDC_FOLDER_OPTIONS_COMMONTASKS
:
854 case IDC_FOLDER_OPTIONS_CLASSICFOLDERS
:
855 case IDC_FOLDER_OPTIONS_SAMEWINDOW
:
856 case IDC_FOLDER_OPTIONS_OWNWINDOW
:
857 case IDC_FOLDER_OPTIONS_SINGLECLICK
:
858 case IDC_FOLDER_OPTIONS_DOUBLECLICK
:
859 if (HIWORD(wParam
) == BN_CLICKED
)
861 UpdateGeneralIcons(hwndDlg
);
863 /* Enable the 'Apply' button */
864 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
872 LPNMHDR pnmh
= (LPNMHDR
)lParam
;
895 ViewDlg_OnInitDialog(HWND hwndDlg
)
897 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
899 s_hImageList
= CreateTreeImageList();
900 TreeView_SetImageList(hwndTreeView
, s_hImageList
, TVSIL_NORMAL
);
904 Advanced_InsertAll(hwndTreeView
);
906 return TRUE
; // set focus
910 ViewDlg_ToggleCheckItem(HWND hwndDlg
, HTREEITEM hItem
)
912 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
917 ZeroMemory(&Item
, sizeof(Item
));
918 Item
.mask
= TVIF_HANDLE
| TVIF_IMAGE
| TVIF_PARAM
;
920 if (!TreeView_GetItem(hwndTreeView
, &Item
))
921 return FALSE
; // no such item
923 ADVANCED_ENTRY
*pEntry
= Advanced_GetItem(Item
.lParam
);
925 return FALSE
; // no such item
927 return FALSE
; // disabled
930 Item
.mask
= TVIF_HANDLE
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
931 switch (pEntry
->dwType
)
933 case AETYPE_CHECKBOX
:
934 pEntry
->bChecked
= !pEntry
->bChecked
;
937 // reset all the entries of the same parent
938 for (i
= 0; i
< s_AdvancedCount
; ++i
)
940 ADVANCED_ENTRY
*pEntry2
= &s_Advanced
[i
];
941 if (pEntry
->dwParentID
== pEntry2
->dwParentID
)
943 pEntry2
->bChecked
= FALSE
;
945 Item
.hItem
= pEntry2
->hItem
;
946 INT iImage
= Advanced_GetImage(pEntry2
);
947 Item
.iImage
= Item
.iSelectedImage
= iImage
;
948 TreeView_SetItem(hwndTreeView
, &Item
);
951 pEntry
->bChecked
= TRUE
;
954 return FALSE
; // failure
956 Item
.iImage
= Item
.iSelectedImage
= Advanced_GetImage(pEntry
);
958 TreeView_SetItem(hwndTreeView
, &Item
);
962 TreeView_GetItemRect(hwndTreeView
, hItem
, &rcItem
, FALSE
);
963 InvalidateRect(hwndTreeView
, &rcItem
, TRUE
);
964 return TRUE
; // success
968 ViewDlg_OnTreeViewClick(HWND hwndDlg
)
970 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
972 // do hit test to get the clicked item
973 TV_HITTESTINFO HitTest
;
974 ZeroMemory(&HitTest
, sizeof(HitTest
));
975 DWORD dwPos
= GetMessagePos();
976 HitTest
.pt
.x
= LOWORD(dwPos
);
977 HitTest
.pt
.y
= HIWORD(dwPos
);
978 ScreenToClient(hwndTreeView
, &HitTest
.pt
);
979 HTREEITEM hItem
= TreeView_HitTest(hwndTreeView
, &HitTest
);
981 // toggle the check mark if possible
982 if (ViewDlg_ToggleCheckItem(hwndDlg
, hItem
))
984 // property sheet was changed
985 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
990 ViewDlg_OnTreeViewKeyDown(HWND hwndDlg
, TV_KEYDOWN
*KeyDown
)
992 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
994 if (KeyDown
->wVKey
== VK_SPACE
)
996 // [Space] key was pressed
997 HTREEITEM hItem
= TreeView_GetSelection(hwndTreeView
);
998 if (ViewDlg_ToggleCheckItem(hwndDlg
, hItem
))
1000 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1006 ViewDlg_OnTreeCustomDraw(HWND hwndDlg
, NMTVCUSTOMDRAW
*Draw
)
1008 NMCUSTOMDRAW
& nmcd
= Draw
->nmcd
;
1009 switch (nmcd
.dwDrawStage
)
1012 return CDRF_NOTIFYITEMDRAW
; // for CDDS_ITEMPREPAINT
1014 case CDDS_ITEMPREPAINT
:
1015 if (!(nmcd
.uItemState
& CDIS_SELECTED
)) // not selected
1017 LPARAM lParam
= nmcd
.lItemlParam
;
1018 ADVANCED_ENTRY
*pEntry
= Advanced_GetItem(lParam
);
1019 if (pEntry
&& pEntry
->bGrayed
) // disabled
1022 Draw
->clrText
= GetSysColor(COLOR_GRAYTEXT
);
1023 Draw
->clrTextBk
= GetSysColor(COLOR_WINDOW
);
1024 return CDRF_NEWFONT
;
1032 return CDRF_DODEFAULT
;
1036 Advanced_RestoreDefaults(HWND hwndDlg
)
1038 HWND hwndTreeView
= GetDlgItem(hwndDlg
, 14003);
1040 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
1042 // ignore if the type is group
1043 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
1044 if (pEntry
->dwType
== AETYPE_GROUP
)
1047 // set default value on registry
1049 if (RegOpenKeyExW(HKEY(pEntry
->hkeyRoot
), pEntry
->szRegPath
,
1050 0, KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
1054 RegSetValueExW(hKey
, pEntry
->szValueName
, 0, REG_DWORD
,
1055 LPBYTE(pEntry
->dwDefaultValue
), sizeof(DWORD
));
1058 // update check status
1059 pEntry
->bChecked
= (pEntry
->dwCheckedValue
== pEntry
->dwDefaultValue
);
1063 ZeroMemory(&Item
, sizeof(Item
));
1064 Item
.mask
= TVIF_HANDLE
| TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
1065 Item
.hItem
= pEntry
->hItem
;
1066 Item
.iImage
= Item
.iSelectedImage
= Advanced_GetImage(pEntry
);
1067 TreeView_SetItem(hwndTreeView
, &Item
);
1070 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1073 /* FIXME: These macros should not be defined here */
1074 #ifndef SSF_SHOWSUPERHIDDEN
1075 #define SSF_SHOWSUPERHIDDEN 0x00040000
1077 #ifndef SSF_SEPPROCESS
1078 #define SSF_SEPPROCESS 0x00080000
1082 ScanAdvancedSettings(SHELLSTATE
*pSS
, DWORD
*pdwMask
)
1084 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
1086 const ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
1087 if (pEntry
->dwType
== AETYPE_GROUP
|| pEntry
->bGrayed
)
1090 BOOL bChecked
= pEntry
->bChecked
;
1092 // FIXME: Add more items
1093 if (lstrcmpiW(pEntry
->szKeyName
, L
"SuperHidden") == 0)
1095 pSS
->fShowSuperHidden
= !bChecked
? 1 : 0;
1096 *pdwMask
|= SSF_SHOWSUPERHIDDEN
;
1099 if (lstrcmpiW(pEntry
->szKeyName
, L
"DesktopProcess") == 0)
1101 pSS
->fSepProcess
= bChecked
? 1 : 0;
1102 *pdwMask
|= SSF_SEPPROCESS
;
1105 if (lstrcmpiW(pEntry
->szKeyName
, L
"SHOWALL") == 0)
1107 pSS
->fShowAllObjects
= !bChecked
? 1 : 0;
1108 *pdwMask
|= SSF_SHOWALLOBJECTS
;
1111 if (lstrcmpiW(pEntry
->szKeyName
, L
"HideFileExt") == 0)
1113 pSS
->fShowExtensions
= !bChecked
? 1 : 0;
1114 *pdwMask
|= SSF_SHOWEXTENSIONS
;
1117 if (lstrcmpiW(pEntry
->szKeyName
, L
"ShowCompColor") == 0)
1119 pSS
->fShowCompColor
= bChecked
? 1 : 0;
1120 *pdwMask
|= SSF_SHOWCOMPCOLOR
;
1123 if (lstrcmpiW(pEntry
->szKeyName
, L
"ShowInfoTip") == 0)
1125 pSS
->fShowInfoTip
= bChecked
? 1 : 0;
1126 *pdwMask
|= SSF_SHOWINFOTIP
;
1133 VOID WINAPI
SHGetSetSettings(LPSHELLSTATE lpss
, DWORD dwMask
, BOOL bSet
);
1135 static BOOL CALLBACK
RefreshBrowsersCallback (HWND hWnd
, LPARAM msg
)
1137 WCHAR ClassName
[100];
1138 if (GetClassName(hWnd
, ClassName
, 100))
1140 if (!wcscmp(ClassName
, L
"Progman") ||
1141 !wcscmp(ClassName
, L
"CabinetWClass") ||
1142 !wcscmp(ClassName
, L
"ExploreWClass"))
1144 PostMessage(hWnd
, WM_COMMAND
, FCIDM_DESKBROWSER_REFRESH
, 0);
1151 ViewDlg_Apply(HWND hwndDlg
)
1153 for (INT i
= 0; i
< s_AdvancedCount
; ++i
)
1155 // ignore the entry if the type is group or the entry is grayed
1156 ADVANCED_ENTRY
*pEntry
= &s_Advanced
[i
];
1157 if (pEntry
->dwType
== AETYPE_GROUP
|| pEntry
->bGrayed
)
1160 // open the registry key
1162 if (RegOpenKeyExW(HKEY(pEntry
->hkeyRoot
), pEntry
->szRegPath
, 0,
1163 KEY_WRITE
, &hkeyTarget
) != ERROR_SUCCESS
)
1168 // checked or unchecked?
1169 DWORD dwValue
, dwSize
;
1170 if (pEntry
->bChecked
)
1172 dwValue
= pEntry
->dwCheckedValue
;
1176 if (pEntry
->bHasUncheckedValue
)
1178 dwValue
= pEntry
->dwUncheckedValue
;
1182 // there is no unchecked value
1183 RegCloseKey(hkeyTarget
);
1189 dwSize
= sizeof(dwValue
);
1190 RegSetValueExW(hkeyTarget
, pEntry
->szValueName
, 0, REG_DWORD
,
1191 LPBYTE(&dwValue
), dwSize
);
1194 RegCloseKey(hkeyTarget
);
1197 // scan advanced settings for user's settings
1199 SHELLSTATE ShellState
;
1200 ZeroMemory(&ShellState
, sizeof(ShellState
));
1201 ScanAdvancedSettings(&ShellState
, &dwMask
);
1203 // update user's settings
1204 SHGetSetSettings(&ShellState
, dwMask
, TRUE
);
1207 SendMessage(HWND_BROADCAST
, WM_WININICHANGE
, 0, 0);
1209 EnumWindows(RefreshBrowsersCallback
, NULL
);
1213 FolderOptionsViewDlg(
1220 NMTVCUSTOMDRAW
*Draw
;
1225 return ViewDlg_OnInitDialog(hwndDlg
);
1227 switch (LOWORD(wParam
))
1229 case 14004: // Restore Defaults
1230 Advanced_RestoreDefaults(hwndDlg
);
1235 switch (LPNMHDR(lParam
)->code
)
1237 case NM_CLICK
: // clicked on treeview
1238 ViewDlg_OnTreeViewClick(hwndDlg
);
1240 case NM_CUSTOMDRAW
: // custom draw (for graying)
1241 Draw
= (NMTVCUSTOMDRAW
*)lParam
;
1242 Result
= ViewDlg_OnTreeCustomDraw(hwndDlg
, Draw
);
1243 SetWindowLongPtr(hwndDlg
, DWL_MSGRESULT
, Result
);
1245 case TVN_KEYDOWN
: // key is down
1246 ViewDlg_OnTreeViewKeyDown(hwndDlg
, (TV_KEYDOWN
*)lParam
);
1248 case PSN_APPLY
: // [Apply] is clicked
1249 ViewDlg_Apply(hwndDlg
);
1262 InitializeFileTypesListCtrlColumns(HWND hDlgCtrl
)
1268 int columnSize
= 140;
1271 if (!LoadStringW(shell32_hInstance
, IDS_COLUMN_EXTENSION
, szName
, sizeof(szName
) / sizeof(WCHAR
)))
1273 /* default to english */
1274 wcscpy(szName
, L
"Extensions");
1277 /* make sure its null terminated */
1278 szName
[(sizeof(szName
)/sizeof(WCHAR
))-1] = 0;
1280 GetClientRect(hDlgCtrl
, &clientRect
);
1281 ZeroMemory(&col
, sizeof(LV_COLUMN
));
1282 columnSize
= 140; //FIXME
1284 col
.mask
= LVCF_WIDTH
| LVCF_TEXT
| LVCF_SUBITEM
| LVCF_FMT
;
1285 col
.fmt
= LVCFMT_FIXED_WIDTH
;
1286 col
.cx
= columnSize
| LVCFMT_LEFT
;
1287 col
.cchTextMax
= wcslen(szName
);
1288 col
.pszText
= szName
;
1289 (void)SendMessageW(hDlgCtrl
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&col
);
1291 if (!LoadStringW(shell32_hInstance
, IDS_FILE_TYPES
, szName
, sizeof(szName
) / sizeof(WCHAR
)))
1293 /* default to english */
1294 wcscpy(szName
, L
"File Types");
1295 ERR("Failed to load localized string!\n");
1299 col
.cx
= clientRect
.right
- clientRect
.left
- columnSize
;
1300 col
.cchTextMax
= wcslen(szName
);
1301 col
.pszText
= szName
;
1302 (void)SendMessageW(hDlgCtrl
, LVM_INSERTCOLUMNW
, 1, (LPARAM
)&col
);
1304 /* set full select style */
1305 dwStyle
= (DWORD
) SendMessage(hDlgCtrl
, LVM_GETEXTENDEDLISTVIEWSTYLE
, 0, 0);
1306 dwStyle
= dwStyle
| LVS_EX_FULLROWSELECT
;
1307 SendMessage(hDlgCtrl
, LVM_SETEXTENDEDLISTVIEWSTYLE
, 0, dwStyle
);
1311 FindItem(HWND hDlgCtrl
, WCHAR
* ItemName
)
1313 LVFINDINFOW findInfo
;
1314 ZeroMemory(&findInfo
, sizeof(LVFINDINFOW
));
1316 findInfo
.flags
= LVFI_STRING
;
1317 findInfo
.psz
= ItemName
;
1318 return ListView_FindItem(hDlgCtrl
, 0, &findInfo
);
1323 InsertFileType(HWND hDlgCtrl
, WCHAR
* szName
, PINT iItem
, WCHAR
* szFile
)
1325 PFOLDER_FILE_TYPE_ENTRY Entry
;
1331 if (szName
[0] != L
'.')
1333 /* FIXME handle URL protocol handlers */
1337 /* allocate file type entry */
1338 Entry
= (PFOLDER_FILE_TYPE_ENTRY
)HeapAlloc(GetProcessHeap(), 0, sizeof(FOLDER_FILE_TYPE_ENTRY
));
1344 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, szName
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
1346 HeapFree(GetProcessHeap(), 0, Entry
);
1350 /* FIXME check for duplicates */
1352 /* query for the default key */
1353 dwSize
= sizeof(Entry
->ClassKey
);
1354 if (RegQueryValueExW(hKey
, NULL
, NULL
, NULL
, (LPBYTE
)Entry
->ClassKey
, &dwSize
) != ERROR_SUCCESS
)
1356 /* no link available */
1357 Entry
->ClassKey
[0] = 0;
1360 if (Entry
->ClassKey
[0])
1363 /* try open linked key */
1364 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, Entry
->ClassKey
, 0, KEY_READ
, &hTemp
) == ERROR_SUCCESS
)
1366 /* use linked key */
1372 /* read friendly type name */
1373 if (RegLoadMUIStringW(hKey
, L
"FriendlyTypeName", Entry
->FileDescription
, sizeof(Entry
->FileDescription
), NULL
, 0, NULL
) != ERROR_SUCCESS
)
1375 /* read file description */
1376 dwSize
= sizeof(Entry
->FileDescription
);
1377 Entry
->FileDescription
[0] = 0;
1379 /* read default key */
1380 RegQueryValueExW(hKey
, NULL
, NULL
, NULL
, (LPBYTE
)Entry
->FileDescription
, &dwSize
);
1383 /* Read the EditFlags value */
1384 Entry
->EditFlags
= 0;
1385 if (!RegQueryValueExW(hKey
, L
"EditFlags", NULL
, &dwType
, NULL
, &dwSize
))
1387 if ((dwType
== REG_DWORD
|| dwType
== REG_BINARY
) && dwSize
== sizeof(DWORD
))
1388 RegQueryValueExW(hKey
, L
"EditFlags", NULL
, NULL
, (LPBYTE
)&Entry
->EditFlags
, &dwSize
);
1394 /* Do not add excluded entries */
1395 if (Entry
->EditFlags
& 0x00000001) //FTA_Exclude
1397 HeapFree(GetProcessHeap(), 0, Entry
);
1401 /* convert extension to upper case */
1402 wcscpy(Entry
->FileExtension
, szName
);
1403 _wcsupr(Entry
->FileExtension
);
1405 if (!Entry
->FileDescription
[0])
1407 /* construct default 'FileExtensionFile' by formatting the uppercase extension
1408 with IDS_FILE_EXT_TYPE, outputting something like a l18n 'INI File' */
1410 StringCchPrintf(Entry
->FileDescription
, _countof(Entry
->FileDescription
), szFile
, &Entry
->FileExtension
[1]);
1413 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
1414 lvItem
.mask
= LVIF_TEXT
| LVIF_PARAM
;
1415 lvItem
.iSubItem
= 0;
1416 lvItem
.pszText
= &Entry
->FileExtension
[1];
1417 lvItem
.iItem
= *iItem
;
1418 lvItem
.lParam
= (LPARAM
)Entry
;
1419 (void)SendMessageW(hDlgCtrl
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
);
1421 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
1422 lvItem
.mask
= LVIF_TEXT
;
1423 lvItem
.pszText
= Entry
->FileDescription
;
1424 lvItem
.iItem
= *iItem
;
1425 lvItem
.iSubItem
= 1;
1426 ListView_SetItem(hDlgCtrl
, &lvItem
);
1434 ListViewCompareProc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
1436 PFOLDER_FILE_TYPE_ENTRY Entry1
, Entry2
;
1439 Entry1
= (PFOLDER_FILE_TYPE_ENTRY
)lParam1
;
1440 Entry2
= (PFOLDER_FILE_TYPE_ENTRY
)lParam2
;
1442 x
= wcsicmp(Entry1
->FileExtension
, Entry2
->FileExtension
);
1446 return wcsicmp(Entry1
->FileDescription
, Entry2
->FileDescription
);
1450 PFOLDER_FILE_TYPE_ENTRY
1451 InitializeFileTypesListCtrl(HWND hwndDlg
)
1461 hDlgCtrl
= GetDlgItem(hwndDlg
, 14000);
1462 InitializeFileTypesListCtrlColumns(hDlgCtrl
);
1465 if (!LoadStringW(shell32_hInstance
, IDS_FILE_EXT_TYPE
, szFile
, _countof(szFile
)))
1467 /* default to english */
1468 wcscpy(szFile
, L
"%s File");
1470 szFile
[(_countof(szFile
)) - 1] = 0;
1472 dwName
= _countof(szName
);
1474 while (RegEnumKeyExW(HKEY_CLASSES_ROOT
, dwIndex
++, szName
, &dwName
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
1476 InsertFileType(hDlgCtrl
, szName
, &iItem
, szFile
);
1477 dwName
= _countof(szName
);
1480 /* Leave if the list is empty */
1485 ListView_SortItems(hDlgCtrl
, ListViewCompareProc
, NULL
);
1487 /* select first item */
1488 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
1489 lvItem
.mask
= LVIF_STATE
;
1490 lvItem
.stateMask
= (UINT
)-1;
1491 lvItem
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
1493 ListView_SetItem(hDlgCtrl
, &lvItem
);
1495 lvItem
.mask
= LVIF_PARAM
;
1496 ListView_GetItem(hDlgCtrl
, &lvItem
);
1498 return (PFOLDER_FILE_TYPE_ENTRY
)lvItem
.lParam
;
1502 PFOLDER_FILE_TYPE_ENTRY
1509 Count
= ListView_GetItemCount(hDlgCtrl
);
1511 for (Index
= 0; Index
< Count
; Index
++)
1513 ZeroMemory(&lvItem
, sizeof(LVITEM
));
1514 lvItem
.mask
= LVIF_PARAM
| LVIF_STATE
;
1515 lvItem
.iItem
= Index
;
1516 lvItem
.stateMask
= (UINT
) - 1;
1518 if (ListView_GetItem(hDlgCtrl
, &lvItem
))
1520 if (lvItem
.state
& LVIS_SELECTED
)
1521 return (PFOLDER_FILE_TYPE_ENTRY
)lvItem
.lParam
;
1530 FolderOptionsFileTypesDlg(
1538 WCHAR Buffer
[255], FormatBuffer
[255];
1539 PFOLDER_FILE_TYPE_ENTRY pItem
;
1545 pItem
= InitializeFileTypesListCtrl(hwndDlg
);
1547 /* Disable the Delete button if the listview is empty or
1548 the selected item should not be deleted by the user */
1549 if (pItem
== NULL
|| (pItem
->EditFlags
& 0x00000010)) // FTA_NoRemove
1550 EnableWindow(GetDlgItem(hwndDlg
, 14002), FALSE
);
1554 switch(LOWORD(wParam
))
1557 pItem
= FindSelectedItem(GetDlgItem(hwndDlg
, 14000));
1560 Info
.oaifInFlags
= OAIF_ALLOW_REGISTRATION
| OAIF_REGISTER_EXT
;
1561 Info
.pcszClass
= pItem
->FileExtension
;
1562 SHOpenWithDialog(hwndDlg
, &Info
);
1569 lppl
= (LPNMLISTVIEW
) lParam
;
1571 if (lppl
->hdr
.code
== LVN_ITEMCHANGING
)
1573 ZeroMemory(&lvItem
, sizeof(LVITEM
));
1574 lvItem
.mask
= LVIF_PARAM
;
1575 lvItem
.iItem
= lppl
->iItem
;
1576 if (!SendMessageW(lppl
->hdr
.hwndFrom
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
))
1579 pItem
= (PFOLDER_FILE_TYPE_ENTRY
)lvItem
.lParam
;
1583 if (!(lppl
->uOldState
& LVIS_FOCUSED
) && (lppl
->uNewState
& LVIS_FOCUSED
))
1585 /* new focused item */
1586 if (!LoadStringW(shell32_hInstance
, IDS_FILE_DETAILS
, FormatBuffer
, sizeof(FormatBuffer
) / sizeof(WCHAR
)))
1588 /* use default english format string */
1589 wcscpy(FormatBuffer
, L
"Details for '%s' extension");
1593 swprintf(Buffer
, FormatBuffer
, &pItem
->FileExtension
[1]);
1595 SetDlgItemTextW(hwndDlg
, 14003, Buffer
);
1597 if (!LoadStringW(shell32_hInstance
, IDS_FILE_DETAILSADV
, FormatBuffer
, sizeof(FormatBuffer
) / sizeof(WCHAR
)))
1599 /* use default english format string */
1600 wcscpy(FormatBuffer
, L
"Files with extension '%s' are of type '%s'. To change settings that affect all '%s' files, click Advanced.");
1603 swprintf(Buffer
, FormatBuffer
, &pItem
->FileExtension
[1], &pItem
->FileDescription
[0], &pItem
->FileDescription
[0]);
1605 SetDlgItemTextW(hwndDlg
, 14007, Buffer
);
1607 /* Enable the Delete button */
1608 if (pItem
->EditFlags
& 0x00000010) // FTA_NoRemove
1609 EnableWindow(GetDlgItem(hwndDlg
, 14002), FALSE
);
1611 EnableWindow(GetDlgItem(hwndDlg
, 14002), TRUE
);
1614 else if (lppl
->hdr
.code
== PSN_SETACTIVE
)
1616 /* On page activation, set the focus to the listview */
1617 SetFocus(GetDlgItem(hwndDlg
, 14000));
1627 ShowFolderOptionsDialog(HWND hWnd
, HINSTANCE hInst
)
1629 PROPSHEETHEADERW pinfo
;
1630 HPROPSHEETPAGE hppages
[3];
1631 HPROPSHEETPAGE hpage
;
1633 WCHAR szOptions
[100];
1635 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_GENERAL
, FolderOptionsGeneralDlg
, 0, NULL
);
1637 hppages
[num_pages
++] = hpage
;
1639 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_VIEW
, FolderOptionsViewDlg
, 0, NULL
);
1641 hppages
[num_pages
++] = hpage
;
1643 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_FILETYPES
, FolderOptionsFileTypesDlg
, 0, NULL
);
1645 hppages
[num_pages
++] = hpage
;
1647 szOptions
[0] = L
'\0';
1648 LoadStringW(shell32_hInstance
, IDS_FOLDER_OPTIONS
, szOptions
, sizeof(szOptions
) / sizeof(WCHAR
));
1649 szOptions
[(sizeof(szOptions
)/sizeof(WCHAR
))-1] = L
'\0';
1651 memset(&pinfo
, 0x0, sizeof(PROPSHEETHEADERW
));
1652 pinfo
.dwSize
= sizeof(PROPSHEETHEADERW
);
1653 pinfo
.dwFlags
= PSH_NOCONTEXTHELP
;
1654 pinfo
.nPages
= num_pages
;
1655 pinfo
.phpage
= hppages
;
1656 pinfo
.pszCaption
= szOptions
;
1658 PropertySheetW(&pinfo
);
1663 Options_RunDLLCommon(HWND hWnd
, HINSTANCE hInst
, int fOptions
, DWORD nCmdShow
)
1668 ShowFolderOptionsDialog(hWnd
, hInst
);
1671 // show taskbar options dialog
1672 FIXME("notify explorer to show taskbar options dialog");
1673 //PostMessage(GetShellWindow(), WM_USER+22, fOptions, 0);
1676 FIXME("unrecognized options id %d\n", fOptions
);
1680 /*************************************************************************
1681 * Options_RunDLL (SHELL32.@)
1683 EXTERN_C VOID WINAPI
Options_RunDLL(HWND hWnd
, HINSTANCE hInst
, LPCSTR cmd
, DWORD nCmdShow
)
1685 Options_RunDLLCommon(hWnd
, hInst
, StrToIntA(cmd
), nCmdShow
);
1688 /*************************************************************************
1689 * Options_RunDLLA (SHELL32.@)
1691 EXTERN_C VOID WINAPI
Options_RunDLLA(HWND hWnd
, HINSTANCE hInst
, LPCSTR cmd
, DWORD nCmdShow
)
1693 Options_RunDLLCommon(hWnd
, hInst
, StrToIntA(cmd
), nCmdShow
);
1696 /*************************************************************************
1697 * Options_RunDLLW (SHELL32.@)
1699 EXTERN_C VOID WINAPI
Options_RunDLLW(HWND hWnd
, HINSTANCE hInst
, LPCWSTR cmd
, DWORD nCmdShow
)
1701 Options_RunDLLCommon(hWnd
, hInst
, StrToIntW(cmd
), nCmdShow
);