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.cpp?rev=71980&r1=71979&r2=71980&view=diff
==============================================================================
--- 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.h?rev=71980&r1=71979&r2=71980&view=diff
==============================================================================
--- 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()
 };
 


Reply via email to