2 * Open With Context Menu extension
4 * Copyright 2007 Johannes Anderwald <johannes.anderwald@reactos.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 WINE_DEFAULT_DEBUG_CHANNEL (fprop
);
25 #define MAX_PROPERTY_SHEET_PAGE (32)
28 /// CLASSKEY = HKEY_CLASSES_ROOT\CLSID\{6DFD7C5C-2451-11d3-A299-00C04F8EF6AF}
29 /// DefaultIcon = %SystemRoot%\system32\SHELL32.dll,-210
30 /// Verbs: Open / RunAs
31 /// Cmd: rundll32.exe shell32.dll,Options_RunDLL 0
33 /// ShellFolder Attributes: 0x0
37 WCHAR FileExtension
[30];
38 WCHAR FileDescription
[100];
39 WCHAR ClassKey
[MAX_PATH
];
40 } FOLDER_FILE_TYPE_ENTRY
, *PFOLDER_FILE_TYPE_ENTRY
;
46 } FOLDER_VIEW_ENTRY
, PFOLDER_VIEW_ENTRY
;
48 static FOLDER_VIEW_ENTRY s_Options[] =
50 { L"AlwaysShowMenus", IDS_ALWAYSSHOWMENUS },
51 { L"AutoCheckSelect", -1 },
52 { L"ClassicViewState", -1 },
53 { L"DontPrettyPath", -1 },
55 { L"FolderContentsInfoTip", IDS_FOLDERCONTENTSTIP },
56 { L"FriendlyTree", -1 },
58 { L"HideFileExt", IDS_HIDEFILEEXT },
61 { L"ListviewAlphaSelect", -1},
62 { L"ListviewShadow", -1},
63 { L"ListviewWatermark", -1},
64 { L"MapNetDrvBtn", -1},
65 { L"PersistBrowsers", -1},
66 { L"SeperateProcess", IDS_SEPERATEPROCESS},
67 { L"ServerAdminUI", -1},
68 { L"SharingWizardOn", IDS_USESHAREWIZARD},
69 { L"ShowCompColor", IDS_COMPCOLOR},
70 { L"ShowInfoTip", IDS_SHOWINFOTIP},
71 { L"ShowPreviewHandlers", -1},
72 { L"ShowSuperHidden", IDS_HIDEOSFILES},
73 { L"ShowTypeOverlay", -1},
74 { L"Start_ShowMyGames", -1},
75 { L"StartMenuInit", -1},
76 { L"SuperHidden", -1},
84 EXTERN_C HPSXA WINAPI
SHCreatePropSheetExtArrayEx(HKEY hKey
, LPCWSTR pszSubKey
, UINT max_iface
, IDataObject
*pDataObj
);
88 FolderOptionsGeneralDlg(
100 InitializeFolderOptionsListCtrl(HWND hwndDlg
)
107 hDlgCtrl
= GetDlgItem(hwndDlg
, 14003);
109 if (!LoadStringW(shell32_hInstance
, IDS_COLUMN_EXTENSION
, szName
, sizeof(szName
) / sizeof(WCHAR
)))
111 szName
[(sizeof(szName
)/sizeof(WCHAR
))-1] = 0;
113 GetClientRect(hDlgCtrl
, &clientRect
);
114 ZeroMemory(&col
, sizeof(LV_COLUMN
));
115 col
.mask
= LVCF_SUBITEM
| LVCF_WIDTH
| LVCF_FMT
;
117 col
.pszText
= szName
;
118 col
.fmt
= LVCFMT_LEFT
;
119 col
.cx
= (clientRect
.right
- clientRect
.left
) - GetSystemMetrics(SM_CXVSCROLL
);
120 (void)SendMessageW(hDlgCtrl
, LVM_INSERTCOLUMN
, 0, (LPARAM
)&col
);
128 FolderOptionsViewDlg(
138 InitializeFolderOptionsListCtrl(hwndDlg
);
148 InitializeFileTypesListCtrlColumns(HWND hDlgCtrl
)
154 int columnSize
= 140;
157 if (!LoadStringW(shell32_hInstance
, IDS_COLUMN_EXTENSION
, szName
, sizeof(szName
) / sizeof(WCHAR
)))
159 /* default to english */
160 wcscpy(szName
, L
"Extensions");
163 /* make sure its null terminated */
164 szName
[(sizeof(szName
)/sizeof(WCHAR
))-1] = 0;
166 GetClientRect(hDlgCtrl
, &clientRect
);
167 ZeroMemory(&col
, sizeof(LV_COLUMN
));
168 columnSize
= 140; //FIXME
170 col
.mask
= LVCF_WIDTH
| LVCF_TEXT
| LVCF_SUBITEM
| LVCF_FMT
;
171 col
.fmt
= LVCFMT_FIXED_WIDTH
;
172 col
.cx
= columnSize
| LVCFMT_LEFT
;
173 col
.cchTextMax
= wcslen(szName
);
174 col
.pszText
= szName
;
175 (void)SendMessageW(hDlgCtrl
, LVM_INSERTCOLUMNW
, 0, (LPARAM
)&col
);
177 if (!LoadStringW(shell32_hInstance
, IDS_FILE_TYPES
, szName
, sizeof(szName
) / sizeof(WCHAR
)))
179 /* default to english */
180 wcscpy(szName
, L
"FileTypes");
184 col
.cx
= clientRect
.right
- clientRect
.left
- columnSize
;
185 col
.cchTextMax
= wcslen(szName
);
186 col
.pszText
= szName
;
187 (void)SendMessageW(hDlgCtrl
, LVM_INSERTCOLUMNW
, 1, (LPARAM
)&col
);
189 /* set full select style */
190 dwStyle
= (DWORD
) SendMessage(hDlgCtrl
, LVM_GETEXTENDEDLISTVIEWSTYLE
, 0, 0);
191 dwStyle
= dwStyle
| LVS_EX_FULLROWSELECT
;
192 SendMessage(hDlgCtrl
, LVM_SETEXTENDEDLISTVIEWSTYLE
, 0, dwStyle
);
196 FindItem(HWND hDlgCtrl
, WCHAR
* ItemName
)
198 LVFINDINFOW findInfo
;
199 ZeroMemory(&findInfo
, sizeof(LVFINDINFOW
));
201 findInfo
.flags
= LVFI_STRING
;
202 findInfo
.psz
= ItemName
;
203 return ListView_FindItem(hDlgCtrl
, 0, &findInfo
);
208 InsertFileType(HWND hDlgCtrl
, WCHAR
* szName
, PINT iItem
, WCHAR
* szFile
)
210 PFOLDER_FILE_TYPE_ENTRY Entry
;
215 if (szName
[0] != L
'.')
217 /* FIXME handle URL protocol handlers */
221 /* allocate file type entry */
222 Entry
= (PFOLDER_FILE_TYPE_ENTRY
)HeapAlloc(GetProcessHeap(), 0, sizeof(FOLDER_FILE_TYPE_ENTRY
));
228 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, szName
, 0, KEY_READ
, &hKey
) != ERROR_SUCCESS
)
230 HeapFree(GetProcessHeap(), 0, Entry
);
234 /* FIXME check for duplicates */
236 /* query for the default key */
237 dwSize
= sizeof(Entry
->ClassKey
);
238 if (RegQueryValueExW(hKey
, NULL
, NULL
, NULL
, (LPBYTE
)Entry
->ClassKey
, &dwSize
) != ERROR_SUCCESS
)
240 /* no link available */
241 Entry
->ClassKey
[0] = 0;
244 if (Entry
->ClassKey
[0])
247 /* try open linked key */
248 if (RegOpenKeyExW(HKEY_CLASSES_ROOT
, Entry
->ClassKey
, 0, KEY_READ
, &hTemp
) == ERROR_SUCCESS
)
256 /* read friendly type name */
257 if (RegLoadMUIStringW(hKey
, L
"FriendlyTypeName", Entry
->FileDescription
, sizeof(Entry
->FileDescription
), NULL
, 0, NULL
) != ERROR_SUCCESS
)
259 /* read file description */
260 dwSize
= sizeof(Entry
->FileDescription
);
261 Entry
->FileDescription
[0] = 0;
263 /* read default key */
264 RegQueryValueExW(hKey
, NULL
, NULL
, NULL
, (LPBYTE
)Entry
->FileDescription
, &dwSize
);
270 /* convert extension to upper case */
271 wcscpy(Entry
->FileExtension
, szName
);
272 _wcsupr(Entry
->FileExtension
);
274 if (!Entry
->FileDescription
[0])
276 /* construct default 'FileExtensionFile' by formatting the uppercase extension
277 with IDS_FILE_EXT_TYPE, outputting something like a l18n 'INI File' */
279 StringCchPrintf(Entry
->FileDescription
, _countof(Entry
->FileDescription
), szFile
, &Entry
->FileExtension
[1]);
282 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
283 lvItem
.mask
= LVIF_TEXT
| LVIF_PARAM
;
285 lvItem
.pszText
= &Entry
->FileExtension
[1];
286 lvItem
.iItem
= *iItem
;
287 lvItem
.lParam
= (LPARAM
)Entry
;
288 (void)SendMessageW(hDlgCtrl
, LVM_INSERTITEMW
, 0, (LPARAM
)&lvItem
);
290 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
291 lvItem
.mask
= LVIF_TEXT
;
292 lvItem
.pszText
= Entry
->FileDescription
;
293 lvItem
.iItem
= *iItem
;
296 (void)SendMessageW(hDlgCtrl
, LVM_SETITEMW
, 0, (LPARAM
)&lvItem
);
303 ListViewCompareProc(LPARAM lParam1
, LPARAM lParam2
, LPARAM lParamSort
)
305 PFOLDER_FILE_TYPE_ENTRY Entry1
, Entry2
;
307 Entry1
= (PFOLDER_FILE_TYPE_ENTRY
)lParam1
;
308 Entry2
= (PFOLDER_FILE_TYPE_ENTRY
)lParam2
;
310 return wcsicmp(Entry1
->FileExtension
, Entry2
->FileExtension
);
315 InitializeFileTypesListCtrl(HWND hwndDlg
)
325 hDlgCtrl
= GetDlgItem(hwndDlg
, 14000);
326 InitializeFileTypesListCtrlColumns(hDlgCtrl
);
329 if (!LoadStringW(shell32_hInstance
, IDS_FILE_EXT_TYPE
, szFile
, _countof(szFile
)))
331 /* default to english */
332 wcscpy(szFile
, L
"%s File");
334 szFile
[(_countof(szFile
))-1] = 0;
336 dwName
= _countof(szName
);
338 while(RegEnumKeyExW(HKEY_CLASSES_ROOT
, dwIndex
++, szName
, &dwName
, NULL
, NULL
, NULL
, NULL
) == ERROR_SUCCESS
)
340 InsertFileType(hDlgCtrl
, szName
, &iItem
, szFile
);
341 dwName
= _countof(szName
);
345 ListView_SortItems(hDlgCtrl
, ListViewCompareProc
, NULL
);
347 /* select first item */
348 ZeroMemory(&lvItem
, sizeof(LVITEMW
));
349 lvItem
.mask
= LVIF_STATE
;
350 lvItem
.stateMask
= (UINT
) - 1;
351 lvItem
.state
= LVIS_FOCUSED
| LVIS_SELECTED
;
353 (void)SendMessageW(hDlgCtrl
, LVM_SETITEMW
, 0, (LPARAM
)&lvItem
);
359 PFOLDER_FILE_TYPE_ENTRY
366 Count
= ListView_GetItemCount(hDlgCtrl
);
368 for (Index
= 0; Index
< Count
; Index
++)
370 ZeroMemory(&lvItem
, sizeof(LVITEM
));
371 lvItem
.mask
= LVIF_PARAM
| LVIF_STATE
;
372 lvItem
.iItem
= Index
;
373 lvItem
.stateMask
= (UINT
) - 1;
375 if (ListView_GetItem(hDlgCtrl
, &lvItem
))
377 if (lvItem
.state
& LVIS_SELECTED
)
378 return (PFOLDER_FILE_TYPE_ENTRY
)lvItem
.lParam
;
387 FolderOptionsFileTypesDlg(
396 WCHAR Buffer
[255], FormatBuffer
[255];
397 PFOLDER_FILE_TYPE_ENTRY pItem
;
403 InitializeFileTypesListCtrl(hwndDlg
);
406 switch(LOWORD(wParam
))
409 pItem
= FindSelectedItem(GetDlgItem(hwndDlg
, 14000));
412 Info
.oaifInFlags
= OAIF_ALLOW_REGISTRATION
| OAIF_REGISTER_EXT
;
413 Info
.pcszClass
= pItem
->FileExtension
;
414 SHOpenWithDialog(hwndDlg
, &Info
);
421 lppl
= (LPNMLISTVIEW
) lParam
;
423 if (lppl
->hdr
.code
== LVN_ITEMCHANGING
)
425 ZeroMemory(&lvItem
, sizeof(LVITEM
));
426 lvItem
.mask
= LVIF_PARAM
;
427 lvItem
.iItem
= lppl
->iItem
;
428 if (!SendMessageW(lppl
->hdr
.hwndFrom
, LVM_GETITEMW
, 0, (LPARAM
)&lvItem
))
431 pItem
= (PFOLDER_FILE_TYPE_ENTRY
)lvItem
.lParam
;
435 if (!(lppl
->uOldState
& LVIS_FOCUSED
) && (lppl
->uNewState
& LVIS_FOCUSED
))
437 /* new focused item */
438 if (!LoadStringW(shell32_hInstance
, IDS_FILE_DETAILS
, FormatBuffer
, sizeof(FormatBuffer
) / sizeof(WCHAR
)))
440 /* use default english format string */
441 wcscpy(FormatBuffer
, L
"Details for '%s' extension");
445 swprintf(Buffer
, FormatBuffer
, &pItem
->FileExtension
[1]);
447 SetDlgItemTextW(hwndDlg
, 14003, Buffer
);
449 if (!LoadStringW(shell32_hInstance
, IDS_FILE_DETAILSADV
, FormatBuffer
, sizeof(FormatBuffer
) / sizeof(WCHAR
)))
451 /* use default english format string */
452 wcscpy(FormatBuffer
, L
"Files with extension '%s' are of type '%s'. To change settings that affect all '%s' files, click Advanced.");
455 swprintf(Buffer
, FormatBuffer
, &pItem
->FileExtension
[1], &pItem
->FileDescription
[0], &pItem
->FileDescription
[0]);
457 SetDlgItemTextW(hwndDlg
, 14007, Buffer
);
468 ShowFolderOptionsDialog(HWND hWnd
, HINSTANCE hInst
)
470 PROPSHEETHEADERW pinfo
;
471 HPROPSHEETPAGE hppages
[3];
472 HPROPSHEETPAGE hpage
;
474 WCHAR szOptions
[100];
476 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_GENERAL
, FolderOptionsGeneralDlg
, 0, NULL
);
478 hppages
[num_pages
++] = hpage
;
480 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_VIEW
, FolderOptionsViewDlg
, 0, NULL
);
482 hppages
[num_pages
++] = hpage
;
484 hpage
= SH_CreatePropertySheetPage(IDD_FOLDER_OPTIONS_FILETYPES
, FolderOptionsFileTypesDlg
, 0, NULL
);
486 hppages
[num_pages
++] = hpage
;
488 szOptions
[0] = L
'\0';
489 LoadStringW(shell32_hInstance
, IDS_FOLDER_OPTIONS
, szOptions
, sizeof(szOptions
) / sizeof(WCHAR
));
490 szOptions
[(sizeof(szOptions
)/sizeof(WCHAR
))-1] = L
'\0';
492 memset(&pinfo
, 0x0, sizeof(PROPSHEETHEADERW
));
493 pinfo
.dwSize
= sizeof(PROPSHEETHEADERW
);
494 pinfo
.dwFlags
= PSH_NOCONTEXTHELP
;
495 pinfo
.nPages
= num_pages
;
496 pinfo
.phpage
= hppages
;
497 pinfo
.pszCaption
= szOptions
;
499 PropertySheetW(&pinfo
);
504 Options_RunDLLCommon(HWND hWnd
, HINSTANCE hInst
, int fOptions
, DWORD nCmdShow
)
509 ShowFolderOptionsDialog(hWnd
, hInst
);
512 // show taskbar options dialog
513 FIXME("notify explorer to show taskbar options dialog");
514 //PostMessage(GetShellWindow(), WM_USER+22, fOptions, 0);
517 FIXME("unrecognized options id %d\n", fOptions
);
521 /*************************************************************************
522 * Options_RunDLL (SHELL32.@)
524 EXTERN_C VOID WINAPI
Options_RunDLL(HWND hWnd
, HINSTANCE hInst
, LPCSTR cmd
, DWORD nCmdShow
)
526 Options_RunDLLCommon(hWnd
, hInst
, StrToIntA(cmd
), nCmdShow
);
529 /*************************************************************************
530 * Options_RunDLLA (SHELL32.@)
532 EXTERN_C VOID WINAPI
Options_RunDLLA(HWND hWnd
, HINSTANCE hInst
, LPCSTR cmd
, DWORD nCmdShow
)
534 Options_RunDLLCommon(hWnd
, hInst
, StrToIntA(cmd
), nCmdShow
);
537 /*************************************************************************
538 * Options_RunDLLW (SHELL32.@)
540 EXTERN_C VOID WINAPI
Options_RunDLLW(HWND hWnd
, HINSTANCE hInst
, LPCWSTR cmd
, DWORD nCmdShow
)
542 Options_RunDLLCommon(hWnd
, hInst
, StrToIntW(cmd
), nCmdShow
);