mirror of
https://github.com/reactos/reactos.git
synced 2024-10-30 03:27:31 +00:00
6a1f287820
CORE-18386
181 lines
6 KiB
C++
181 lines
6 KiB
C++
/*
|
|
* Shell Library Functions
|
|
*
|
|
* Copyright 2005 Johannes Anderwald
|
|
* Copyright 2012 Rafal Harabien
|
|
* Copyright 2017-2018 Katayama Hirofumi MZ
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
|
|
|
EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
|
|
|
|
static UINT
|
|
LoadPropSheetHandlers(LPCWSTR pwszPath, PROPSHEETHEADERW *pHeader, UINT cMaxPages, HPSXA *phpsxa, IDataObject *pDataObj)
|
|
{
|
|
WCHAR wszBuf[MAX_PATH];
|
|
UINT cPages = 0, i = 0;
|
|
|
|
LPWSTR pwszFilename = PathFindFileNameW(pwszPath);
|
|
BOOL bDir = PathIsDirectoryW(pwszPath);
|
|
|
|
if (bDir)
|
|
{
|
|
phpsxa[i] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"Folder", cMaxPages - cPages, pDataObj);
|
|
cPages += SHAddFromPropSheetExtArray(phpsxa[i++], AddPropSheetPageCallback, (LPARAM)pHeader);
|
|
|
|
phpsxa[i] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"Directory", cMaxPages - cPages, pDataObj);
|
|
cPages += SHAddFromPropSheetExtArray(phpsxa[i++], AddPropSheetPageCallback, (LPARAM)pHeader);
|
|
}
|
|
else
|
|
{
|
|
/* Load property sheet handlers from ext key */
|
|
LPWSTR pwszExt = PathFindExtensionW(pwszFilename);
|
|
phpsxa[i] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, pwszExt, cMaxPages - cPages, pDataObj);
|
|
cPages += SHAddFromPropSheetExtArray(phpsxa[i++], AddPropSheetPageCallback, (LPARAM)pHeader);
|
|
|
|
/* Load property sheet handlers from prog id key */
|
|
DWORD cbBuf = sizeof(wszBuf);
|
|
if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, L"", RRF_RT_REG_SZ, NULL, wszBuf, &cbBuf) == ERROR_SUCCESS)
|
|
{
|
|
TRACE("EnumPropSheetExt wszBuf %s, pwszExt %s\n", debugstr_w(wszBuf), debugstr_w(pwszExt));
|
|
phpsxa[i] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, wszBuf, cMaxPages - cPages, pDataObj);
|
|
cPages += SHAddFromPropSheetExtArray(phpsxa[i++], AddPropSheetPageCallback, (LPARAM)pHeader);
|
|
}
|
|
|
|
/* Add property sheet handlers from "*" key */
|
|
phpsxa[i] = SHCreatePropSheetExtArrayEx(HKEY_CLASSES_ROOT, L"*", cMaxPages - cPages, pDataObj);
|
|
cPages += SHAddFromPropSheetExtArray(phpsxa[i++], AddPropSheetPageCallback, (LPARAM)pHeader);
|
|
}
|
|
|
|
return cPages;
|
|
}
|
|
|
|
/*************************************************************************
|
|
*
|
|
* SH_ShowPropertiesDialog
|
|
*
|
|
* called from ShellExecuteExW32
|
|
*
|
|
* pwszPath contains path of folder/file
|
|
*
|
|
* TODO: provide button change application type if file has registered type
|
|
* make filename field editable and apply changes to filename on close
|
|
*/
|
|
|
|
BOOL
|
|
SH_ShowPropertiesDialog(LPCWSTR pwszPath, IDataObject *pDataObj)
|
|
{
|
|
HPSXA hpsxa[3] = {NULL, NULL, NULL};
|
|
CComObject<CFileDefExt> *pFileDefExt = NULL;
|
|
|
|
TRACE("SH_ShowPropertiesDialog entered filename %s\n", debugstr_w(pwszPath));
|
|
|
|
if (pwszPath == NULL || !wcslen(pwszPath))
|
|
return FALSE;
|
|
|
|
HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE];
|
|
memset(hppages, 0x0, sizeof(HPROPSHEETPAGE) * MAX_PROPERTY_SHEET_PAGE);
|
|
|
|
/* Make a copy of path */
|
|
WCHAR wszPath[MAX_PATH];
|
|
StringCbCopyW(wszPath, sizeof(wszPath), pwszPath);
|
|
|
|
/* remove trailing \\ at the end of path */
|
|
PathRemoveBackslashW(wszPath);
|
|
|
|
CDataObjectHIDA cida(pDataObj);
|
|
if (FAILED_UNEXPECTEDLY(cida.hr()))
|
|
return FALSE;
|
|
|
|
if (cida->cidl == 0)
|
|
{
|
|
ERR("Empty HIDA\n");
|
|
return FALSE;
|
|
}
|
|
|
|
/* Handle drives */
|
|
if (_ILIsDrive(HIDA_GetPIDLItem(cida, 0)))
|
|
return SH_ShowDriveProperties(wszPath, pDataObj);
|
|
|
|
|
|
RECT rcPosition = {CW_USEDEFAULT, CW_USEDEFAULT, 0, 0};
|
|
POINT pt;
|
|
if (SUCCEEDED(DataObject_GetOffset(pDataObj, &pt)))
|
|
{
|
|
rcPosition.left = pt.x;
|
|
rcPosition.top = pt.y;
|
|
}
|
|
|
|
DWORD style = WS_DISABLED | WS_CLIPSIBLINGS | WS_CAPTION;
|
|
DWORD exstyle = WS_EX_WINDOWEDGE | WS_EX_APPWINDOW;
|
|
CStubWindow32 stub;
|
|
if (!stub.Create(NULL, rcPosition, NULL, style, exstyle))
|
|
{
|
|
ERR("StubWindow32 creation failed\n");
|
|
return FALSE;
|
|
}
|
|
|
|
/* Handle files and folders */
|
|
PROPSHEETHEADERW Header;
|
|
memset(&Header, 0x0, sizeof(PROPSHEETHEADERW));
|
|
Header.dwSize = sizeof(PROPSHEETHEADERW);
|
|
Header.hwndParent = stub;
|
|
Header.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE;
|
|
Header.phpage = hppages;
|
|
Header.pszCaption = PathFindFileNameW(wszPath);
|
|
|
|
HRESULT hr = CComObject<CFileDefExt>::CreateInstance(&pFileDefExt);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pFileDefExt->AddRef(); // CreateInstance returns object with 0 ref count
|
|
hr = pFileDefExt->Initialize(HIDA_GetPIDLFolder(cida), pDataObj, NULL);
|
|
if (!FAILED_UNEXPECTEDLY(hr))
|
|
{
|
|
hr = pFileDefExt->AddPages(AddPropSheetPageCallback, (LPARAM)&Header);
|
|
if (FAILED_UNEXPECTEDLY(hr))
|
|
{
|
|
ERR("AddPages failed\n");
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERR("Initialize failed\n");
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
LoadPropSheetHandlers(wszPath, &Header, MAX_PROPERTY_SHEET_PAGE - 1, hpsxa, pDataObj);
|
|
|
|
INT_PTR Result = PropertySheetW(&Header);
|
|
|
|
for (UINT i = 0; i < 3; ++i)
|
|
if (hpsxa[i])
|
|
SHDestroyPropSheetExtArray(hpsxa[i]);
|
|
if (pFileDefExt)
|
|
pFileDefExt->Release();
|
|
|
|
stub.DestroyWindow();
|
|
|
|
return (Result != -1);
|
|
}
|
|
|
|
/*EOF */
|