Author: rharabien
Date: Mon Jan 9 23:01:01 2012
New Revision: 54894
URL:
http://svn.reactos.org/svn/reactos?rev=54894&view=rev
Log:
[SHELL32]
- Add item icons to New menu
- Fix some leaks in New menu
- Properly handle New Folder and New Link items
Modified:
trunk/reactos/dll/win32/shell32/newmenu.cpp
trunk/reactos/dll/win32/shell32/newmenu.h
trunk/reactos/dll/win32/shell32/openwithmenu.cpp
trunk/reactos/dll/win32/shell32/openwithmenu.h
Modified: trunk/reactos/dll/win32/shell32/newmenu.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/newmenu.…
==============================================================================
--- trunk/reactos/dll/win32/shell32/newmenu.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/newmenu.cpp [iso-8859-1] Mon Jan 9 23:01:01 2012
@@ -3,6 +3,7 @@
*
* 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
@@ -26,132 +27,83 @@
CNewMenu::CNewMenu()
{
m_wszPath = NULL;
- m_pShellItems = NULL;
+ m_pItems = NULL;
+ m_pLinkItem = NULL;
m_pSite = NULL;
+ m_hbmFolder = NULL;
+ m_hbmLink = NULL;
}
CNewMenu::~CNewMenu()
{
- UnloadShellItems();
- if (m_hSubMenu)
- CleanupMenu();
-}
-
-void CNewMenu::CleanupMenu()
-{
- INT Count, Index;
- MENUITEMINFOW mii;
-
- /* get item count */
- Count = GetMenuItemCount(m_hSubMenu);
- if (Count == -1)
- return;
-
- /* setup menuitem info */
- ZeroMemory(&mii, sizeof(mii));
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_DATA | MIIM_FTYPE | MIIM_CHECKMARKS;
-
- for(Index = 0; Index < Count; Index++)
- {
- if (GetMenuItemInfoW(m_hSubMenu, Index, TRUE, &mii))
- {
- if (mii.hbmpChecked)
- DeleteObject(mii.hbmpChecked);
- }
- }
+ UnloadAllItems();
+ if (m_hbmFolder)
+ DeleteObject(m_hbmFolder);
+ if (m_hbmLink)
+ DeleteObject(m_hbmLink);
}
void CNewMenu::UnloadItem(SHELLNEW_ITEM *pItem)
{
- // bail if the item is clearly invalid
- if (NULL == pItem)
- return;
-
- if (NULL != pItem->pwszTarget)
- free(pItem->pwszTarget);
-
+ /* Note: free allows NULL as argument */
+ free(pItem->pData);
free(pItem->pwszDesc);
- free(pItem->pwszIcon);
free(pItem->pwszExt);
+ if (pItem->hBitmap)
+ DeleteObject(pItem->hBitmap);
+
HeapFree(GetProcessHeap(), 0, pItem);
}
-void CNewMenu::UnloadShellItems()
+void CNewMenu::UnloadAllItems()
{
SHELLNEW_ITEM *pCurItem;
- while (m_pShellItems)
- {
- pCurItem = m_pShellItems;
- m_pShellItems = m_pShellItems->pNext;
+ /* Unload normal items */
+ while (m_pItems)
+ {
+ pCurItem = m_pItems;
+ m_pItems = m_pItems->pNext;
UnloadItem(pCurItem);
}
-}
-
-BOOL CNewMenu::GetKeyDescription(LPCWSTR pwszExt, LPWSTR pwszResult)
+
+ /* Unload link item */
+ if (m_pLinkItem)
+ UnloadItem(m_pLinkItem);
+ m_pLinkItem = NULL;
+}
+
+static HBITMAP IconToBitmap(HICON hIcon)
+{
+ HDC hdc, hdcScr;
+ HBITMAP hbm, hbmOld;
+ RECT rc;
+
+ hdcScr = GetDC(NULL);
+ hdc = CreateCompatibleDC(hdcScr);
+ SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXMENUCHECK),
GetSystemMetrics(SM_CYMENUCHECK));
+ hbm = CreateCompatibleBitmap(hdcScr, rc.right, rc.bottom);
+ ReleaseDC(NULL, hdcScr);
+
+ hbmOld = (HBITMAP)SelectObject(hdc, hbm);
+ FillRect(hdc, &rc, (HBRUSH)(COLOR_MENU + 1));
+ if (!DrawIconEx(hdc, 0, 0, hIcon, rc.right, rc.bottom, 0, NULL, DI_NORMAL))
+ ERR("DrawIcon failed: %x\n", GetLastError());
+ SelectObject(hdc, hbmOld);
+
+ DeleteDC(hdc);
+
+ return hbm;
+}
+
+CNewMenu::SHELLNEW_ITEM *CNewMenu::LoadItem(LPCWSTR pwszExt)
{
HKEY hKey;
- DWORD cbDesc;
- WCHAR wszDesc[100];
- LONG Result;
-
- TRACE("GetKeyDescription: keyname %s\n", debugstr_w(pwszExt));
-
- if (RegOpenKeyExW(HKEY_CLASSES_ROOT, pwszExt, 0, KEY_READ, &hKey) !=
ERROR_SUCCESS)
- return FALSE;
-
- /* Get user friendly name */
- if (RegLoadMUIStringW(hKey, L"\\FriendlyTypeName", pwszResult, MAX_PATH,
&cbDesc, 0, NULL) == ERROR_SUCCESS)
- {
- TRACE("result %s\n", debugstr_w(pwszResult));
- RegCloseKey(hKey);
- return TRUE;
- }
-
- /* Fetch default value */
- cbDesc = sizeof(wszDesc);
- Result = RegGetValueW(hKey, NULL, L"", RRF_RT_REG_SZ, NULL, wszDesc,
&cbDesc);
- if(Result == ERROR_SUCCESS)
- {
- if (wcscmp(pwszExt, wszDesc) != 0)
- {
- /* recurse for to a linked key */
- if (!GetKeyDescription(wszDesc, pwszResult))
- {
- /* use description */
- wcscpy(pwszResult, wszDesc);
- }
- }
- else
- {
- /* use default value as description */
- wcscpy(pwszResult, wszDesc);
- }
- }
- else
- {
- /* registry key w/o default key?? */
- ERR("RegGetValue failed with %x\n", Result);
- wcscpy(pwszResult, pwszExt);
- }
-
- RegCloseKey(hKey);
- return TRUE;
-}
-
-CNewMenu::SHELLNEW_ITEM *CNewMenu::LoadItem(LPCWSTR pwszExt)
-{
- HKEY hKey;
- DWORD dwIndex = 0;
WCHAR wszBuf[MAX_PATH];
- WCHAR wszCommand[MAX_PATH];
- WCHAR wszDesc[MAX_PATH] = L"";
- WCHAR wszIcon[MAX_PATH] = L"";
- DWORD cchName, cbCommand;
- SHELLNEW_ITEM *pNewItem = NULL;
+ BYTE *pData = NULL;
+ DWORD cbData;
StringCbPrintfW(wszBuf, sizeof(wszBuf), L"%s\\ShellNew", pwszExt);
@@ -164,59 +116,68 @@
}
/* Find first valid value */
- while (TRUE)
- {
- cchName = _countof(wszBuf);
- cbCommand = sizeof(wszCommand);
- if (RegEnumValueW(hKey, dwIndex++, wszBuf, &cchName, NULL, NULL,
(LPBYTE)wszCommand, &cbCommand) != ERROR_SUCCESS)
- break;
-
- SHELLNEW_TYPE Type = SHELLNEW_TYPE_INVALID;
- LPWSTR pwszTarget = wszCommand;
-
- TRACE("wszBuf %s wszCommand %s\n", debugstr_w(wszBuf),
debugstr_w(wszCommand));
-
- /* Handle different types */
- if (!wcsicmp(wszBuf, L"Command"))
- Type = SHELLNEW_TYPE_COMMAND;
- else if (!wcsicmp(wszBuf, L"Data"))
- Type = SHELLNEW_TYPE_DATA;
- else if (!wcsicmp(wszBuf, L"FileName"))
- Type = SHELLNEW_TYPE_FILENAME;
- else if (!wcsicmp(wszBuf, L"NullFile"))
+ struct
+ {
+ LPCSTR pszName;
+ SHELLNEW_TYPE Type;
+ BOOL bNeedData;
+ BOOL bStr;
+ } Types[] = {
+ {"FileName", SHELLNEW_TYPE_FILENAME, TRUE, TRUE},
+ {"Command", SHELLNEW_TYPE_COMMAND, TRUE, TRUE},
+ {"Data", SHELLNEW_TYPE_DATA, TRUE, FALSE},
+ {"NullFile", SHELLNEW_TYPE_NULLFILE, FALSE},
+ {NULL}
+ };
+ UINT i;
+
+ for (i = 0; Types[i].pszName; ++i)
+ {
+ /* Note: We are using ANSI function because strings can be treated as data */
+ cbData = 0;
+ DWORD dwFlags = Types[i].bStr ? RRF_RT_REG_SZ|RRF_RT_REG_EXPAND_SZ : RRF_RT_ANY;
+ if (RegGetValueA(hKey, NULL, Types[i].pszName, dwFlags, NULL, NULL, &cbData)
== ERROR_SUCCESS)
{
- Type = SHELLNEW_TYPE_NULLFILE;
- pwszTarget = NULL;
- }
-
- /* Create new item */
- if (Type != SHELLNEW_TYPE_INVALID)
- {
- pNewItem = (SHELLNEW_ITEM *)HeapAlloc(GetProcessHeap(), 0,
sizeof(SHELLNEW_ITEM));
- if (!pNewItem)
- break;
-
- pNewItem->Type = Type;
- if (pwszTarget)
- pNewItem->pwszTarget = _wcsdup(pwszTarget);
- else
- pNewItem->pwszTarget = NULL;
-
- GetKeyDescription(pwszExt, wszDesc);
- pNewItem->pwszDesc = _wcsdup(wszDesc);
- pNewItem->pwszIcon = _wcsdup(wszIcon);
- pNewItem->pwszExt = _wcsdup(pwszExt);
- pNewItem->pNext = NULL;
+ if (Types[i].bNeedData && cbData > 0)
+ {
+ pData = (BYTE*)malloc(cbData);
+ RegGetValueA(hKey, NULL, Types[i].pszName, dwFlags, NULL, pData,
&cbData);
+ }
break;
}
}
-
RegCloseKey(hKey);
+
+ /* Was any key found? */
+ if (!Types[i].pszName)
+ return NULL;
+
+ SHFILEINFO fi;
+ if (!SHGetFileInfoW(pwszExt, FILE_ATTRIBUTE_NORMAL, &fi, sizeof(fi),
SHGFI_USEFILEATTRIBUTES|SHGFI_TYPENAME|SHGFI_ICON|SHGFI_SMALLICON))
+ return NULL;
+
+ /* Create new item */
+ SHELLNEW_ITEM *pNewItem = (SHELLNEW_ITEM *)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, sizeof(SHELLNEW_ITEM));
+ if (!pNewItem)
+ {
+ free(pData);
+ return NULL;
+ }
+
+ TRACE("new item %ls\n", fi.szTypeName);
+ pNewItem->Type = Types[i].Type;
+ pNewItem->pData = pData;
+ pNewItem->cbData = pData ? cbData : 0;
+ pNewItem->pwszExt = _wcsdup(pwszExt);
+ pNewItem->pwszDesc = _wcsdup(fi.szTypeName);
+ if (fi.hIcon)
+ pNewItem->hBitmap = IconToBitmap(fi.hIcon);
+
return pNewItem;
}
BOOL
-CNewMenu::LoadShellNewItems()
+CNewMenu::LoadAllItems()
{
DWORD dwIndex = 0;
WCHAR wszName[MAX_PATH];
@@ -224,28 +185,21 @@
SHELLNEW_ITEM *pCurItem = NULL;
/* If there are any unload them */
- UnloadShellItems();
+ UnloadAllItems();
/* Enumerate all extesions */
while (RegEnumKeyW(HKEY_CLASSES_ROOT, dwIndex++, wszName, _countof(wszName)) ==
ERROR_SUCCESS)
{
- if (wszName[0] != '.' || wcsicmp(wszName, L".lnk") == 0)
+ if (wszName[0] != L'.')
continue;
pNewItem = LoadItem(wszName);
if (pNewItem)
{
- if (!wcsicmp(pNewItem->pwszExt, L".lnk"))
- {
- /* FIXME: Should we load them?
- Add lnk handlers to begin of the list */
- if (m_pShellItems)
- {
- pNewItem->pNext = m_pShellItems;
- m_pShellItems = pNewItem;
- }
- else
- m_pShellItems = pCurItem = pNewItem;
+ if (wcsicmp(pNewItem->pwszExt, L".lnk") == 0)
+ {
+ /* Link handler */
+ m_pLinkItem = pNewItem;
}
else
{
@@ -256,51 +210,38 @@
pCurItem = pNewItem;
}
else
- pCurItem = m_pShellItems = pNewItem;
+ pCurItem = m_pItems = pNewItem;
}
}
}
- if (m_pShellItems == NULL)
+ if (!m_pLinkItem)
+ {
+ m_pLinkItem = (SHELLNEW_ITEM *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(SHELLNEW_ITEM));
+ if (m_pLinkItem)
+ {
+ m_pLinkItem->Type = SHELLNEW_TYPE_NULLFILE;
+ m_pLinkItem->pwszDesc = _wcsdup(L"Link");
+ m_pLinkItem->pwszExt = _wcsdup(L".lnk");
+ }
+ }
+
+ if (m_pItems == NULL)
return FALSE;
else
return TRUE;
}
-static HBITMAP IconToBitmap(HICON hIcon)
-{
- HDC hdc, hdcScr;
- HBITMAP hbm, hbmOld;
- RECT rc;
-
- hdcScr = GetDC(NULL);
- hdc = CreateCompatibleDC(hdcScr);
- SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXMENUCHECK),
GetSystemMetrics(SM_CYMENUCHECK));
- hbm = CreateCompatibleBitmap(hdcScr, rc.right, rc.bottom);
- ReleaseDC(NULL, hdcScr);
-
- hbmOld = (HBITMAP)SelectObject(hdc, hbm);
- FillRect(hdc, &rc, (HBRUSH)(COLOR_MENU + 1));
- if (!DrawIconEx(hdc, 0, 0, hIcon, rc.right, rc.bottom, 0, NULL, DI_NORMAL))
- ERR("DrawIcon failed: %x\n", GetLastError());
- SelectObject(hdc, hbmOld);
-
- DeleteDC(hdc);
-
- return hbm;
-}
-
UINT
CNewMenu::InsertShellNewItems(HMENU hMenu, UINT idCmdFirst, UINT Pos)
{
MENUITEMINFOW mii;
WCHAR wszBuf[256];
- HICON hIcon;
UINT idCmd = idCmdFirst;
- if (m_pShellItems == NULL)
- {
- if (!LoadShellNewItems())
+ if (m_pItems == NULL)
+ {
+ if (!LoadAllItems())
return 0;
}
@@ -315,11 +256,10 @@
mii.dwTypeData = wszBuf;
mii.cch = wcslen(mii.dwTypeData);
mii.wID = idCmd;
- hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_FOLDER),
IMAGE_ICON, 0, 0, 0);
- if (hIcon)
+ if (m_hbmFolder)
{
mii.fMask |= MIIM_CHECKMARKS;
- mii.hbmpChecked = mii.hbmpUnchecked = IconToBitmap(hIcon);
+ mii.hbmpChecked = mii.hbmpUnchecked = m_hbmFolder;
}
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
++idCmd;
@@ -329,12 +269,11 @@
wszBuf[0] = 0;
mii.dwTypeData = wszBuf;
mii.cch = wcslen(mii.dwTypeData);
- mii.wID = idCmdFirst++;
- hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_SHORTCUT),
IMAGE_ICON, 0, 0, 0);
- if (hIcon)
+ mii.wID = idCmd;
+ if (m_hbmLink)
{
mii.fMask |= MIIM_CHECKMARKS;
- mii.hbmpChecked = mii.hbmpUnchecked = IconToBitmap(hIcon);
+ mii.hbmpChecked = mii.hbmpUnchecked = m_hbmLink;
}
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
++idCmd;
@@ -346,22 +285,22 @@
InsertMenuItemW(hMenu, Pos++, TRUE, &mii);
/* Insert rest of items */
- mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
- /*
- * FIXME:
- * implement loading of icons
- * and using MFT_OWNERDRAWN
- */
mii.fType = MFT_STRING;
mii.fState = MFS_ENABLED;
- SHELLNEW_ITEM *pCurItem = m_pShellItems;
+ SHELLNEW_ITEM *pCurItem = m_pItems;
while (pCurItem)
{
TRACE("szDesc %s\n", debugstr_w(pCurItem->pwszDesc));
+ mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_DATA;
mii.dwTypeData = pCurItem->pwszDesc;
mii.cch = wcslen(mii.dwTypeData);
mii.wID = idCmd;
+ if (pCurItem->hBitmap)
+ {
+ mii.fMask |= MIIM_CHECKMARKS;
+ mii.hbmpChecked = mii.hbmpUnchecked = pCurItem->hBitmap;
+ }
if (InsertMenuItemW(hMenu, Pos++, TRUE, &mii))
++idCmd;
pCurItem = pCurItem->pNext;
@@ -370,34 +309,86 @@
return idCmd - idCmdFirst;
}
-HRESULT
-CNewMenu::DoShellNewCmd(LPCMINVOKECOMMANDINFO lpcmi, IShellView *psv)
-{
- SHELLNEW_ITEM *pCurItem = m_pShellItems;
+CNewMenu::SHELLNEW_ITEM *CNewMenu::FindItemFromIdOffset(UINT IdOffset)
+{
+ if (IdOffset == 0)
+ return NULL; /* Folder */
+
+ if (IdOffset == 1)
+ return m_pLinkItem; /* shortcut */
+
+ /* Find shell new item */
+ SHELLNEW_ITEM *pItem = m_pItems;
+ for (UINT i = 2; pItem; ++i)
+ {
+ if (i == IdOffset)
+ break;
+
+ pItem = pItem->pNext;
+ }
+
+ return pItem;
+}
+
+HRESULT CNewMenu::CreateNewFolder(IShellView *psv)
+{
+ WCHAR wszName[MAX_PATH];
+ CComPtr<ISFHelper> psfhlp;
+ CComPtr<IFolderView> pFolderView;
+ CComPtr<IShellFolder> pParentFolder;
+ HRESULT hr;
+
+ //if (m_pSite == NULL)
+ // return E_FAIL;
+
+ /* Get current folder */
+ hr = IUnknown_QueryService(psv, SID_IFolderView, IID_IFolderView, (void
**)&pFolderView);
+ if (FAILED(hr))
+ return hr;
+
+ hr = pFolderView->GetFolder(IID_IShellFolder, (void **)&pParentFolder);
+ if (FAILED(hr))
+ return hr;
+
+ hr = pParentFolder->QueryInterface(IID_ISFHelper, (LPVOID*)&psfhlp);
+ if (FAILED(hr))
+ return hr;
+
+ LPITEMIDLIST pidl;
+
+ /* Get unique name and create a folder */
+ hr = psfhlp->GetUniqueName(wszName, _countof(wszName));
+ if (hr != S_OK)
+ return hr;
+ hr = psfhlp->AddFolder(0, wszName, &pidl);
+ if (hr != S_OK)
+ {
+ WCHAR wszBuf[256];
+ StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Cannot create folder: %s",
wszName);
+ MessageBoxW(NULL, wszBuf, L"Cannot create folder",
MB_OK|MB_ICONERROR);
+ return hr;
+ }
+
+ /* Do a labeledit */
+ psv->Refresh();
+ psv->SelectItem(pidl, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
+ SVSI_FOCUSED | SVSI_SELECT);
+
+ SHFree(pidl);
+ return S_OK;
+}
+
+HRESULT CNewMenu::CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi,
IShellView *psv)
+{
LPITEMIDLIST pidl;
STRRET strTemp;
WCHAR wszBuf[MAX_PATH];
WCHAR wszPath[MAX_PATH];
- UINT i, idCmd = LOWORD(lpcmi->lpVerb);
CComPtr<IFolderView> pFolderView;
CComPtr<IShellFolder> pParentFolder;
CComPtr<IPersistFolder3> psf;
HRESULT hr;
- /* Find shell new item */
- for (i = 1; pCurItem; ++i)
- {
- if (i == idCmd)
- break;
-
- pCurItem = pCurItem->pNext;
- }
-
- if (!pCurItem)
- return E_UNEXPECTED;
- //if (m_pSite == NULL)
- // return E_FAIL;
-
/* Get current folder */
hr = IUnknown_QueryService(psv, SID_IFolderView, IID_IFolderView, (void
**)&pFolderView);
if (FAILED(hr))
@@ -427,7 +418,7 @@
}
StrRetToBufW(&strTemp, pidl, wszPath, _countof(wszPath));
- switch (pCurItem->Type)
+ switch (pItem->Type)
{
case SHELLNEW_TYPE_COMMAND:
{
@@ -436,7 +427,7 @@
STARTUPINFOW si;
PROCESS_INFORMATION pi;
- if (!ExpandEnvironmentStringsW(pCurItem->pwszTarget, wszBuf, MAX_PATH))
+ if (!ExpandEnvironmentStringsW((LPWSTR)pItem->pData, wszBuf, MAX_PATH))
{
TRACE("ExpandEnvironmentStrings failed\n");
break;
@@ -475,41 +466,35 @@
/* Build new file name */
LoadStringW(shell32_hInstance, FCIDM_SHVIEW_NEW, wszBuf, _countof(wszBuf));
StringCchCatExW(wszPath, _countof(wszPath), L"\\",
&pwszFilename, &cchFilenameMax, 0);
- StringCchPrintfW(pwszFilename, cchFilenameMax, L"%s %s%s", wszBuf,
pCurItem->pwszDesc, pCurItem->pwszExt);
+ StringCchPrintfW(pwszFilename, cchFilenameMax, L"%s %s%s", wszBuf,
pItem->pwszDesc, pItem->pwszExt);
/* Find unique name */
- for (i = 2; PathFileExistsW(wszPath); ++i)
- {
- StringCchPrintfW(pwszFilename, cchFilenameMax, L"%s %s (%u)%s",
wszBuf, pCurItem->pwszDesc, i, pCurItem->pwszExt);
+ for (UINT i = 2; PathFileExistsW(wszPath); ++i)
+ {
+ StringCchPrintfW(pwszFilename, cchFilenameMax, L"%s %s (%u)%s",
wszBuf, pItem->pwszDesc, i, pItem->pwszExt);
TRACE("New Filename %ls\n", pwszFilename);
}
- if (pCurItem->Type == SHELLNEW_TYPE_DATA || pCurItem->Type ==
SHELLNEW_TYPE_NULLFILE)
- {
- /* Create new file */
- HANDLE hFile = CreateFileW(wszPath, GENERIC_WRITE, 0, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
- if (hFile != INVALID_HANDLE_VALUE)
+ /* Create new file */
+ HANDLE hFile = CreateFileW(wszPath, GENERIC_WRITE, 0, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile != INVALID_HANDLE_VALUE)
+ {
+ if (pItem->Type == SHELLNEW_TYPE_DATA)
{
- if (pCurItem->Type == SHELLNEW_TYPE_DATA)
- {
- /* Write a content */
- CHAR szTemp[256];
- DWORD cbWritten, cbTemp = WideCharToMultiByte(CP_ACP, 0,
pCurItem->pwszTarget, -1, szTemp, _countof(szTemp), NULL, NULL);
- if (cbTemp)
- WriteFile(hFile, (LPCVOID)szTemp, cbTemp, &cbWritten,
NULL);
- else
- ERR("WideCharToMultiByte failed\n");
- }
-
- /* Close file now */
- CloseHandle(hFile);
+ /* Write a content */
+ DWORD cbWritten;
+ WriteFile(hFile, pItem->pData, pItem->cbData, &cbWritten,
NULL);
}
- else bSuccess = FALSE;
- }
- else if (pCurItem->Type == SHELLNEW_TYPE_FILENAME)
+
+ /* Close file now */
+ CloseHandle(hFile);
+ } else
+ bSuccess = FALSE;
+
+ if (pItem->Type == SHELLNEW_TYPE_FILENAME)
{
/* Copy file */
- bSuccess = CopyFileW(pCurItem->pwszTarget, wszPath, FALSE);
+ bSuccess = CopyFileW((LPWSTR)pItem->pData, wszPath, FALSE);
}
/* Show message if we failed */
@@ -517,6 +502,15 @@
{
TRACE("Notifying fs %s\n", debugstr_w(wszPath));
SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, (LPCVOID)wszPath, NULL);
+ psv->Refresh();
+
+ LPITEMIDLIST pidl;
+ hr = _ILCreateFromPathW(wszPath, &pidl);
+ if (SUCCEEDED(hr))
+ {
+ psv->SelectItem(pidl,
SVSI_DESELECTOTHERS|SVSI_EDIT|SVSI_ENSUREVISIBLE|SVSI_FOCUSED|SVSI_SELECT);
+ ILFree(pidl);
+ }
}
else
{
@@ -529,52 +523,8 @@
ERR("Invalid type\n");
break;
}
+
return S_OK;
-}
-
-void CNewMenu::CreateNewFolder(IShellView *psv)
-{
- WCHAR wszName[MAX_PATH];
- CComPtr<ISFHelper> psfhlp;
- CComPtr<IFolderView> pFolderView;
- CComPtr<IShellFolder> pParentFolder;
- HRESULT hr;
-
- //if (m_pSite == NULL)
- // return;
-
- /* Get current folder */
- hr = IUnknown_QueryService(psv, SID_IFolderView, IID_IFolderView, (void
**)&pFolderView);
- if (FAILED(hr))
- return;
-
- hr = pFolderView->GetFolder(IID_IShellFolder, (void **)&pParentFolder);
- if (FAILED(hr))
- return;
-
- hr = pParentFolder->QueryInterface(IID_ISFHelper, (LPVOID*)&psfhlp);
- if (SUCCEEDED(hr))
- {
- LPITEMIDLIST pidl;
-
- /* Get unique name and create a folder */
- if (psfhlp->GetUniqueName(wszName, _countof(wszName)) != S_OK)
- return;
- if (psfhlp->AddFolder(0, wszName, &pidl) != S_OK)
- {
- WCHAR wszBuf[256];
- StringCbPrintfW(wszBuf, sizeof(wszBuf), L"Cannot create folder:
%s", wszName);
- MessageBoxW(NULL, wszBuf, L"Cannot create folder",
MB_OK|MB_ICONERROR);
- return;
- }
-
- /* Do a labeledit */
- psv->Refresh();
- psv->SelectItem(pidl, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
- SVSI_FOCUSED | SVSI_SELECT);
-
- SHFree(pidl);
- }
}
HRESULT STDMETHODCALLTYPE CNewMenu::SetSite(IUnknown *pUnkSite)
@@ -612,21 +562,20 @@
return E_FAIL;
m_hSubMenu = CreateMenu();
+ if (!m_hSubMenu)
+ return E_FAIL;
+
+ cItems = InsertShellNewItems(m_hSubMenu, idCmdFirst, 0);
+
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
+ mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE | MIIM_SUBMENU;
mii.fType = MFT_STRING;
mii.wID = -1;
mii.dwTypeData = wszNew;
mii.cch = wcslen(mii.dwTypeData);
mii.fState = MFS_ENABLED;
-
- if (m_hSubMenu)
- {
- cItems = InsertShellNewItems(m_hSubMenu, idCmdFirst, 0);
- mii.fMask |= MIIM_SUBMENU;
- mii.hSubMenu = m_hSubMenu;
- }
+ mii.hSubMenu = m_hSubMenu;
if (!InsertMenuItemW(hMenu, indexMenu, TRUE, &mii))
return E_FAIL;
@@ -638,23 +587,23 @@
WINAPI
CNewMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
- LPSHELLBROWSER lpSB;
- LPSHELLVIEW lpSV = NULL;
- HRESULT hr;
-
+ IShellBrowser *lpSB = NULL;
+ CComPtr<IShellView> lpSV = NULL;
+ HRESULT hr = E_FAIL;
+
+ /* Note: CWM_GETISHELLBROWSER returns shell browser without adding reference */
lpSB = (LPSHELLBROWSER)SendMessageA(lpici->hwnd, CWM_GETISHELLBROWSER, 0, 0);
if (lpSB)
lpSB->QueryActiveShellView(&lpSV);
if (LOWORD(lpici->lpVerb) == 0)
- {
- CreateNewFolder(lpSV);
- return S_OK;
- }
-
- hr = DoShellNewCmd(lpici, lpSV);
- if (SUCCEEDED(hr) && lpSV)
- lpSV->Refresh();
+ hr = CreateNewFolder(lpSV);
+ else
+ {
+ SHELLNEW_ITEM *pItem = FindItemFromIdOffset(LOWORD(lpici->lpVerb));
+ if (pItem)
+ hr = CreateNewItem(pItem, lpici, lpSV);
+ }
TRACE("CNewMenu::InvokeCommand %x\n", hr);
return hr;
@@ -676,11 +625,8 @@
HRESULT
WINAPI
-CNewMenu::HandleMenuMsg(UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
-{
- UNIMPLEMENTED;
+CNewMenu::HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
return S_OK;
}
@@ -688,5 +634,10 @@
CNewMenu::Initialize(LPCITEMIDLIST pidlFolder,
IDataObject *pdtobj, HKEY hkeyProgID)
{
+ HICON hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_FOLDER),
IMAGE_ICON, 0, 0, LR_SHARED);
+ m_hbmFolder = hIcon ? IconToBitmap(hIcon) : NULL;
+ hIcon = (HICON)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDI_SHELL_SHORTCUT),
IMAGE_ICON, 0, 0, LR_SHARED);
+ m_hbmLink = hIcon ? IconToBitmap(hIcon) : NULL;
+
return S_OK;
}
Modified: trunk/reactos/dll/win32/shell32/newmenu.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/newmenu.…
==============================================================================
--- trunk/reactos/dll/win32/shell32/newmenu.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/newmenu.h [iso-8859-1] Mon Jan 9 23:01:01 2012
@@ -3,6 +3,7 @@
*
* 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
@@ -43,26 +44,28 @@
{
SHELLNEW_TYPE Type;
LPWSTR pwszExt;
- LPWSTR pwszTarget;
+ PBYTE pData;
+ ULONG cbData;
LPWSTR pwszDesc;
- LPWSTR pwszIcon;
+ HBITMAP hBitmap;
SHELLNEW_ITEM *pNext;
};
LPWSTR m_wszPath;
- SHELLNEW_ITEM *m_pShellItems;
+ SHELLNEW_ITEM *m_pItems;
+ SHELLNEW_ITEM *m_pLinkItem;
IUnknown *m_pSite;
HMENU m_hSubMenu;
+ HBITMAP m_hbmFolder, m_hbmLink;
- void CleanupMenu();
- static BOOL GetKeyDescription(LPCWSTR pwszExt, LPWSTR pwszResult);
SHELLNEW_ITEM *LoadItem(LPCWSTR pwszExt);
void UnloadItem(SHELLNEW_ITEM *pItem);
- void UnloadShellItems();
- BOOL LoadShellNewItems();
+ void UnloadAllItems();
+ BOOL LoadAllItems();
UINT InsertShellNewItems(HMENU hMenu, UINT idFirst, UINT idMenu);
- HRESULT DoShellNewCmd(LPCMINVOKECOMMANDINFO lpcmi, IShellView *psv);
- void CreateNewFolder(IShellView *psv);
+ SHELLNEW_ITEM *FindItemFromIdOffset(UINT IdOffset);
+ HRESULT CreateNewFolder(IShellView *psv);
+ HRESULT CreateNewItem(SHELLNEW_ITEM *pItem, LPCMINVOKECOMMANDINFO lpcmi, IShellView
*psv);
public:
CNewMenu();
Modified: trunk/reactos/dll/win32/shell32/openwithmenu.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/openwith…
==============================================================================
--- trunk/reactos/dll/win32/shell32/openwithmenu.cpp [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/openwithmenu.cpp [iso-8859-1] Mon Jan 9 23:01:01
2012
@@ -3,6 +3,7 @@
*
* 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
Modified: trunk/reactos/dll/win32/shell32/openwithmenu.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/openwith…
==============================================================================
--- trunk/reactos/dll/win32/shell32/openwithmenu.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/shell32/openwithmenu.h [iso-8859-1] Mon Jan 9 23:01:01 2012
@@ -3,6 +3,7 @@
*
* 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