Author: cwittich
Date: Sat Jul 23 12:31:30 2016
New Revision: 71980
URL:
http://svn.reactos.org/svn/reactos?rev=71980&view=rev
Log:
[SHELL32] cache entries of "New" menu
CORE-10439
Modified:
trunk/reactos/dll/win32/shell32/CNewMenu.cpp
trunk/reactos/dll/win32/shell32/CNewMenu.h
Modified: trunk/reactos/dll/win32/shell32/CNewMenu.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CNewMenu…
==============================================================================
--- trunk/reactos/dll/win32/shell32/CNewMenu.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/CNewMenu.cpp [iso-8859-1] Sat Jul 23 12:31:30 2016
@@ -163,17 +163,18 @@
}
BOOL
-CNewMenu::LoadAllItems()
-{
+CNewMenu::CacheItems()
+{
+ HKEY hKey;
+ DWORD dwSize = 0;
DWORD dwIndex = 0;
+ LPWSTR lpValue;
+ LPWSTR lpValues;
WCHAR wszName[MAX_PATH];
SHELLNEW_ITEM *pNewItem;
SHELLNEW_ITEM *pCurItem = NULL;
- /* If there are any unload them */
- UnloadAllItems();
-
- /* Enumerate all extesions */
+ /* Enumerate all extensions */
while (RegEnumKeyW(HKEY_CLASSES_ROOT, dwIndex++, wszName, _countof(wszName)) ==
ERROR_SUCCESS)
{
if (wszName[0] != L'.')
@@ -182,6 +183,7 @@
pNewItem = LoadItem(wszName);
if (pNewItem)
{
+ dwSize += wcslen(wszName) + 1;
if (wcsicmp(pNewItem->pwszExt, L".lnk") == 0)
{
/* Link handler */
@@ -200,7 +202,109 @@
}
}
}
-
+
+ dwSize++;
+
+ lpValues = (LPWSTR) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize *
sizeof(WCHAR));
+ if (!lpValues)
+ return FALSE;
+
+ lpValue = lpValues;
+ pCurItem = m_pItems;
+ while (pCurItem)
+ {
+ memcpy(lpValue, pCurItem->pwszExt, (wcslen(pCurItem->pwszExt) + 1) *
sizeof(WCHAR));
+ lpValue += wcslen(pCurItem->pwszExt) + 1;
+ pCurItem = pCurItem->pNext;
+ }
+
+ if (RegCreateKeyEx(HKEY_CURRENT_USER, ShellNewKey, 0, NULL, REG_OPTION_NON_VOLATILE,
KEY_WRITE, NULL, &hKey, NULL) != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(), 0, lpValues);
+ return FALSE;
+ }
+
+ if (RegSetValueExW(hKey, L"Classes", NULL, REG_MULTI_SZ, (LPBYTE)lpValues,
dwSize) != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(), 0, lpValues);
+ return FALSE;
+ }
+
+ HeapFree(GetProcessHeap(), 0, lpValues);
+ RegCloseKey(hKey);
+
+ return TRUE;
+}
+
+BOOL
+CNewMenu::LoadCachedItems()
+{
+ LPWSTR wszName;
+ LPWSTR lpValues;
+ DWORD dwSize;
+ HKEY hKey;
+ SHELLNEW_ITEM *pNewItem;
+ SHELLNEW_ITEM *pCurItem = NULL;
+
+ if (RegOpenKeyExW(HKEY_CURRENT_USER, ShellNewKey, 0, KEY_READ, &hKey) !=
ERROR_SUCCESS)
+ return FALSE;
+
+ if (RegQueryValueExW(hKey, L"Classes", NULL, NULL, NULL, &dwSize) !=
ERROR_SUCCESS)
+ return FALSE;
+
+ lpValues = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, dwSize);
+ if (!lpValues)
+ return FALSE;
+
+ if (RegQueryValueExW(hKey, L"Classes", NULL, NULL, (LPBYTE)lpValues,
&dwSize) != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(), 0, lpValues);
+ return FALSE;
+ }
+
+ wszName = lpValues;
+
+ for (; '\0' != *wszName; wszName += wcslen(wszName) + 1)
+ {
+ pNewItem = LoadItem(wszName);
+ if (pNewItem)
+ {
+ if (wcsicmp(pNewItem->pwszExt, L".lnk") == 0)
+ {
+ /* Link handler */
+ m_pLinkItem = pNewItem;
+ }
+ else
+ {
+ /* Add at the end of list */
+ if (pCurItem)
+ {
+ pCurItem->pNext = pNewItem;
+ pCurItem = pNewItem;
+ }
+ else
+ pCurItem = m_pItems = pNewItem;
+ }
+ }
+ }
+
+ HeapFree(GetProcessHeap(), 0, lpValues);
+ RegCloseKey(hKey);
+
+ return TRUE;
+}
+
+BOOL
+CNewMenu::LoadAllItems()
+{
+ /* If there are any unload them */
+ UnloadAllItems();
+
+ if (!LoadCachedItems())
+ {
+ CacheItems();
+ }
+
if (!m_pLinkItem)
{
m_pLinkItem = static_cast<SHELLNEW_ITEM *>(HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(SHELLNEW_ITEM)));
Modified: trunk/reactos/dll/win32/shell32/CNewMenu.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/CNewMenu…
==============================================================================
--- trunk/reactos/dll/win32/shell32/CNewMenu.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/CNewMenu.h [iso-8859-1] Sat Jul 23 12:31:30 2016
@@ -23,33 +23,35 @@
#ifndef _SHV_ITEM_NEW_H_
#define _SHV_ITEM_NEW_H_
+const WCHAR ShellNewKey[] =
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Discardable\\PostSetup\\ShellNew";
+
class CNewMenu :
- public CComCoClass<CNewMenu, &CLSID_NewMenu>,
- public CComObjectRootEx<CComMultiThreadModelNoCS>,
- public IObjectWithSite,
- public IContextMenu3,
- public IShellExtInit
+ public CComCoClass<CNewMenu, &CLSID_NewMenu>,
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IObjectWithSite,
+ public IContextMenu3,
+ public IShellExtInit
{
private:
- enum SHELLNEW_TYPE
- {
- SHELLNEW_TYPE_INVALID = -1,
- SHELLNEW_TYPE_COMMAND = 1,
- SHELLNEW_TYPE_DATA = 2,
- SHELLNEW_TYPE_FILENAME = 4,
- SHELLNEW_TYPE_NULLFILE = 8
- };
+ enum SHELLNEW_TYPE
+ {
+ SHELLNEW_TYPE_INVALID = -1,
+ SHELLNEW_TYPE_COMMAND = 1,
+ SHELLNEW_TYPE_DATA = 2,
+ SHELLNEW_TYPE_FILENAME = 4,
+ SHELLNEW_TYPE_NULLFILE = 8
+ };
- struct SHELLNEW_ITEM
- {
- SHELLNEW_TYPE Type;
- LPWSTR pwszExt;
- PBYTE pData;
- ULONG cbData;
- LPWSTR pwszDesc;
- HICON hIcon;
- SHELLNEW_ITEM *pNext;
- };
+ struct SHELLNEW_ITEM
+ {
+ SHELLNEW_TYPE Type;
+ LPWSTR pwszExt;
+ PBYTE pData;
+ ULONG cbData;
+ LPWSTR pwszDesc;
+ HICON hIcon;
+ SHELLNEW_ITEM *pNext;
+ };
LPITEMIDLIST m_pidlFolder;
LPWSTR m_wszPath;
@@ -62,35 +64,37 @@
SHELLNEW_ITEM *LoadItem(LPCWSTR pwszExt);
void UnloadItem(SHELLNEW_ITEM *pItem);
- void UnloadAllItems();
- BOOL LoadAllItems();
- UINT InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu);
- SHELLNEW_ITEM *FindItemFromIdOffset(UINT IdOffset);
- HRESULT CreateNewFolder(LPCMINVOKECOMMANDINFO lpici);
- HRESULT CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi);
+ void UnloadAllItems();
+ BOOL CacheItems();
+ BOOL LoadCachedItems();
+ BOOL LoadAllItems();
+ UINT InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu);
+ SHELLNEW_ITEM *FindItemFromIdOffset(UINT IdOffset);
+ HRESULT CreateNewFolder(LPCMINVOKECOMMANDINFO lpici);
+ HRESULT CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi);
HRESULT SelectNewItem(LPCMINVOKECOMMANDINFO lpici, LONG wEventId, UINT uFlags, LPWSTR
pszName);
public:
- CNewMenu();
- ~CNewMenu();
+ CNewMenu();
+ ~CNewMenu();
- // IObjectWithSite
- virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite);
- virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite);
+ // IObjectWithSite
+ virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite);
+ virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite);
- // IContextMenu
- virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst,
UINT idCmdLast, UINT uFlags);
- virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
- virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT
*lpReserved, LPSTR lpszName, UINT uMaxNameLen);
+ // IContextMenu
+ virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst,
UINT idCmdLast, UINT uFlags);
+ virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi);
+ virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT
*lpReserved, LPSTR lpszName, UINT uMaxNameLen);
- // IContextMenu3
- virtual HRESULT WINAPI HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT
*plResult);
+ // IContextMenu3
+ virtual HRESULT WINAPI HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam,
LRESULT *plResult);
- // IContextMenu2
- virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
+ // IContextMenu2
+ virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam);
- // IShellExtInit
- virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidlFolder, IDataObject
*pdtobj, HKEY hkeyProgID);
+ // IShellExtInit
+ virtual HRESULT STDMETHODCALLTYPE Initialize(LPCITEMIDLIST pidlFolder, IDataObject
*pdtobj, HKEY hkeyProgID);
DECLARE_REGISTRY_RESOURCEID(IDR_NEWMENU)
DECLARE_NOT_AGGREGATABLE(CNewMenu)
@@ -98,11 +102,11 @@
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CNewMenu)
- COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
- COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
- COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
- COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
- COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
+ COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
+ COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
+ COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
END_COM_MAP()
};