Author: rharabien
Date: Wed Jan 11 20:20:01 2012
New Revision: 54908
URL:
http://svn.reactos.org/svn/reactos?rev=54908&view=rev
Log:
[SHELL32]
- Add CLSID_ShellFileDefExt, CLSID_ShellDrvDefExt, CLSID_ShellNetDefExt GUIDs
- Move File Properties default pages to CFileDefExt
Added:
trunk/reactos/dll/win32/shell32/drvdefext.cpp (with props)
trunk/reactos/dll/win32/shell32/drvdefext.h (with props)
trunk/reactos/dll/win32/shell32/filedefext.cpp (with props)
trunk/reactos/dll/win32/shell32/filedefext.h (with props)
trunk/reactos/dll/win32/shell32/res/rgs/shellfiledefext.rgs
Modified:
trunk/reactos/dll/win32/shell32/CMakeLists.txt
trunk/reactos/dll/win32/shell32/fprop.cpp
trunk/reactos/dll/win32/shell32/precomp.h
trunk/reactos/dll/win32/shell32/rgs_res.rc
trunk/reactos/dll/win32/shell32/shell32.rbuild
trunk/reactos/dll/win32/shell32/shresdef.h
trunk/reactos/include/psdk/shlguid_undoc.h
Modified: trunk/reactos/dll/win32/shell32/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CMakeLis…
==============================================================================
--- trunk/reactos/dll/win32/shell32/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/CMakeLists.txt [iso-8859-1] Wed Jan 11 20:20:01 2012
@@ -69,6 +69,8 @@
newmenu.cpp
startmenu.cpp
folder_options.cpp
+ filedefext.cpp
+ drvdefext.cpp
shell32.rc
${CMAKE_CURRENT_BINARY_DIR}/shell32_stubs.c
${CMAKE_CURRENT_BINARY_DIR}/shell32.def)
Added: trunk/reactos/dll/win32/shell32/drvdefext.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/drvdefex…
==============================================================================
--- trunk/reactos/dll/win32/shell32/drvdefext.cpp (added)
+++ trunk/reactos/dll/win32/shell32/drvdefext.cpp [iso-8859-1] Wed Jan 11 20:20:01 2012
@@ -1,0 +1,1 @@
+
Propchange: trunk/reactos/dll/win32/shell32/drvdefext.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/win32/shell32/drvdefext.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/drvdefex…
==============================================================================
--- trunk/reactos/dll/win32/shell32/drvdefext.h (added)
+++ trunk/reactos/dll/win32/shell32/drvdefext.h [iso-8859-1] Wed Jan 11 20:20:01 2012
@@ -1,0 +1,1 @@
+
Propchange: trunk/reactos/dll/win32/shell32/drvdefext.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/reactos/dll/win32/shell32/drvdefext.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Added: trunk/reactos/dll/win32/shell32/filedefext.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/filedefe…
==============================================================================
--- trunk/reactos/dll/win32/shell32/filedefext.cpp (added)
+++ trunk/reactos/dll/win32/shell32/filedefext.cpp [iso-8859-1] Wed Jan 11 20:20:01 2012
@@ -1,0 +1,812 @@
+/*
+ * provides new shell item service
+ *
+ * Copyright 2007 Johannes Anderwald (janderwald(a)reactos.org)
+ * Copyright 2009 Andrew Hill
+ * Copyright 2012 Rafal Harabien
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <precomp.h>
+
+WINE_DEFAULT_DEBUG_CHANNEL(shell);
+
+BOOL PathIsExeW(LPCWSTR lpszPath);
+
+BOOL CFileVersionInfo::Load(LPCWSTR pwszPath)
+{
+ ULONG cbInfo = GetFileVersionInfoSizeW(pwszPath, NULL);
+ if (!cbInfo)
+ {
+ WARN("GetFileVersionInfoSize %ls failed\n", pwszPath);
+ return FALSE;
+ }
+
+ m_pInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbInfo);
+ if (!m_pInfo)
+ {
+ ERR("HeapAlloc failed bytes %x\n", cbInfo);
+ return FALSE;
+ }
+
+ if (!GetFileVersionInfoW(pwszPath, 0, cbInfo, m_pInfo))
+ {
+ ERR("GetFileVersionInfoW failed\n");
+ return FALSE;
+ }
+
+ LPLANGANDCODEPAGE lpLangCode;
+ UINT cBytes;
+ if (!VerQueryValueW(m_pInfo, L"VarFileInfo\\Translation", (LPVOID
*)&lpLangCode, &cBytes))
+ {
+ ERR("VerQueryValueW failed\n");
+ return FALSE;
+ }
+
+ /* FIXME: find language from current locale / if not available,
+ * default to english
+ * for now default to first available language
+ */
+ m_wLang = lpLangCode->lang;
+ m_wCode = lpLangCode->code;
+ return TRUE;
+}
+
+LPCWSTR CFileVersionInfo::GetString(LPCWSTR pwszName)
+{
+ if (!m_pInfo)
+ return NULL;
+
+ WCHAR wszBuf[256];
+ swprintf(wszBuf, L"\\StringFileInfo\\%04x%04x\\%s", m_wLang, m_wCode,
pwszName);
+
+ LPCWSTR pwszResult = NULL;
+ UINT cBytes = 0;
+ if (!VerQueryValueW(m_pInfo, wszBuf, (LPVOID *)&pwszResult, &cBytes))
+ return NULL;
+
+ return pwszResult;
+}
+
+VS_FIXEDFILEINFO *CFileVersionInfo::GetFixedInfo()
+{
+ if (!m_pInfo)
+ return NULL;
+
+ VS_FIXEDFILEINFO *pInfo;
+ UINT cBytes;
+ if (!VerQueryValueW(m_pInfo, L"\\", (PVOID*)&pInfo, &cBytes))
+ return NULL;
+ return pInfo;
+}
+
+/*************************************************************************
+ *
+ * SH_FormatFileSizeWithBytes
+ *
+ * Format a size in bytes to string.
+ *
+ * lpQwSize = Pointer to 64bit large integer to format
+ * pszBuf = Buffer to fill with output string
+ * cchBuf = size of pszBuf in characters
+ *
+ */
+
+LPWSTR
+SH_FormatFileSizeWithBytes(PULARGE_INTEGER lpQwSize, LPWSTR pszBuf, UINT cchBuf)
+{
+ NUMBERFMTW nf;
+ WCHAR szNumber[24];
+ WCHAR szDecimalSep[8];
+ WCHAR szThousandSep[8];
+ WCHAR szGrouping[12];
+ int Len, cchFormatted, i;
+ size_t cchRemaining;
+ LPWSTR Ptr;
+
+ // Try to build first Format byte string
+ if (StrFormatByteSizeW(lpQwSize->QuadPart, pszBuf, cchBuf) == NULL)
+ return NULL;
+
+ // If there is less bytes than 1KB, we have nothing to do
+ if (lpQwSize->QuadPart < 1024)
+ return pszBuf;
+
+ // Print the number in uniform mode
+ swprintf(szNumber, L"%I64u", lpQwSize->QuadPart);
+
+ // Get system strings for decimal and thousand separators.
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szDecimalSep,
sizeof(szDecimalSep) / sizeof(*szDecimalSep));
+ GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szThousandSep,
sizeof(szThousandSep) / sizeof(*szThousandSep));
+
+ // Initialize format for printing the number in bytes
+ ZeroMemory(&nf, sizeof(nf));
+ nf.NumDigits = 0;
+ nf.LeadingZero = 0;
+ nf.Grouping = 0;
+ nf.lpDecimalSep = szDecimalSep;
+ nf.lpThousandSep = szThousandSep;
+ nf.NegativeOrder = 0;
+
+ // Get system string for groups separator
+ Len = GetLocaleInfoW(LOCALE_USER_DEFAULT,
+ LOCALE_SGROUPING,
+ szGrouping,
+ sizeof(szGrouping) / sizeof(*szGrouping));
+
+ // Convert grouping specs from string to integer
+ for (i = 0; i < Len; i++)
+ {
+ WCHAR wch = szGrouping[i];
+
+ if (wch >= L'0' && wch <= L'9')
+ nf.Grouping = nf.Grouping * 10 + (wch - L'0');
+ else if (wch != L';')
+ break;
+ }
+
+ if ((nf.Grouping % 10) == 0)
+ nf.Grouping /= 10;
+ else
+ nf.Grouping *= 10;
+
+ // Concate " (" at the end of buffer
+ Len = wcslen(pszBuf);
+ Ptr = pszBuf + Len;
+ cchRemaining = cchBuf - Len;
+ StringCchCopyExW(Ptr, cchRemaining, L" (", &Ptr, &cchRemaining,
0);
+
+ // Save formatted number of bytes in buffer
+ cchFormatted = GetNumberFormatW(LOCALE_USER_DEFAULT,
+ 0,
+ szNumber,
+ &nf,
+ Ptr,
+ cchRemaining);
+
+ if (cchFormatted == 0)
+ return NULL;
+
+ // cchFormatted is number of characters including NULL - make it a real length
+ --cchFormatted;
+
+ // Copy ' ' to buffer
+ Ptr += cchFormatted;
+ cchRemaining -= cchFormatted;
+ StringCchCopyExW(Ptr, cchRemaining, L" ", &Ptr, &cchRemaining, 0);
+
+ // Copy 'bytes' string and remaining ')'
+ Len = LoadStringW(shell32_hInstance, IDS_BYTES_FORMAT, Ptr, cchRemaining);
+ Ptr += Len;
+ cchRemaining -= Len;
+ StringCchCopy(Ptr, cchRemaining, L")");
+
+ return pszBuf;
+}
+
+/*************************************************************************
+ *
+ * SH_CreatePropertySheetPage [Internal]
+ *
+ * creates a property sheet page from an resource name
+ *
+ */
+
+HPROPSHEETPAGE
+SH_CreatePropertySheetPage(LPCSTR pszResName, DLGPROC pfnDlgProc, LPARAM lParam, LPWSTR
pwszTitle)
+{
+ if (pszResName == NULL)
+ return NULL;
+
+ HRSRC hRes = FindResourceA(shell32_hInstance, pszResName, (LPSTR)RT_DIALOG);
+ if (hRes == NULL)
+ {
+ ERR("failed to find resource name\n");
+ return NULL;
+ }
+
+ LPVOID pTemplate = LoadResource(shell32_hInstance, hRes);
+ if (pTemplate == NULL)
+ {
+ ERR("failed to load resource\n");
+ return NULL;
+ }
+
+ PROPSHEETPAGEW Page;
+ memset(&Page, 0x0, sizeof(PROPSHEETPAGEW));
+ Page.dwSize = sizeof(PROPSHEETPAGEW);
+ Page.dwFlags = PSP_DLGINDIRECT;
+ Page.pResource = (DLGTEMPLATE*)pTemplate;
+ Page.pfnDlgProc = pfnDlgProc;
+ Page.lParam = lParam;
+ Page.pszTitle = pwszTitle;
+
+ if (pwszTitle)
+ Page.dwFlags |= PSP_USETITLE;
+
+ return CreatePropertySheetPageW(&Page);
+}
+
+VOID
+CFileDefExt::InitOpensWithField(HWND hwndDlg)
+{
+ WCHAR wszBuf[MAX_PATH] = L"";
+ WCHAR wszPath[MAX_PATH] = L"";
+ DWORD dwSize = sizeof(wszBuf);
+ BOOL bUnknownApp = TRUE;
+ LPCWSTR pwszExt = PathFindExtensionW(m_wszPath);
+
+ if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, L"", RRF_RT_REG_SZ, NULL,
wszBuf, &dwSize) == ERROR_SUCCESS)
+ {
+ bUnknownApp = FALSE;
+ StringCbCatW(wszBuf, sizeof(wszBuf), L"\\shell\\open\\command");
+ dwSize = sizeof(wszPath);
+ if (RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, L"", RRF_RT_REG_SZ, NULL,
wszPath, &dwSize) == ERROR_SUCCESS)
+ {
+ /* Get path from command line */
+ ExpandEnvironmentStringsW(wszPath, wszBuf, _countof(wszBuf));
+ PathRemoveArgs(wszBuf);
+ PathUnquoteSpacesW(wszBuf);
+ PathSearchAndQualify(wszBuf, wszPath, _countof(wszPath));
+
+ if (PathFileExistsW(wszPath))
+ {
+ /* Get file description */
+ CFileVersionInfo VerInfo;
+ VerInfo.Load(wszPath);
+ LPCWSTR pwszDescr = VerInfo.GetString(L"FileDescription");
+ if (pwszDescr)
+ SetDlgItemTextW(hwndDlg, 14007, pwszDescr);
+ else
+ {
+ /* File has no description - display filename */
+ LPWSTR pwszFilename = PathFindFileNameW(wszPath);
+ PathRemoveExtension(pwszFilename);
+ pwszFilename[0] = towupper(pwszFilename[0]);
+ SetDlgItemTextW(hwndDlg, 14007, pwszFilename);
+ }
+ }
+ else
+ bUnknownApp = TRUE;
+ } else
+ WARN("RegGetValueW %ls failed\n", wszBuf);
+ } else
+ WARN("RegGetValueW %ls failed\n", pwszExt);
+
+ if (bUnknownApp)
+ {
+ /* Unknown application */
+ LoadStringW(shell32_hInstance, IDS_UNKNOWN_APP, wszBuf, _countof(wszBuf));
+ SetDlgItemTextW(hwndDlg, 14007, wszBuf);
+ }
+}
+
+/*************************************************************************
+ *
+ * SH_FileGeneralFileType [Internal]
+ *
+ * retrieves file extension description from registry and sets it in dialog
+ *
+ * TODO: retrieve file extension default icon and load it
+ * find executable name from registry, retrieve description from executable
+ */
+
+BOOL
+CFileDefExt::InitFileType(HWND hwndDlg)
+{
+ TRACE("path %s\n", debugstr_w(m_wszPath));
+
+ HWND hDlgCtrl = GetDlgItem(hwndDlg, 14005);
+ if (hDlgCtrl == NULL)
+ return FALSE;
+
+ /* Get file information */
+ SHFILEINFO fi;
+ if (!SHGetFileInfoW(m_wszPath, 0, &fi, sizeof(fi), SHGFI_TYPENAME|SHGFI_ICON))
+ {
+ ERR("SHGetFileInfoW failed for %ls (%lu)\n", m_wszPath,
GetLastError());
+ fi.szTypeName[0] = L'\0';
+ fi.hIcon = NULL;
+ }
+
+ LPCWSTR pwszExt = PathFindExtensionW(m_wszPath);
+ if (pwszExt[0])
+ {
+ WCHAR wszBuf[256];
+
+ if (!fi.szTypeName[0])
+ {
+ /* The file type is unknown, so default to string "FileExtension
File" */
+ size_t cchRemaining = 0;
+ LPWSTR pwszEnd = NULL;
+
+ StringCchPrintfExW(wszBuf, _countof(wszBuf), &pwszEnd, &cchRemaining,
0, L"%s ", pwszExt + 1);
+ SendMessageW(hDlgCtrl, WM_GETTEXT, (WPARAM)cchRemaining, (LPARAM)pwszEnd);
+
+ SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)wszBuf);
+ }
+ else
+ {
+ /* Update file type */
+ StringCbPrintfW(wszBuf, sizeof(wszBuf), L"%s (%s)", fi.szTypeName,
pwszExt);
+ SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)wszBuf);
+ }
+ }
+
+ /* Update file icon */
+ if (fi.hIcon)
+ SendDlgItemMessageW(hwndDlg, 14000, STM_SETICON, (WPARAM)fi.hIcon, 0);
+ else
+ ERR("No icon %ls\n", m_wszPath);
+
+ return TRUE;
+}
+
+/*************************************************************************
+ *
+ * SHFileGeneralGetFileTimeString [Internal]
+ *
+ * formats a given LPFILETIME struct into readable user format
+ */
+
+BOOL
+CFileDefExt::GetFileTimeString(LPFILETIME lpFileTime, WCHAR *lpResult)
+{
+ FILETIME ft;
+ SYSTEMTIME st;
+
+ if (lpFileTime == NULL || lpResult == NULL)
+ return FALSE;
+
+ if (!FileTimeToLocalFileTime(lpFileTime, &ft))
+ return FALSE;
+
+ FileTimeToSystemTime(&ft, &st);
+
+ /* ddmmyy */
+ swprintf(lpResult, L"%02hu/%02hu/%04hu %02hu:%02hu", st.wDay, st.wMonth,
st.wYear, st.wHour, st.wMinute);
+
+ TRACE("result %s\n", debugstr_w(lpResult));
+ return TRUE;
+}
+
+/*************************************************************************
+ *
+ * SH_FileGeneralSetText [Internal]
+ *
+ * sets file path string and filename string
+ *
+ */
+
+BOOL
+CFileDefExt::InitFilePath(HWND hwndDlg)
+{
+ /* Find the filename */
+ WCHAR *pwszFilename = PathFindFileNameW(m_wszPath);
+
+ if (pwszFilename > m_wszPath)
+ {
+ /* Location field */
+ WCHAR wszLocation[MAX_PATH];
+ StringCchCopyNW(wszLocation, _countof(wszLocation), m_wszPath, pwszFilename -
m_wszPath);
+ PathRemoveBackslashW(wszLocation);
+
+ SetDlgItemTextW(hwndDlg, 14009, wszLocation);
+ }
+
+ /* Filename field */
+ SetDlgItemTextW(hwndDlg, 14001, pwszFilename);
+
+ return TRUE;
+}
+
+/*************************************************************************
+ *
+ * SH_FileGeneralSetFileSizeTime [Internal]
+ *
+ * retrieves file information from file and sets in dialog
+ *
+ */
+
+BOOL
+CFileDefExt::InitFileSizeTime(HWND hwndDlg)
+{
+ WCHAR wszBuf[MAX_PATH];
+
+ TRACE("SH_FileGeneralSetFileSizeTime %ls\n", m_wszPath);
+
+ HANDLE hFile = CreateFileW(m_wszPath,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ WARN("failed to open file %s\n", debugstr_w(m_wszPath));
+ return FALSE;
+ }
+
+ FILETIME CreateTime, AccessedTime, WriteTime;
+ if (!GetFileTime(hFile, &CreateTime, &AccessedTime, &WriteTime))
+ {
+ WARN("GetFileTime failed\n");
+ CloseHandle(hFile);
+ return FALSE;
+ }
+
+ LARGE_INTEGER FileSize;
+ if (!GetFileSizeEx(hFile, &FileSize))
+ {
+ WARN("GetFileSize failed\n");
+ CloseHandle(hFile);
+ return FALSE;
+ }
+
+ CloseHandle(hFile);
+
+ if (GetFileTimeString(&CreateTime, wszBuf))
+ SetDlgItemTextW(hwndDlg, 14015, wszBuf);
+
+ if (GetFileTimeString(&AccessedTime, wszBuf))
+ SetDlgItemTextW(hwndDlg, 14019, wszBuf);
+
+ if (GetFileTimeString(&WriteTime, wszBuf))
+ SetDlgItemTextW(hwndDlg, 14017, wszBuf);
+
+ if (SH_FormatFileSizeWithBytes((PULARGE_INTEGER)&FileSize,
+ wszBuf,
+ sizeof(wszBuf) / sizeof(WCHAR)))
+ {
+ SetDlgItemTextW(hwndDlg, 14011, wszBuf);
+ }
+
+ return TRUE;
+}
+
+/*************************************************************************
+ *
+ * CFileDefExt::InitGeneralPage [Internal]
+ *
+ * sets all file general properties in dialog
+ */
+
+BOOL
+CFileDefExt::InitGeneralPage(HWND hwndDlg)
+{
+ /* Set general text properties filename filelocation and icon */
+ InitFilePath(hwndDlg);
+
+ /* Set file type and icon */
+ InitFileType(hwndDlg);
+
+ /* Set open with application */
+ if (!PathIsExeW(m_wszPath))
+ InitOpensWithField(hwndDlg);
+ else
+ {
+ LPCWSTR pwszDescr = m_VerInfo.GetString(L"FileDescription");
+ if (pwszDescr)
+ SetDlgItemTextW(hwndDlg, 14007, pwszDescr);
+ }
+
+ /* Set file created/modfied/accessed time */
+ InitFileSizeTime(hwndDlg);
+
+ return TRUE;
+}
+
+/*************************************************************************
+ *
+ * CFileDefExt::GeneralPageProc
+ *
+ * wnd proc of 'General' property sheet page
+ *
+ */
+
+INT_PTR CALLBACK
+CFileDefExt::GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ LPPROPSHEETPAGEW ppsp = (LPPROPSHEETPAGEW)lParam;
+
+ if (ppsp == NULL || !ppsp->lParam)
+ break;
+
+ TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %S\n", hwndDlg,
lParam, ppsp->lParam);
+
+ CFileDefExt *pFileDefExt = (CFileDefExt*)ppsp->lParam;
+ pFileDefExt->InitGeneralPage(hwndDlg);
+ }
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+/*************************************************************************
+ *
+ * CFileDefExt::InitVersionPage [Internal]
+ *
+ * sets all file version properties in dialog
+ */
+
+BOOL
+CFileDefExt::InitVersionPage(HWND hwndDlg)
+{
+ /* Get fixed info */
+ VS_FIXEDFILEINFO *pInfo = m_VerInfo.GetFixedInfo();
+ if (pInfo)
+ {
+ WCHAR wszVersion[256];
+ swprintf(wszVersion, L"%u.%u.%u.%u",
HIWORD(pInfo->dwFileVersionMS),
+ LOWORD(pInfo->dwFileVersionMS),
+ HIWORD(pInfo->dwFileVersionLS),
+ LOWORD(pInfo->dwFileVersionLS));
+ TRACE("MS %x LS %x ver %s \n", pInfo->dwFileVersionMS,
pInfo->dwFileVersionLS, debugstr_w(wszVersion));
+ SetDlgItemTextW(hwndDlg, 14001, wszVersion);
+ }
+
+ /* Update labels */
+ SetVersionLabel(hwndDlg, 14003, L"FileDescription");
+ SetVersionLabel(hwndDlg, 14005, L"LegalCopyright");
+
+ /* Add items to listbox */
+ AddVersionString(hwndDlg, L"CompanyName");
+ /* FIXME insert language identifier */
+ AddVersionString(hwndDlg, L"ProductName");
+ AddVersionString(hwndDlg, L"InternalName");
+ AddVersionString(hwndDlg, L"OriginalFilename");
+ AddVersionString(hwndDlg, L"FileVersion");
+ AddVersionString(hwndDlg, L"ProductVersion");
+
+ /* Attach file version to dialog window */
+ SetWindowLongPtr(hwndDlg, DWL_USER, (LONG_PTR)this);
+
+ /* Select first item */
+ HWND hDlgCtrl = GetDlgItem(hwndDlg, 14009);
+ SendMessageW(hDlgCtrl, LB_SETCURSEL, 0, 0);
+ LPCWSTR pwszText = (WCHAR *)SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)0,
(LPARAM)NULL);
+ SetDlgItemTextW(hwndDlg, 14010, pwszText);
+
+ return TRUE;
+}
+
+/*************************************************************************
+ *
+ * CFileDefExt::SetVersionLabel [Internal]
+ *
+ *
+ */
+
+BOOL
+CFileDefExt::SetVersionLabel(HWND hwndDlg, DWORD idCtrl, LPCWSTR pwszName)
+{
+ if (hwndDlg == NULL || pwszName == NULL)
+ return FALSE;
+
+ LPCWSTR pwszValue = m_VerInfo.GetString(pwszName);
+ if (pwszValue)
+ {
+ /* file description property */
+ TRACE("%s :: %s\n", debugstr_w(pwszName), debugstr_w(pwszValue));
+ SetDlgItemTextW(hwndDlg, idCtrl, pwszValue);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*************************************************************************
+ *
+ * CFileDefExt::AddVersionString [Internal]
+ *
+ * retrieves a version string and adds it to listbox
+ *
+ */
+
+BOOL
+CFileDefExt::AddVersionString(HWND hwndDlg, LPCWSTR pwszName)
+{
+ TRACE("pwszName %s, hwndDlg %p\n", debugstr_w(pwszName), hwndDlg);
+
+ if (hwndDlg == NULL || pwszName == NULL)
+ return FALSE;
+
+ LPCWSTR pwszValue = m_VerInfo.GetString(pwszName);
+ if (pwszValue)
+ {
+ /* listbox name property */
+ HWND hDlgCtrl = GetDlgItem(hwndDlg, 14009);
+ TRACE("%s :: %s\n", debugstr_w(pwszName), debugstr_w(pwszValue));
+ UINT Index = SendMessageW(hDlgCtrl, LB_ADDSTRING, (WPARAM) -1,
(LPARAM)pwszName);
+ SendMessageW(hDlgCtrl, LB_SETITEMDATA, (WPARAM)Index, (LPARAM)(WCHAR
*)pwszValue);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*************************************************************************
+ *
+ * CFileDefExt::VersionPageProc
+ *
+ * wnd proc of 'Version' property sheet page
+ */
+
+INT_PTR CALLBACK
+CFileDefExt::VersionPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ LPPROPSHEETPAGE ppsp = (LPPROPSHEETPAGE)lParam;
+
+ if (ppsp == NULL || !ppsp->lParam)
+ break;
+
+ TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %x\n", hwndDlg,
lParam, ppsp->lParam);
+
+ CFileDefExt *pFileDefExt = (CFileDefExt*)ppsp->lParam;
+ return pFileDefExt->InitVersionPage(hwndDlg);
+ }
+ case WM_COMMAND:
+ if (LOWORD(wParam) == 14009 && HIWORD(wParam) == LBN_SELCHANGE)
+ {
+ HWND hDlgCtrl = (HWND)lParam;
+
+ LRESULT Index = SendMessageW(hDlgCtrl, LB_GETCURSEL, (WPARAM)NULL,
(LPARAM)NULL);
+ if (Index == LB_ERR)
+ break;
+
+ LPCWSTR pwszData = (LPCWSTR)SendMessageW(hDlgCtrl, LB_GETITEMDATA,
(WPARAM)Index, (LPARAM)NULL);
+ if (pwszData == NULL)
+ break;
+
+ TRACE("hDlgCtrl %x string %s\n", hDlgCtrl,
debugstr_w(pwszData));
+ SetDlgItemTextW(hwndDlg, 14010, pwszData);
+
+ return TRUE;
+ }
+ break;
+ case WM_DESTROY:
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+CFileDefExt::CFileDefExt()
+{
+ m_wszPath[0] = L'\0';
+}
+
+CFileDefExt::~CFileDefExt()
+{
+
+}
+
+HRESULT WINAPI
+CFileDefExt::Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pDataObj, HKEY
hkeyProgID)
+{
+ FORMATETC format;
+ STGMEDIUM stgm;
+ HRESULT hr;
+
+ TRACE("%p %p %p %p\n", this, pidlFolder, pDataObj, hkeyProgID);
+
+ if (!pDataObj)
+ return E_FAIL;
+
+ format.cfFormat = CF_HDROP;
+ format.ptd = NULL;
+ format.dwAspect = DVASPECT_CONTENT;
+ format.lindex = -1;
+ format.tymed = TYMED_HGLOBAL;
+
+ hr = pDataObj->GetData(&format, &stgm);
+ if (FAILED(hr))
+ return hr;
+
+ if (!DragQueryFileW((HDROP)stgm.hGlobal, 0, m_wszPath, _countof(m_wszPath)))
+ {
+ ERR("DragQueryFileW failed\n");
+ ReleaseStgMedium(&stgm);
+ return E_FAIL;
+ }
+
+ ReleaseStgMedium(&stgm);
+ TRACE("File properties %ls\n", m_wszPath);
+ m_VerInfo.Load(m_wszPath);
+
+ return S_OK;
+}
+
+HRESULT WINAPI
+CFileDefExt::QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT
idCmdLast, UINT uFlags)
+{
+ UNIMPLEMENTED;
+ return E_NOTIMPL;
+}
+
+HRESULT WINAPI
+CFileDefExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
+{
+ UNIMPLEMENTED;
+ return E_NOTIMPL;
+}
+
+HRESULT WINAPI
+CFileDefExt::GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved, LPSTR
pszName, UINT cchMax)
+{
+ UNIMPLEMENTED;
+ return E_NOTIMPL;
+}
+
+HRESULT WINAPI
+CFileDefExt::AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam)
+{
+ HPROPSHEETPAGE hPage;
+
+ hPage = SH_CreatePropertySheetPage("SHELL_FILE_GENERAL_DLG",
+ GeneralPageProc,
+ (LPARAM)this,
+ NULL);
+ if (hPage)
+ pfnAddPage(hPage, lParam);
+
+ if (GetFileVersionInfoSizeW(m_wszPath, NULL))
+ {
+ hPage = SH_CreatePropertySheetPage("SHELL_FILE_VERSION_DLG",
+ VersionPageProc,
+ (LPARAM)this,
+ NULL);
+ if (hPage)
+ pfnAddPage(hPage, lParam);
+ }
+
+ return S_OK;
+}
+
+HRESULT WINAPI
+CFileDefExt::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM
lParam)
+{
+ UNIMPLEMENTED;
+ return E_NOTIMPL;
+}
+
+HRESULT WINAPI
+CFileDefExt::SetSite(IUnknown *punk)
+{
+ UNIMPLEMENTED;
+ return E_NOTIMPL;
+}
+
+HRESULT WINAPI
+CFileDefExt::GetSite(REFIID iid, void **ppvSite)
+{
+ UNIMPLEMENTED;
+ return E_NOTIMPL;
+}
Propchange: trunk/reactos/dll/win32/shell32/filedefext.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Added: trunk/reactos/dll/win32/shell32/filedefext.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/filedefe…
==============================================================================
--- trunk/reactos/dll/win32/shell32/filedefext.h (added)
+++ trunk/reactos/dll/win32/shell32/filedefext.h [iso-8859-1] Wed Jan 11 20:20:01 2012
@@ -1,0 +1,110 @@
+/*
+ * Provides default file shell extension
+ *
+ * Copyright 2012 Rafal Harabien
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef _FILE_DEF_EXT_H_
+#define _FILE_DEF_EXT_H_
+
+class CFileVersionInfo
+{
+ private:
+ PVOID m_pInfo;
+ WORD m_wLang, m_wCode;
+
+ typedef struct _LANGANDCODEPAGE_
+ {
+ WORD lang;
+ WORD code;
+ } LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
+
+ public:
+ inline CFileVersionInfo():
+ m_pInfo(NULL), m_wLang(0), m_wCode(0) {}
+
+ inline ~CFileVersionInfo()
+ {
+ if (m_pInfo)
+ HeapFree(GetProcessHeap(), 0, m_pInfo);
+ }
+
+ BOOL Load(LPCWSTR pwszPath);
+
+ LPCWSTR GetString(LPCWSTR pwszName);
+
+ VS_FIXEDFILEINFO *GetFixedInfo();
+};
+
+class CFileDefExt :
+ public CComCoClass<CFileDefExt, &CLSID_ShellFileDefExt>,
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IShellExtInit,
+ public IContextMenu,
+ public IShellPropSheetExt,
+ public IObjectWithSite
+{
+private:
+ VOID InitOpensWithField(HWND hwndDlg);
+ BOOL InitFileType(HWND hwndDlg);
+ static BOOL GetFileTimeString(LPFILETIME lpFileTime, WCHAR *lpResult);
+ BOOL InitFilePath(HWND hwndDlg);
+ BOOL InitFileSizeTime(HWND hwndDlg);
+ BOOL InitGeneralPage(HWND hwndDlg);
+ BOOL SetVersionLabel(HWND hwndDlg, DWORD idCtrl, LPCWSTR pwszName);
+ BOOL AddVersionString(HWND hwndDlg, LPCWSTR pwszName);
+ BOOL InitVersionPage(HWND hwndDlg);
+ static INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
LPARAM lParam);
+ static INT_PTR CALLBACK VersionPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
lParam);
+
+ WCHAR m_wszPath[MAX_PATH];
+ CFileVersionInfo m_VerInfo;
+
+public:
+ CFileDefExt();
+ ~CFileDefExt();
+
+ // IShellExtInit
+ virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidlFolder, IDataObject
*pdtobj, HKEY hkeyProgID);
+
+ // IContextMenu
+ virtual HRESULT WINAPI QueryContextMenu(HMENU hmenu, UINT indexMenu, UINT idCmdFirst,
UINT idCmdLast, UINT uFlags);
+ virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpici);
+ virtual HRESULT WINAPI GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pwReserved,
LPSTR pszName, UINT cchMax);
+
+ // IShellPropSheetExt
+ virtual HRESULT WINAPI AddPages(LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam);
+ virtual HRESULT WINAPI ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage,
LPARAM lParam);
+
+ // IObjectWithSite
+ virtual HRESULT WINAPI SetSite(IUnknown *punk);
+ virtual HRESULT WINAPI GetSite(REFIID iid, void **ppvSite);
+
+DECLARE_REGISTRY_RESOURCEID(IDR_FILEDEFEXT)
+DECLARE_NOT_AGGREGATABLE(CFileDefExt)
+
+DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+BEGIN_COM_MAP(CFileDefExt)
+ COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
+ COM_INTERFACE_ENTRY_IID(IID_IShellPropSheetExt, IShellPropSheetExt)
+ COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
+END_COM_MAP()
+};
+
+#endif // _FILE_DEF_EXT_H_
Propchange: trunk/reactos/dll/win32/shell32/filedefext.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: trunk/reactos/dll/win32/shell32/filedefext.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Modified: trunk/reactos/dll/win32/shell32/fprop.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/fprop.cp…
==============================================================================
--- trunk/reactos/dll/win32/shell32/fprop.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/fprop.cpp [iso-8859-1] Wed Jan 11 20:20:01 2012
@@ -2,6 +2,7 @@
* Shell Library Functions
*
* Copyright 2005 Johannes Anderwald
+ * Copyright 2012 Rafal Harabien
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -20,727 +21,11 @@
#include <precomp.h>
+#define MAX_PROPERTY_SHEET_PAGE 32
+
WINE_DEFAULT_DEBUG_CHANNEL(shell);
-#define MAX_PROPERTY_SHEET_PAGE 32
-
-typedef struct _LANGANDCODEPAGE_
-{
- WORD lang;
- WORD code;
-} LANGANDCODEPAGE, *LPLANGANDCODEPAGE;
-
EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT
max_iface, IDataObject *pDataObj);
-BOOL PathIsExeW(LPCWSTR lpszPath);
-
-class CFileVersionInfo
-{
- public:
- inline CFileVersionInfo():
- m_pInfo(NULL), m_wLang(0), m_wCode(0) {}
-
- inline ~CFileVersionInfo()
- {
- if (m_pInfo)
- HeapFree(GetProcessHeap(), 0, m_pInfo);
- }
-
- BOOL Load(LPCWSTR pwszPath)
- {
- ULONG cbBuf = GetFileVersionInfoSizeW(pwszPath, NULL);
- if (!cbBuf)
- {
- WARN("GetFileVersionInfoSize %ls failed\n", pwszPath);
- return FALSE;
- }
-
- m_pInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbBuf);
- if (!m_pInfo)
- {
- ERR("HeapAlloc failed bytes %x\n", cbBuf);
- return FALSE;
- }
-
- if (!GetFileVersionInfoW(pwszPath, 0, cbBuf, m_pInfo))
- {
- ERR("GetFileVersionInfoW failed\n");
- return FALSE;
- }
-
- LPLANGANDCODEPAGE lpLangCode;
- UINT cBytes;
- if (!VerQueryValueW(m_pInfo, L"VarFileInfo\\Translation", (LPVOID
*)&lpLangCode, &cBytes))
- {
- ERR("VerQueryValueW failed\n");
- return FALSE;
- }
-
- /* FIXME: find language from current locale / if not available,
- * default to english
- * for now default to first available language
- */
- m_wLang = lpLangCode->lang;
- m_wCode = lpLangCode->code;
- return TRUE;
- }
-
- LPCWSTR GetString(LPCWSTR pwszName)
- {
- if (!m_pInfo)
- return NULL;
-
- WCHAR wszBuf[256];
- swprintf(wszBuf, L"\\StringFileInfo\\%04x%04x\\%s", m_wLang,
m_wCode, pwszName);
-
- LPCWSTR pwszResult = NULL;
- UINT cBytes = 0;
- if (!VerQueryValueW(m_pInfo, wszBuf, (LPVOID *)&pwszResult,
&cBytes))
- return NULL;
-
- return pwszResult;
- }
-
- VS_FIXEDFILEINFO *GetFixedInfo()
- {
- if (!m_pInfo)
- return NULL;
-
- VS_FIXEDFILEINFO *pInfo;
- UINT cBytes;
- if (!VerQueryValueW(m_pInfo, L"\\", (PVOID*)&pInfo,
&cBytes))
- return NULL;
- return pInfo;
- }
-
-
- private:
- PVOID m_pInfo;
- WORD m_wLang, m_wCode;
-};
-
-static VOID
-SH_FileGeneralOpensWith(HWND hwndDlg, LPCWSTR pwszExt)
-{
- WCHAR wszBuf[MAX_PATH] = L"";
- WCHAR wszPath[MAX_PATH] = L"";
- DWORD dwSize = sizeof(wszBuf);
-
- if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, L"", RRF_RT_REG_SZ, NULL,
wszBuf, &dwSize) == ERROR_SUCCESS)
- {
- StringCbCatW(wszBuf, sizeof(wszBuf), L"\\shell\\open\\command");
- dwSize = sizeof(wszPath);
- if (RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, L"", RRF_RT_REG_SZ, NULL,
wszPath, &dwSize) == ERROR_SUCCESS)
- {
- /* Get path from command line */
- ExpandEnvironmentStringsW(wszPath, wszBuf, _countof(wszBuf));
- PathRemoveArgs(wszBuf);
- PathUnquoteSpacesW(wszBuf);
- PathSearchAndQualify(wszBuf, wszPath, _countof(wszPath));
-
- if (PathFileExistsW(wszPath))
- {
- /* Get file description */
- CFileVersionInfo VerInfo;
- VerInfo.Load(wszPath);
- LPCWSTR pwszDescr = VerInfo.GetString(L"FileDescription");
- if (pwszDescr)
- SetDlgItemTextW(hwndDlg, 14007, pwszDescr);
- else
- {
- /* File has no description - display filename */
- LPWSTR pwszFilename = PathFindFileNameW(wszPath);
- PathRemoveExtension(pwszFilename);
- pwszFilename[0] = towupper(pwszFilename[0]);
- SetDlgItemTextW(hwndDlg, 14007, pwszFilename);
- }
- }
- else
- {
- /* Unknown application */
- LoadStringW(shell32_hInstance, IDS_UNKNOWN_APP, wszBuf,
_countof(wszBuf));
- SetDlgItemTextW(hwndDlg, 14007, wszBuf);
- }
- } else
- WARN("RegGetValueW %ls failed\n", wszBuf);
- } else
- WARN("RegGetValueW %ls failed\n", pwszExt);
-
-
-}
-
-/*************************************************************************
- *
- * SH_FormatFileSizeWithBytes
- *
- * Format a size in bytes to string.
- *
- * lpQwSize = Pointer to 64bit large integer to format
- * pszBuf = Buffer to fill with output string
- * cchBuf = size of pszBuf in characters
- *
- */
-
-LPWSTR
-SH_FormatFileSizeWithBytes(PULARGE_INTEGER lpQwSize, LPWSTR pszBuf, UINT cchBuf)
-{
- NUMBERFMTW nf;
- WCHAR szNumber[24];
- WCHAR szDecimalSep[8];
- WCHAR szThousandSep[8];
- WCHAR szGrouping[12];
- int Len, cchFormatted, i;
- size_t cchRemaining;
- LPWSTR Ptr;
-
- // Try to build first Format byte string
- if (StrFormatByteSizeW(lpQwSize->QuadPart, pszBuf, cchBuf) == NULL)
- return NULL;
-
- // If there is less bytes than 1KB, we have nothing to do
- if (lpQwSize->QuadPart < 1024)
- return pszBuf;
-
- // Print the number in uniform mode
- swprintf(szNumber, L"%I64u", lpQwSize->QuadPart);
-
- // Get system strings for decimal and thousand separators.
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szDecimalSep,
sizeof(szDecimalSep) / sizeof(*szDecimalSep));
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_STHOUSAND, szThousandSep,
sizeof(szThousandSep) / sizeof(*szThousandSep));
-
- // Initialize format for printing the number in bytes
- ZeroMemory(&nf, sizeof(nf));
- nf.NumDigits = 0;
- nf.LeadingZero = 0;
- nf.Grouping = 0;
- nf.lpDecimalSep = szDecimalSep;
- nf.lpThousandSep = szThousandSep;
- nf.NegativeOrder = 0;
-
- // Get system string for groups separator
- Len = GetLocaleInfoW(LOCALE_USER_DEFAULT,
- LOCALE_SGROUPING,
- szGrouping,
- sizeof(szGrouping) / sizeof(*szGrouping));
-
- // Convert grouping specs from string to integer
- for (i = 0; i < Len; i++)
- {
- WCHAR wch = szGrouping[i];
-
- if (wch >= L'0' && wch <= L'9')
- nf.Grouping = nf.Grouping * 10 + (wch - L'0');
- else if (wch != L';')
- break;
- }
-
- if ((nf.Grouping % 10) == 0)
- nf.Grouping /= 10;
- else
- nf.Grouping *= 10;
-
- // Concate " (" at the end of buffer
- Len = wcslen(pszBuf);
- Ptr = pszBuf + Len;
- cchRemaining = cchBuf - Len;
- StringCchCopyExW(Ptr, cchRemaining, L" (", &Ptr, &cchRemaining,
0);
-
- // Save formatted number of bytes in buffer
- cchFormatted = GetNumberFormatW(LOCALE_USER_DEFAULT,
- 0,
- szNumber,
- &nf,
- Ptr,
- cchRemaining);
-
- if (cchFormatted == 0)
- return NULL;
-
- // cchFormatted is number of characters including NULL - make it a real length
- --cchFormatted;
-
- // Copy ' ' to buffer
- Ptr += cchFormatted;
- cchRemaining -= cchFormatted;
- StringCchCopyExW(Ptr, cchRemaining, L" ", &Ptr, &cchRemaining, 0);
-
- // Copy 'bytes' string and remaining ')'
- Len = LoadStringW(shell32_hInstance, IDS_BYTES_FORMAT, Ptr, cchRemaining);
- Ptr += Len;
- cchRemaining -= Len;
- StringCchCopy(Ptr, cchRemaining, L")");
-
- return pszBuf;
-}
-
-/*************************************************************************
- *
- * SH_CreatePropertySheetPage [Internal]
- *
- * creates a property sheet page from an resource name
- *
- */
-
-HPROPSHEETPAGE
-SH_CreatePropertySheetPage(LPCSTR pwszResName, DLGPROC pfnDlgProc, LPARAM lParam, LPWSTR
pwszTitle)
-{
- if (pwszResName == NULL)
- return NULL;
-
- HRSRC hRes = FindResourceA(shell32_hInstance, pwszResName, (LPSTR)RT_DIALOG);
- if (hRes == NULL)
- {
- ERR("failed to find resource name\n");
- return NULL;
- }
-
- LPVOID pTemplate = LoadResource(shell32_hInstance, hRes);
- if (pTemplate == NULL)
- {
- ERR("failed to load resource\n");
- return NULL;
- }
-
- PROPSHEETPAGEW Page;
- memset(&Page, 0x0, sizeof(PROPSHEETPAGEW));
- Page.dwSize = sizeof(PROPSHEETPAGEW);
- Page.dwFlags = PSP_DLGINDIRECT;
- Page.pResource = (DLGTEMPLATE*)pTemplate;
- Page.pfnDlgProc = pfnDlgProc;
- Page.lParam = lParam;
- Page.pszTitle = pwszTitle;
-
- if (pwszTitle)
- Page.dwFlags |= PSP_USETITLE;
-
- return CreatePropertySheetPageW(&Page);
-}
-
-/*************************************************************************
- *
- * SH_FileGeneralFileType [Internal]
- *
- * retrieves file extension description from registry and sets it in dialog
- *
- * TODO: retrieve file extension default icon and load it
- * find executable name from registry, retrieve description from executable
- */
-
-static BOOL
-SH_FileGeneralSetFileType(HWND hwndDlg, LPCWSTR pwszPath)
-{
- TRACE("path %s\n", debugstr_w(pwszPath));
-
- if (pwszPath == NULL || !pwszPath[0])
- return FALSE;
-
- HWND hDlgCtrl = GetDlgItem(hwndDlg, 14005);
- if (hDlgCtrl == NULL)
- return FALSE;
-
- /* Get file information */
- SHFILEINFO fi;
- if (!SHGetFileInfoW(pwszPath, 0, &fi, sizeof(fi), SHGFI_TYPENAME|SHGFI_ICON))
- {
- ERR("SHGetFileInfoW failed for %ls (%lu)\n", pwszPath,
GetLastError());
- fi.szTypeName[0] = L'\0';
- fi.hIcon = NULL;
- }
-
- LPCWSTR pwszExt = PathFindExtensionW(pwszPath);
- if (pwszExt[0])
- {
- WCHAR wszBuf[256];
-
- if (!fi.szTypeName[0])
- {
- /* The file type is unknown, so default to string "FileExtension
File" */
- size_t cchRemaining = 0;
- LPWSTR pwszEnd = NULL;
-
- StringCchPrintfExW(wszBuf, _countof(wszBuf), &pwszEnd, &cchRemaining,
0, L"%s ", pwszExt + 1);
- SendMessageW(hDlgCtrl, WM_GETTEXT, (WPARAM)cchRemaining, (LPARAM)pwszEnd);
-
- SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)wszBuf);
- }
- else
- {
- /* Update file type */
- StringCbPrintfW(wszBuf, sizeof(wszBuf), L"%s (%s)", fi.szTypeName,
pwszExt);
- SendMessageW(hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)wszBuf);
- }
- }
-
- /* Update file icon */
- if (fi.hIcon)
- SendDlgItemMessageW(hwndDlg, 14000, STM_SETICON, (WPARAM)fi.hIcon, 0);
- else
- ERR("No icon %ls\n", pwszPath);
-
- return TRUE;
-}
-
-/*************************************************************************
- *
- * SHFileGeneralGetFileTimeString [Internal]
- *
- * formats a given LPFILETIME struct into readable user format
- */
-
-static BOOL
-SHFileGeneralGetFileTimeString(LPFILETIME lpFileTime, WCHAR *lpResult)
-{
- FILETIME ft;
- SYSTEMTIME st;
-
- if (lpFileTime == NULL || lpResult == NULL)
- return FALSE;
-
- if (!FileTimeToLocalFileTime(lpFileTime, &ft))
- return FALSE;
-
- FileTimeToSystemTime(&ft, &st);
-
- /* ddmmyy */
- swprintf(lpResult, L"%02hu/%02hu/%04hu %02hu:%02hu", st.wDay, st.wMonth,
st.wYear, st.wHour, st.wMinute);
-
- TRACE("result %s\n", debugstr_w(lpResult));
- return TRUE;
-}
-
-/*************************************************************************
- *
- * SH_FileGeneralSetText [Internal]
- *
- * sets file path string and filename string
- *
- */
-
-static BOOL
-SH_FileGeneralSetText(HWND hwndDlg, LPCWSTR pwszPath)
-{
- if (pwszPath == NULL)
- return FALSE;
-
- /* Find the filename */
- WCHAR *pwszFilename = PathFindFileNameW(pwszPath);
-
- if (pwszFilename > pwszPath)
- {
- /* Location field */
- WCHAR wszLocation[MAX_PATH];
- StringCchCopyNW(wszLocation, _countof(wszLocation), pwszPath, pwszFilename -
pwszPath);
- PathRemoveBackslashW(wszLocation);
-
- SetDlgItemTextW(hwndDlg, 14009, wszLocation);
- }
-
- /* Filename field */
- SetDlgItemTextW(hwndDlg, 14001, pwszFilename);
-
- return TRUE;
-}
-
-/*************************************************************************
- *
- * SH_FileGeneralSetFileSizeTime [Internal]
- *
- * retrieves file information from file and sets in dialog
- *
- */
-
-static BOOL
-SH_FileGeneralSetFileSizeTime(HWND hwndDlg, LPCWSTR pwszPath)
-{
- HANDLE hFile;
- FILETIME CreateTime;
- FILETIME AccessedTime;
- FILETIME WriteTime;
- WCHAR wszBuf[MAX_PATH];
- LARGE_INTEGER FileSize;
-
- if (pwszPath == NULL)
- return FALSE;
-
- TRACE("SH_FileGeneralSetFileSizeTime %ls\n", pwszPath);
-
- hFile = CreateFileW(pwszPath,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
- if (hFile == INVALID_HANDLE_VALUE)
- {
- WARN("failed to open file %s\n", debugstr_w(pwszPath));
- return FALSE;
- }
-
- if (!GetFileTime(hFile, &CreateTime, &AccessedTime, &WriteTime))
- {
- WARN("GetFileTime failed\n");
- CloseHandle(hFile);
- return FALSE;
- }
-
- if (!GetFileSizeEx(hFile, &FileSize))
- {
- WARN("GetFileSize failed\n");
- CloseHandle(hFile);
- return FALSE;
- }
-
- CloseHandle(hFile);
-
- if (SHFileGeneralGetFileTimeString(&CreateTime, wszBuf))
- SetDlgItemTextW(hwndDlg, 14015, wszBuf);
-
- if (SHFileGeneralGetFileTimeString(&AccessedTime, wszBuf))
- SetDlgItemTextW(hwndDlg, 14019, wszBuf);
-
- if (SHFileGeneralGetFileTimeString(&WriteTime, wszBuf))
- SetDlgItemTextW(hwndDlg, 14017, wszBuf);
-
- if (SH_FormatFileSizeWithBytes((PULARGE_INTEGER)&FileSize,
- wszBuf,
- sizeof(wszBuf) / sizeof(WCHAR)))
- {
- SetDlgItemTextW(hwndDlg, 14011, wszBuf);
- }
-
- return TRUE;
-}
-
-/*************************************************************************
- *
- * SH_SetFileVersionText [Internal]
- *
- *
- */
-
-static BOOL
-SH_FileVersionQuerySetText(HWND hwndDlg, DWORD idCtrl, CFileVersionInfo *pVerInfo,
LPCWSTR pwszName)
-{
- if (hwndDlg == NULL || pwszName == NULL)
- return FALSE;
-
- LPCWSTR pwszValue = pVerInfo->GetString(pwszName);
- if (pwszValue)
- {
- /* file description property */
- TRACE("%s :: %s\n", debugstr_w(pwszName), debugstr_w(pwszValue));
- SetDlgItemTextW(hwndDlg, idCtrl, pwszValue);
- return TRUE;
- }
-
- return FALSE;
-}
-
-/*************************************************************************
- *
- * SH_FileVersionQuerySetListText [Internal]
- *
- * retrieves a version string and adds it to listbox
- *
- */
-
-static BOOL
-SH_FileVersionQuerySetListText(HWND hwndDlg, CFileVersionInfo *pVerInfo, LPCWSTR
pwszName)
-{
- TRACE("pwszName %s, hwndDlg %p\n", debugstr_w(pwszName), hwndDlg);
-
- if (hwndDlg == NULL || pwszName == NULL)
- return FALSE;
-
- LPCWSTR pwszValue = pVerInfo->GetString(pwszName);
- if (pwszValue)
- {
- /* listbox name property */
- HWND hDlgCtrl = GetDlgItem(hwndDlg, 14009);
- TRACE("%s :: %s\n", debugstr_w(pwszName), debugstr_w(pwszValue));
- UINT Index = SendMessageW(hDlgCtrl, LB_ADDSTRING, (WPARAM) -1,
(LPARAM)pwszName);
- SendMessageW(hDlgCtrl, LB_SETITEMDATA, (WPARAM)Index, (LPARAM)(WCHAR
*)pwszValue);
- return TRUE;
- }
-
- return FALSE;
-}
-
-/*************************************************************************
- *
- * SH_FileVersionInitialize [Internal]
- *
- * sets all file version properties in dialog
- */
-
-static BOOL
-SH_FileVersionInitialize(HWND hwndDlg, LPCWSTR pwszPath)
-{
- if (pwszPath == NULL)
- return FALSE;
-
- /* Get file version info */
- CFileVersionInfo *pVerInfo;
- pVerInfo = new CFileVersionInfo;
- if (!pVerInfo || !pVerInfo->Load(pwszPath))
- return FALSE;
-
- /* Get fixed info */
- VS_FIXEDFILEINFO *pInfo = pVerInfo->GetFixedInfo();
- if (pInfo)
- {
- WCHAR wszVersion[256];
- swprintf(wszVersion, L"%u.%u.%u.%u",
HIWORD(pInfo->dwFileVersionMS),
- LOWORD(pInfo->dwFileVersionMS),
- HIWORD(pInfo->dwFileVersionLS),
- LOWORD(pInfo->dwFileVersionLS));
- TRACE("MS %x LS %x ver %s \n", pInfo->dwFileVersionMS,
pInfo->dwFileVersionLS, debugstr_w(wszVersion));
- SetDlgItemTextW(hwndDlg, 14001, wszVersion);
- }
-
- /* Update labels */
- SH_FileVersionQuerySetText(hwndDlg, 14003, pVerInfo, L"FileDescription");
- SH_FileVersionQuerySetText(hwndDlg, 14005, pVerInfo, L"LegalCopyright");
-
- /* Add items to listbox */
- SH_FileVersionQuerySetListText(hwndDlg, pVerInfo, L"CompanyName");
- /* FIXME insert language identifier */
- SH_FileVersionQuerySetListText(hwndDlg, pVerInfo, L"ProductName");
- SH_FileVersionQuerySetListText(hwndDlg, pVerInfo, L"InternalName");
- SH_FileVersionQuerySetListText(hwndDlg, pVerInfo, L"OriginalFilename");
- SH_FileVersionQuerySetListText(hwndDlg, pVerInfo, L"FileVersion");
- SH_FileVersionQuerySetListText(hwndDlg, pVerInfo, L"ProductVersion");
-
- /* Attach file version to dialog window */
- SetWindowLongPtr(hwndDlg, DWL_USER, (LONG_PTR)pVerInfo);
-
- /* Select first item */
- HWND hDlgCtrl = GetDlgItem(hwndDlg, 14009);
- SendMessageW(hDlgCtrl, LB_SETCURSEL, 0, 0);
- LPCWSTR pwszText = (WCHAR *)SendMessageW(hDlgCtrl, LB_GETITEMDATA, (WPARAM)0,
(LPARAM)NULL);
- SetDlgItemTextW(hwndDlg, 14010, pwszText);
-
- return TRUE;
-}
-
-/*************************************************************************
- *
- * SH_FileVersionDlgProc
- *
- * wnd proc of 'Version' property sheet page
- */
-
-INT_PTR CALLBACK
-SH_FileVersionDlgProc(HWND hwndDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- switch (uMsg)
- {
- case WM_INITDIALOG:
- {
- LPPROPSHEETPAGE ppsp = (LPPROPSHEETPAGE)lParam;
-
- if (ppsp == NULL)
- break;
-
- TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %x\n", hwndDlg,
lParam, ppsp->lParam);
-
- LPCWSTR pwszFilename = (LPCWSTR)ppsp->lParam;
-
- if (pwszFilename == NULL)
- break;
-
- return SH_FileVersionInitialize(hwndDlg, pwszFilename);
- }
- case WM_COMMAND:
- if (LOWORD(wParam) == 14009 && HIWORD(wParam) == LBN_SELCHANGE)
- {
- HWND hDlgCtrl = (HWND)lParam;
-
- LRESULT Index = SendMessageW(hDlgCtrl, LB_GETCURSEL, (WPARAM)NULL,
(LPARAM)NULL);
- if (Index == LB_ERR)
- break;
-
- LPCWSTR pwszData = (LPCWSTR)SendMessageW(hDlgCtrl, LB_GETITEMDATA,
(WPARAM)Index, (LPARAM)NULL);
- if (pwszData == NULL)
- break;
-
- TRACE("hDlgCtrl %x string %s\n", hDlgCtrl,
debugstr_w(pwszData));
- SetDlgItemTextW(hwndDlg, 14010, pwszData);
-
- return TRUE;
- }
- break;
- case WM_DESTROY:
- {
- CFileVersionInfo *pVerInfo = (CFileVersionInfo*)GetWindowLongPtr(hwndDlg,
DWL_USER);
- if (pVerInfo)
- delete pVerInfo;
- break;
- }
- default:
- break;
- }
-
- return FALSE;
-}
-
-/*************************************************************************
- *
- * SH_FileGeneralDlgProc
- *
- * wnd proc of 'General' property sheet page
- *
- */
-
-INT_PTR CALLBACK
-SH_FileGeneralDlgProc(HWND hwndDlg,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- switch (uMsg)
- {
- case WM_INITDIALOG:
- {
- LPPROPSHEETPAGEW ppsp = (LPPROPSHEETPAGEW)lParam;
-
- if (ppsp == NULL)
- break;
-
- TRACE("WM_INITDIALOG hwnd %p lParam %p ppsplParam %S\n", hwndDlg,
lParam, ppsp->lParam);
-
- LPCWSTR pwszPath = (WCHAR *)ppsp->lParam;
- if (pwszPath == NULL)
- {
- ERR("no path\n");
- break;
- }
-
- /* Set general text properties filename filelocation and icon */
- SH_FileGeneralSetText(hwndDlg, pwszPath);
-
- /* Set file type and icon */
- SH_FileGeneralSetFileType(hwndDlg, pwszPath);
-
- /* Set open with application */
- if (!PathIsExeW(pwszPath))
- SH_FileGeneralOpensWith(hwndDlg, PathFindExtensionW(pwszPath));
-
- /* Set file created/modfied/accessed time */
- SH_FileGeneralSetFileSizeTime(hwndDlg, pwszPath);
-
- return TRUE;
- }
- default:
- break;
- }
-
- return FALSE;
-}
static BOOL CALLBACK
AddPropSheetPageCallback(HPROPSHEETPAGE hPage, LPARAM lParam)
@@ -844,31 +129,29 @@
Header.phpage = hppages;
Header.pszCaption = PathFindFileNameW(wszPath);
- hppages[Header.nPages] =
- SH_CreatePropertySheetPage("SHELL_FILE_GENERAL_DLG",
- SH_FileGeneralDlgProc,
- (LPARAM)wszPath,
- NULL);
-
- if (hppages[Header.nPages])
- Header.nPages++;
-
- if (GetFileVersionInfoSizeW(wszPath, NULL) && Header.nPages <
_countof(hppages))
- {
- hppages[Header.nPages] =
- SH_CreatePropertySheetPage("SHELL_FILE_VERSION_DLG",
- SH_FileVersionDlgProc,
- (LPARAM)wszPath,
- NULL);
- if (hppages[Header.nPages])
- Header.nPages++;
- }
-
CComPtr<IDataObject> pDataObj;
hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_IDataObject, (LPVOID
*)&pDataObj);
if (SUCCEEDED(hr))
+ {
+ CComObject<CFileDefExt> *pFileDefExt;
+ ATLTRY(pFileDefExt = new CComObject<CFileDefExt>);
+ if (pFileDefExt)
+ {
+ hr = pFileDefExt->Initialize(pidlFolder, pDataObj, NULL);
+ if (SUCCEEDED(hr))
+ {
+ hr = pFileDefExt->AddPages(AddPropSheetPageCallback,
(LPARAM)&Header);
+ if (FAILED(hr))
+ ERR("AddPages failed\n");
+ } else
+ ERR("Initialize failed\n");
+
+ pFileDefExt->Release();
+ }
+
LoadPropSheetHandlers(wszPath, &Header, MAX_PROPERTY_SHEET_PAGE - 1, hpsxa,
pDataObj);
+ }
INT_PTR Result = PropertySheetW(&Header);
Modified: trunk/reactos/dll/win32/shell32/precomp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/precomp.…
==============================================================================
--- trunk/reactos/dll/win32/shell32/precomp.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/precomp.h [iso-8859-1] Wed Jan 11 20:20:01 2012
@@ -82,6 +82,8 @@
#include "openwithmenu.h"
#include "newmenu.h"
#include "startmenu.h"
+#include "filedefext.h"
+#include "drvdefext.h"
#include "wine/debug.h"
#include "wine/unicode.h"
@@ -96,5 +98,4 @@
extern const GUID SHELL32_AdvtShortcutProduct;
extern const GUID SHELL32_AdvtShortcutComponent;
-
#endif
Added: trunk/reactos/dll/win32/shell32/res/rgs/shellfiledefext.rgs
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/res/rgs/…
==============================================================================
--- trunk/reactos/dll/win32/shell32/res/rgs/shellfiledefext.rgs (added)
+++ trunk/reactos/dll/win32/shell32/res/rgs/shellfiledefext.rgs [iso-8859-1] Wed Jan 11
20:20:01 2012
@@ -1,0 +1,13 @@
+HKCR
+{
+ NoRemove CLSID
+ {
+ ForceRemove {21B22460-3AEA-1069-A2DC-08002B30309D} = s 'File Default
Extension'
+ {
+ InprocServer32 = s '%MODULE%'
+ {
+ val ThreadingModel = s 'Apartment'
+ }
+ }
+ }
+}
Modified: trunk/reactos/dll/win32/shell32/rgs_res.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/rgs_res.…
==============================================================================
--- trunk/reactos/dll/win32/shell32/rgs_res.rc [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/rgs_res.rc [iso-8859-1] Wed Jan 11 20:20:01 2012
@@ -21,3 +21,4 @@
IDR_SHELLLINK REGISTRY "res\\rgs\\shelllink.rgs"
IDR_STARTMENU REGISTRY "res\\rgs\\startmenu.rgs"
IDR_OPENWITHMENU REGISTRY "res\\rgs\\openwithmenu.rgs"
+IDR_FILEDEFEXT REGISTRY
"res\\rgs\\shellfiledefext.rgs"
Modified: trunk/reactos/dll/win32/shell32/shell32.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shell32.…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shell32.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/shell32.rbuild [iso-8859-1] Wed Jan 11 20:20:01 2012
@@ -84,6 +84,8 @@
<file>openwithmenu.cpp</file>
<file>newmenu.cpp</file>
<file>folder_options.cpp</file>
+ <file>filedefext.cpp</file>
+ <file>drvdefext.cpp</file>
<file>shell32.rc</file>
</module>
<module name="shobjidl_local_interface" type="idlinterface">
Modified: trunk/reactos/dll/win32/shell32/shresdef.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shresdef…
==============================================================================
--- trunk/reactos/dll/win32/shell32/shresdef.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/shresdef.h [iso-8859-1] Wed Jan 11 20:20:01 2012
@@ -476,5 +476,7 @@
#define IDR_SHELLLINK 144
#define IDR_STARTMENU 145
#define IDR_OPENWITHMENU 146
+#define IDR_FILEDEFEXT 147
+#define IDR_DRVDEFEXT 148
#endif
Modified: trunk/reactos/include/psdk/shlguid_undoc.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/shlguid_undoc…
==============================================================================
--- trunk/reactos/include/psdk/shlguid_undoc.h [iso-8859-1] (original)
+++ trunk/reactos/include/psdk/shlguid_undoc.h [iso-8859-1] Wed Jan 11 20:20:01 2012
@@ -19,6 +19,7 @@
#ifndef __SHLGUID_UNDOC_H
#define __SHLGUID_UNDOC_H
+
DEFINE_GUID(CLSID_RebarBandSite, 0xECD4FC4D, 0x521C, 0x11D0, 0xB7, 0x92, 0x00,
0xA0, 0xC9, 0x03, 0x12, 0xE1);
DEFINE_GUID(CLSID_BandSiteMenu, 0xECD4FC4E, 0x521C, 0x11D0, 0xB7, 0x92, 0x00,
0xA0, 0xC9, 0x03, 0x12, 0xE1);
DEFINE_GUID(IID_IBandSiteHelper, 0xD1E7AFEA, 0x6A2E, 0x11D0, 0x8C, 0x78, 0x00,
0xC0, 0x4F, 0xD9, 0x18, 0xB4);
@@ -97,8 +98,12 @@
DEFINE_GUID(CLSID_FolderOptions, 0x6DFD7C5C, 0x2451, 0x11D3, 0xA2, 0x99, 0x00,
0xC0, 0x4F, 0x8E, 0xF6, 0xAF);
+DEFINE_GUID(CLSID_ShellFileDefExt, 0x21B22460, 0x3AEA, 0x1069, 0xA2, 0xDC, 0x08,
0x00, 0x2B, 0x30, 0x30, 0x9D);
+DEFINE_GUID(CLSID_ShellDrvDefExt, 0x5F5295E0, 0x429F, 0x1069, 0xA2, 0xE2, 0x08,
0x00, 0x2B, 0x30, 0x30, 0x9D);
+DEFINE_GUID(CLSID_ShellNetDefExt, 0x86422020, 0x42A0, 0x1069, 0xA2, 0xE5, 0x08,
0x00, 0x2B, 0x30, 0x30, 0x9D);
+
// In theory, this is documented. But until I see an SDK header that defines it, it will
be treated as undocumented...
-DEFINE_GUID(CLSID_ShellItem, 0x2fe352ea, 0xfd1f, 0x11d2, 0xb1, 0xf4, 0x00,
0xc0, 0x4f, 0x8e, 0xeb, 0x3e);
+DEFINE_GUID(CLSID_ShellItem, 0x2FE352EA, 0xFD1F, 0x11D2, 0xB1, 0xF4, 0x00,
0xC0, 0x4F, 0x8E, 0xEB, 0x3E);
#define CGID_IExplorerToolbar IID_IExplorerToolbar
#define SID_IExplorerToolbar IID_IExplorerToolbar