2 * Shell Library Functions
4 * Copyright 2005 Johannes Anderwald
5 * Copyright 2012 Rafal Harabien
6 * Copyright 2017 Katayama Hirofumi MZ
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #define MAX_PROPERTY_SHEET_PAGE 32
27 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
29 EXTERN_C HPSXA WINAPI
SHCreatePropSheetExtArrayEx(HKEY hKey
, LPCWSTR pszSubKey
, UINT max_iface
, IDataObject
*pDataObj
);
32 AddPropSheetPageCallback(HPROPSHEETPAGE hPage
, LPARAM lParam
)
34 PROPSHEETHEADERW
*pHeader
= (PROPSHEETHEADERW
*)lParam
;
36 if (pHeader
->nPages
< MAX_PROPERTY_SHEET_PAGE
)
38 pHeader
->phpage
[pHeader
->nPages
++] = hPage
;
46 LoadPropSheetHandlers(LPCWSTR pwszPath
, PROPSHEETHEADERW
*pHeader
, UINT cMaxPages
, HPSXA
*phpsxa
, IDataObject
*pDataObj
)
48 WCHAR wszBuf
[MAX_PATH
];
49 UINT cPages
= 0, i
= 0;
51 LPWSTR pwszFilename
= PathFindFileNameW(pwszPath
);
52 BOOL bDir
= PathIsDirectoryW(pwszPath
);
56 phpsxa
[i
] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, L
"Folder", cMaxPages
- cPages
, pDataObj
);
57 cPages
+= SHAddFromPropSheetExtArray(phpsxa
[i
++], AddPropSheetPageCallback
, (LPARAM
)pHeader
);
59 phpsxa
[i
] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, L
"Directory", cMaxPages
- cPages
, pDataObj
);
60 cPages
+= SHAddFromPropSheetExtArray(phpsxa
[i
++], AddPropSheetPageCallback
, (LPARAM
)pHeader
);
64 /* Load property sheet handlers from ext key */
65 LPWSTR pwszExt
= PathFindExtensionW(pwszFilename
);
66 phpsxa
[i
] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, pwszExt
, cMaxPages
- cPages
, pDataObj
);
67 cPages
+= SHAddFromPropSheetExtArray(phpsxa
[i
++], AddPropSheetPageCallback
, (LPARAM
)pHeader
);
69 /* Load property sheet handlers from prog id key */
70 DWORD cbBuf
= sizeof(wszBuf
);
71 if (RegGetValueW(HKEY_CLASSES_ROOT
, pwszExt
, L
"", RRF_RT_REG_SZ
, NULL
, wszBuf
, &cbBuf
) == ERROR_SUCCESS
)
73 TRACE("EnumPropSheetExt wszBuf %s, pwszExt %s\n", debugstr_w(wszBuf
), debugstr_w(pwszExt
));
74 phpsxa
[i
] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, wszBuf
, cMaxPages
- cPages
, pDataObj
);
75 cPages
+= SHAddFromPropSheetExtArray(phpsxa
[i
++], AddPropSheetPageCallback
, (LPARAM
)pHeader
);
78 /* Add property sheet handlers from "*" key */
79 phpsxa
[i
] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, L
"*", cMaxPages
- cPages
, pDataObj
);
80 cPages
+= SHAddFromPropSheetExtArray(phpsxa
[i
++], AddPropSheetPageCallback
, (LPARAM
)pHeader
);
86 /*************************************************************************
88 * SH_ShowPropertiesDialog
90 * called from ShellExecuteExW32
92 * pwszPath contains path of folder/file
94 * TODO: provide button change application type if file has registered type
95 * make filename field editable and apply changes to filename on close
99 SH_ShowPropertiesDialog(LPCWSTR pwszPath
, LPCITEMIDLIST pidlFolder
, PCUITEMID_CHILD_ARRAY apidl
)
101 HPSXA hpsxa
[3] = {NULL
, NULL
, NULL
};
102 CComObject
<CFileDefExt
> *pFileDefExt
= NULL
;
104 TRACE("SH_ShowPropertiesDialog entered filename %s\n", debugstr_w(pwszPath
));
106 if (pwszPath
== NULL
|| !wcslen(pwszPath
))
109 HPROPSHEETPAGE hppages
[MAX_PROPERTY_SHEET_PAGE
];
110 memset(hppages
, 0x0, sizeof(HPROPSHEETPAGE
) * MAX_PROPERTY_SHEET_PAGE
);
112 /* Make a copy of path */
113 WCHAR wszPath
[MAX_PATH
];
114 StringCbCopyW(wszPath
, sizeof(wszPath
), pwszPath
);
116 /* remove trailing \\ at the end of path */
117 PathRemoveBackslashW(wszPath
);
120 if (PathIsRootW(wszPath
))
121 return SUCCEEDED(SH_ShowDriveProperties(wszPath
, pidlFolder
, apidl
));
123 /* Handle files and folders */
124 PROPSHEETHEADERW Header
;
125 memset(&Header
, 0x0, sizeof(PROPSHEETHEADERW
));
126 Header
.dwSize
= sizeof(PROPSHEETHEADERW
);
127 Header
.dwFlags
= PSH_NOCONTEXTHELP
| PSH_PROPTITLE
;
128 Header
.phpage
= hppages
;
129 Header
.pszCaption
= PathFindFileNameW(wszPath
);
131 CComPtr
<IDataObject
> pDataObj
;
132 HRESULT hr
= SHCreateDataObject(pidlFolder
, 1, apidl
, NULL
, IID_PPV_ARG(IDataObject
, &pDataObj
));
136 hr
= CComObject
<CFileDefExt
>::CreateInstance(&pFileDefExt
);
139 pFileDefExt
->AddRef(); // CreateInstance returns object with 0 ref count
140 hr
= pFileDefExt
->Initialize(pidlFolder
, pDataObj
, NULL
);
143 hr
= pFileDefExt
->AddPages(AddPropSheetPageCallback
, (LPARAM
)&Header
);
145 ERR("AddPages failed\n");
147 ERR("Initialize failed\n");
150 LoadPropSheetHandlers(wszPath
, &Header
, MAX_PROPERTY_SHEET_PAGE
- 1, hpsxa
, pDataObj
);
153 INT_PTR Result
= PropertySheetW(&Header
);
155 for (UINT i
= 0; i
< 3; ++i
)
157 SHDestroyPropSheetExtArray(hpsxa
[i
]);
159 pFileDefExt
->Release();
161 return (Result
!= -1);