2 * Shell Library Functions
4 * Copyright 2005 Johannes Anderwald
5 * Copyright 2012 Rafal Harabien
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 Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #define MAX_PROPERTY_SHEET_PAGE 32
26 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
28 EXTERN_C HPSXA WINAPI
SHCreatePropSheetExtArrayEx(HKEY hKey
, LPCWSTR pszSubKey
, UINT max_iface
, IDataObject
*pDataObj
);
31 AddPropSheetPageCallback(HPROPSHEETPAGE hPage
, LPARAM lParam
)
33 PROPSHEETHEADERW
*pHeader
= (PROPSHEETHEADERW
*)lParam
;
35 if (pHeader
->nPages
< MAX_PROPERTY_SHEET_PAGE
)
37 pHeader
->phpage
[pHeader
->nPages
++] = hPage
;
45 LoadPropSheetHandlers(LPCWSTR pwszPath
, PROPSHEETHEADERW
*pHeader
, UINT cMaxPages
, HPSXA
*phpsxa
, IDataObject
*pDataObj
)
47 WCHAR wszBuf
[MAX_PATH
];
48 UINT cPages
= 0, i
= 0;
50 LPWSTR pwszFilename
= PathFindFileNameW(pwszPath
);
51 BOOL bDir
= PathIsDirectoryW(pwszPath
);
55 phpsxa
[i
] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, L
"Folder", cMaxPages
- cPages
, pDataObj
);
56 cPages
+= SHAddFromPropSheetExtArray(phpsxa
[i
++], AddPropSheetPageCallback
, (LPARAM
)pHeader
);
58 phpsxa
[i
] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, L
"Directory", cMaxPages
- cPages
, pDataObj
);
59 cPages
+= SHAddFromPropSheetExtArray(phpsxa
[i
++], AddPropSheetPageCallback
, (LPARAM
)pHeader
);
63 /* Load property sheet handlers from ext key */
64 LPWSTR pwszExt
= PathFindExtensionW(pwszFilename
);
65 phpsxa
[i
] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, pwszExt
, cMaxPages
- cPages
, pDataObj
);
66 cPages
+= SHAddFromPropSheetExtArray(phpsxa
[i
++], AddPropSheetPageCallback
, (LPARAM
)pHeader
);
68 /* Load property sheet handlers from prog id key */
69 DWORD cbBuf
= sizeof(wszBuf
);
70 if (RegGetValueW(HKEY_CLASSES_ROOT
, pwszExt
, L
"", RRF_RT_REG_SZ
, NULL
, wszBuf
, &cbBuf
) == ERROR_SUCCESS
)
72 TRACE("EnumPropSheetExt wszBuf %s, pwszExt %s\n", debugstr_w(wszBuf
), debugstr_w(pwszExt
));
73 phpsxa
[i
] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, wszBuf
, cMaxPages
- cPages
, pDataObj
);
74 cPages
+= SHAddFromPropSheetExtArray(phpsxa
[i
++], AddPropSheetPageCallback
, (LPARAM
)pHeader
);
77 /* Add property sheet handlers from "*" key */
78 phpsxa
[i
] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT
, L
"*", cMaxPages
- cPages
, pDataObj
);
79 cPages
+= SHAddFromPropSheetExtArray(phpsxa
[i
++], AddPropSheetPageCallback
, (LPARAM
)pHeader
);
85 /*************************************************************************
87 * SH_ShowPropertiesDialog
89 * called from ShellExecuteExW32
91 * pwszPath contains path of folder/file
93 * TODO: provide button change application type if file has registered type
94 * make filename field editable and apply changes to filename on close
98 SH_ShowPropertiesDialog(LPCWSTR pwszPath
, LPCITEMIDLIST pidlFolder
, LPCITEMIDLIST
*apidl
)
100 HPSXA hpsxa
[3] = {NULL
, NULL
, NULL
};
101 CComObject
<CFileDefExt
> *pFileDefExt
= NULL
;
103 TRACE("SH_ShowPropertiesDialog entered filename %s\n", debugstr_w(pwszPath
));
105 if (pwszPath
== NULL
|| !wcslen(pwszPath
))
108 HPROPSHEETPAGE hppages
[MAX_PROPERTY_SHEET_PAGE
];
109 memset(hppages
, 0x0, sizeof(HPROPSHEETPAGE
) * MAX_PROPERTY_SHEET_PAGE
);
111 /* Make a copy of path */
112 WCHAR wszPath
[MAX_PATH
];
113 StringCbCopyW(wszPath
, sizeof(wszPath
), pwszPath
);
115 /* remove trailing \\ at the end of path */
116 PathRemoveBackslashW(wszPath
);
119 if (PathIsRootW(wszPath
))
120 return SH_ShowDriveProperties(wszPath
, pidlFolder
, apidl
);
122 /* Handle files and folders */
123 PROPSHEETHEADERW Header
;
124 memset(&Header
, 0x0, sizeof(PROPSHEETHEADERW
));
125 Header
.dwSize
= sizeof(PROPSHEETHEADERW
);
126 Header
.dwFlags
= PSH_NOCONTEXTHELP
| PSH_PROPTITLE
;
127 Header
.phpage
= hppages
;
128 Header
.pszCaption
= PathFindFileNameW(wszPath
);
130 CComPtr
<IDataObject
> pDataObj
;
131 HRESULT hr
= SHCreateDataObject(pidlFolder
, 1, apidl
, NULL
, IID_PPV_ARG(IDataObject
, &pDataObj
));
135 hr
= CComObject
<CFileDefExt
>::CreateInstance(&pFileDefExt
);
138 pFileDefExt
->AddRef(); // CreateInstance returns object with 0 ref count
139 hr
= pFileDefExt
->Initialize(pidlFolder
, pDataObj
, NULL
);
142 hr
= pFileDefExt
->AddPages(AddPropSheetPageCallback
, (LPARAM
)&Header
);
144 ERR("AddPages failed\n");
146 ERR("Initialize failed\n");
149 LoadPropSheetHandlers(wszPath
, &Header
, MAX_PROPERTY_SHEET_PAGE
- 1, hpsxa
, pDataObj
);
152 INT_PTR Result
= PropertySheetW(&Header
);
154 for (UINT i
= 0; i
< 3; ++i
)
156 SHDestroyPropSheetExtArray(hpsxa
[i
]);
158 pFileDefExt
->Release();
160 return (Result
!= -1);