[SHELL32]

* Implement support for file formats' drop target shell extensions.
* Implement a shell extension for executable files.
* Implement a shell extension for lnk files.
* Change the shell notifications for moving files and folders, as they were all conflated with renaming files.
* Fix up SHChangeNotification so the desktop receives notifications when files are added to common or user desktop directories.
* Fix up SHChangeNotification such that folder pidls are not incorrectly assumed to be file pidls and displayed incorrectly.
* Implement a drop target for My Documents.
* Fix up the desktop's drop target resolution so files can be dropped on the recycle bin and my documents etc properly.
* Stub IDragSourceHelper in CLSID_DragDropHelper.
* Add a few additional shell change notifications.
* Silence a few FIXMEs to TRACEs.
* Some code clean up.
* Brought to you by Huw Campbell.
CORE-3760

svn path=/trunk/; revision=62502
This commit is contained in:
Amine Khaldi 2014-03-15 13:59:22 +00:00
parent 3643e3e2b9
commit 4f523a3000
26 changed files with 783 additions and 165 deletions

View file

@ -100,6 +100,7 @@ HKCR,"exefile","FriendlyTypeName",0x00020000,"@%SystemRoot%\system32\shell32.dll
HKCR,"exefile\Defaulticon","",0x00000000,"%1"
HKCR,"exefile\shell\open\command","",0x00000000,"""%1"" %*"
HKCR,"exefile\shell\runas\command","",0x00020000,"""%1"" %*"
HKCR,"exefile\shellex\DropHandler","",0x00020000,"{86C86720-42A0-1069-A2E8-08002B30309D}"
; Fonts
HKCR,".fon","",0x00000000,"fonfile"
@ -191,6 +192,7 @@ HKCR,"lnkfile","NeverShowExt",0x00000000,""
HKCR,"lnkfile","IsShortcut",0x00000000,"yes"
HKCR,"lnkfile\CLSID","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
HKCR,"lnkfile\shellex\IconHandler","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
HKCR,"lnkfile\shellex\DropHandler","",0x00000000,"{00021401-0000-0000-C000-000000000046}"
HKCR,"lnkfile\shellex\ContextMenuHandlers\{00021401-0000-0000-C000-000000000046}","",0x00000000,""
HKCR,"lnkfile\shellex\PropertySheetHandlers\Shellink Property Page", "", 0x00000000, "{00021401-0000-0000-C000-000000000046}"

View file

@ -54,6 +54,7 @@ list(APPEND SOURCE
folders/fonts.cpp
folders/cpanel.cpp
folders/recyclebin.cpp
droptargets/CexeDropHandler.cpp
shlexec.cpp
shlfileop.cpp
shlfolder.cpp

View file

@ -264,6 +264,25 @@ static BOOL should_notify( LPCITEMIDLIST changed, LPCITEMIDLIST watched, BOOL su
return TRUE;
if( sub && ILIsParent( watched, changed, TRUE ) )
return TRUE;
if (sub && _ILIsDesktop(watched)) {
WCHAR wszPath[MAX_PATH];
SHGetSpecialFolderPathW(0, wszPath, CSIDL_DESKTOPDIRECTORY, FALSE);
LPITEMIDLIST deskpidl = SHSimpleIDListFromPathW(wszPath);
if (ILIsParent(deskpidl, changed, TRUE))
{
ILFree(deskpidl);
return TRUE;
}
ILFree(deskpidl);
SHGetSpecialFolderPathW(0, wszPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
deskpidl = SHSimpleIDListFromPathW(wszPath);
if (ILIsParent(deskpidl, changed, TRUE))
{
ILFree(deskpidl);
return TRUE;
}
ILFree(deskpidl);
}
return FALSE;
}
@ -272,7 +291,7 @@ static BOOL should_notify( LPCITEMIDLIST changed, LPCITEMIDLIST watched, BOOL su
*/
void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
{
LPCITEMIDLIST Pidls[2];
LPITEMIDLIST Pidls[2];
LPNOTIFICATIONLIST ptr;
UINT typeFlag = uFlags & SHCNF_TYPE;
@ -316,10 +335,43 @@ void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID
case SHCNF_PATHW:
if (dwItem1) Pidls[0] = SHSimpleIDListFromPathW((LPCWSTR)dwItem1);
if (dwItem2) Pidls[1] = SHSimpleIDListFromPathW((LPCWSTR)dwItem2);
if (wEventId & (SHCNE_MKDIR | SHCNE_RMDIR | SHCNE_UPDATEDIR | SHCNE_RENAMEFOLDER))
{
/*
* The last items in the ID are currently files. So we chop off the last
* entry, and create a new one using a find data struct.
*/
if (dwItem1 && Pidls[0]){
ILRemoveLastID(Pidls[0]);
WIN32_FIND_DATAW wfd;
LPWSTR p = PathFindFileNameW((LPCWSTR)dwItem1);
lstrcpynW(&wfd.cFileName[0], p, MAX_PATH);
wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
LPITEMIDLIST newpidl = _ILCreateFromFindDataW(&wfd);
LPITEMIDLIST oldpidl = ILClone(Pidls[0]);
ILFree(Pidls[0]);
Pidls[0] = ILCombine(oldpidl, newpidl);
ILFree(newpidl);
ILFree(oldpidl);
}
if (dwItem2 && Pidls[1]){
ILRemoveLastID(Pidls[1]);
WIN32_FIND_DATAW wfd;
LPWSTR p = PathFindFileNameW((LPCWSTR)dwItem2);
lstrcpynW(&wfd.cFileName[0], p, MAX_PATH);
wfd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
LPITEMIDLIST newpidl = _ILCreateFromFindDataW(&wfd);
LPITEMIDLIST oldpidl = ILClone(Pidls[0]);
ILFree(Pidls[1]);
Pidls[1] = ILCombine(oldpidl, newpidl);
ILFree(newpidl);
ILFree(oldpidl);
}
}
break;
case SHCNF_IDLIST:
Pidls[0] = (LPCITEMIDLIST)dwItem1;
Pidls[1] = (LPCITEMIDLIST)dwItem2;
Pidls[0] = (LPITEMIDLIST)dwItem1;
Pidls[1] = (LPITEMIDLIST)dwItem2;
break;
case SHCNF_PRINTERA:
case SHCNF_PRINTERW:

View file

@ -61,6 +61,7 @@ class CDefaultContextMenu :
HRESULT DoPaste(LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink);
HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoRefresh(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoDelete(LPCMINVOKECOMMANDINFO lpcmi);
HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFO lpcmi, BOOL bCopy);
HRESULT DoRename(LPCMINVOKECOMMANDINFO lpcmi);
@ -931,19 +932,34 @@ NotifyShellViewWindow(LPCMINVOKECOMMANDINFO lpcmi, BOOL bRefresh)
if (FAILED(lpSB->QueryActiveShellView(&lpSV)))
return E_FAIL;
if (LOWORD(lpcmi->lpVerb) == FCIDM_SHVIEW_REFRESH || bRefresh)
lpSV->Refresh();
else
{
HWND hwndSV = NULL;
if (SUCCEEDED(lpSV->GetWindow(&hwndSV)))
SendMessageW(hwndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0), 0);
}
HWND hwndSV = NULL;
if (SUCCEEDED(lpSV->GetWindow(&hwndSV)))
SendMessageW(hwndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0), 0);
lpSV->Release();
return S_OK;
}
HRESULT
CDefaultContextMenu::DoRefresh(
LPCMINVOKECOMMANDINFO lpcmi)
{
CComPtr<IPersistFolder2> ppf2 = NULL;
LPITEMIDLIST pidl;
HRESULT hr = m_Dcm.psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &ppf2));
if (SUCCEEDED(hr))
{
hr = ppf2->GetCurFolder(&pidl);
if (SUCCEEDED(hr))
{
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST, pidl, NULL);
ILFree(pidl);
}
ppf2->Release();
}
return hr;
}
HRESULT
CDefaultContextMenu::DoPaste(
LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink)
@ -1512,8 +1528,9 @@ CDefaultContextMenu::InvokeCommand(
case 0x33:
case FCIDM_SHVIEW_AUTOARRANGE:
case FCIDM_SHVIEW_SNAPTOGRID:
case FCIDM_SHVIEW_REFRESH:
return NotifyShellViewWindow(lpcmi, FALSE);
case FCIDM_SHVIEW_REFRESH:
return DoRefresh(lpcmi);
case FCIDM_SHVIEW_INSERT:
return DoPaste(lpcmi, FALSE);
case FCIDM_SHVIEW_INSERTLINK:

View file

@ -36,6 +36,18 @@ CDropTargetHelper::~CDropTargetHelper()
{
}
HRESULT WINAPI CDropTargetHelper::InitializeFromBitmap(LPSHDRAGIMAGE pshdi, IDataObject *pDataObject)
{
FIXME ("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CDropTargetHelper::InitializeFromWindow(HWND hwnd, POINT *ppt, IDataObject *pDataObject)
{
FIXME ("(%p)->()\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CDropTargetHelper::DragEnter (HWND hwndTarget, IDataObject* pDataObject, POINT* ppt, DWORD dwEffect)
{
FIXME ("(%p)->(%p %p %p 0x%08x)\n", this, hwndTarget, pDataObject, ppt, dwEffect);

View file

@ -26,6 +26,7 @@
class CDropTargetHelper :
public CComCoClass<CDropTargetHelper, &CLSID_DragDropHelper>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IDragSourceHelper,
public IDropTargetHelper
{
private:
@ -33,7 +34,9 @@ public:
CDropTargetHelper();
~CDropTargetHelper();
////////
virtual HRESULT WINAPI InitializeFromBitmap(LPSHDRAGIMAGE pshdi, IDataObject *pDataObject);
virtual HRESULT WINAPI InitializeFromWindow(HWND hwnd, POINT *ppt, IDataObject *pDataObject);
virtual HRESULT WINAPI DragEnter (HWND hwndTarget, IDataObject* pDataObject, POINT* ppt, DWORD dwEffect);
virtual HRESULT WINAPI DragLeave();
virtual HRESULT WINAPI DragOver(POINT *ppt, DWORD dwEffect);
@ -46,6 +49,7 @@ DECLARE_NOT_AGGREGATABLE(CDropTargetHelper)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CDropTargetHelper)
COM_INTERFACE_ENTRY_IID(IID_IDragSourceHelper, IDragSourceHelper)
COM_INTERFACE_ENTRY_IID(IID_IDropTargetHelper, IDropTargetHelper)
END_COM_MAP()
};

View file

@ -0,0 +1,138 @@
/*
* executable drop target handler
*
* Copyright 2014 Huw Campbell
*
* 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);
CExeDropHandler::CExeDropHandler()
{
pclsid = (CLSID *)&CLSID_ExeDropHandler;
}
CExeDropHandler::~CExeDropHandler()
{
}
// IDropTarget
HRESULT WINAPI CExeDropHandler::DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
TRACE ("(%p)\n", this);
*pdwEffect = DROPEFFECT_COPY;
return S_OK;
}
HRESULT WINAPI CExeDropHandler::DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
TRACE ("(%p)\n", this);
*pdwEffect = DROPEFFECT_COPY;
return S_OK;
}
HRESULT WINAPI CExeDropHandler::DragLeave()
{
TRACE ("(%p)\n", this);
return S_OK;
}
HRESULT WINAPI CExeDropHandler::Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
TRACE ("(%p)\n", this);
FORMATETC fmt;
STGMEDIUM medium;
LPWSTR pszSrcList;
InitFormatEtc (fmt, CF_HDROP, TYMED_HGLOBAL);
WCHAR wszBuf[MAX_PATH * 2 + 8], *pszEnd = wszBuf;
size_t cchRemaining = _countof(wszBuf);
if (SUCCEEDED(pDataObject->GetData(&fmt, &medium)) /* && SUCCEEDED(pDataObject->GetData(&fmt2, &medium))*/)
{
LPDROPFILES lpdf = (LPDROPFILES) GlobalLock(medium.hGlobal);
if (!lpdf)
{
ERR("Error locking global\n");
return E_FAIL;
}
pszSrcList = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);
while (*pszSrcList)
{
if (StrChrW(pszSrcList, L' ') && cchRemaining > 3)
StringCchPrintfExW(pszEnd, cchRemaining, &pszEnd, &cchRemaining, 0, L"\"%ls\" ", pszSrcList);
else
StringCchPrintfExW(pszEnd, cchRemaining, &pszEnd, &cchRemaining, 0, L"%ls ", pszSrcList);
pszSrcList += wcslen(pszSrcList) + 1;
}
}
ShellExecute(NULL, L"open", sPathTarget, wszBuf, NULL,SW_SHOWNORMAL);
return S_OK;
}
// IPersistFile
HRESULT WINAPI CExeDropHandler::GetCurFile(LPOLESTR *ppszFileName)
{
FIXME ("(%p)\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CExeDropHandler::IsDirty()
{
FIXME ("(%p)\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CExeDropHandler::Load(LPCOLESTR pszFileName, DWORD dwMode)
{
UINT len = strlenW(pszFileName);
sPathTarget = (WCHAR *)SHAlloc((len + 1) * sizeof(WCHAR));
memcpy(sPathTarget, pszFileName, (len + 1) * sizeof(WCHAR));
return S_OK;
}
HRESULT WINAPI CExeDropHandler::Save(LPCOLESTR pszFileName, BOOL fRemember)
{
FIXME ("(%p)\n", this);
return E_NOTIMPL;
}
HRESULT WINAPI CExeDropHandler::SaveCompleted(LPCOLESTR pszFileName)
{
FIXME ("(%p)\n", this);
return E_NOTIMPL;
}
/************************************************************************
* CFSFolder::GetClassID
*/
HRESULT WINAPI CExeDropHandler::GetClassID(CLSID * lpClassId)
{
TRACE ("(%p)\n", this);
if (!lpClassId)
return E_POINTER;
*lpClassId = *pclsid;
return S_OK;
}

View file

@ -0,0 +1,66 @@
/*
* executable drop target handler
*
* Copyright 2014 Huw Campbell
*
* 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 _CEXEDROPHANDLER_H_
#define _CEXEDROPHANDLER_H_
class CExeDropHandler :
public CComCoClass<CExeDropHandler, &CLSID_ExeDropHandler>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IDropTarget,
public IPersistFile
{
private:
CLSID *pclsid;
LPWSTR sPathTarget;
public:
CExeDropHandler();
~CExeDropHandler();
// IDropTarget
virtual HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI DragLeave();
virtual HRESULT WINAPI Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
// IPersist
virtual HRESULT WINAPI GetClassID(CLSID *lpClassId);
//////// IPersistFile
virtual HRESULT WINAPI GetCurFile(LPOLESTR *ppszFileName);
virtual HRESULT WINAPI IsDirty();
virtual HRESULT WINAPI Load(LPCOLESTR pszFileName, DWORD dwMode);
virtual HRESULT WINAPI Save(LPCOLESTR pszFileName, BOOL fRemember);
virtual HRESULT WINAPI SaveCompleted(LPCOLESTR pszFileName);
DECLARE_REGISTRY_RESOURCEID(IDR_EXEDROPHANDLER)
DECLARE_NOT_AGGREGATABLE(CExeDropHandler)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CExeDropHandler)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
END_COM_MAP()
};
#endif /* _CEXEDROPHANDLER_H_ */

View file

@ -651,7 +651,7 @@ HRESULT WINAPI CDesktopFolder::GetUIObjectOf(
else if (IsEqualIID (riid, IID_IDropTarget))
{
/* only interested in attempting to bind to shell folders, not files, semicolon intentionate */
if (cidl == 1 && SUCCEEDED(this->BindToObject(apidl[0], NULL, IID_IDropTarget, (LPVOID*)&pObj)));
if (cidl == 1 && SUCCEEDED(hr = this->_GetDropTarget(apidl[0], (LPVOID*)&pObj)));
else
hr = this->QueryInterface(IID_IDropTarget, (LPVOID*)&pObj);
}
@ -1451,7 +1451,7 @@ HRESULT WINAPI CDesktopFolder::Drop(IDataObject *pDataObject,
else
{
InitFormatEtc (formatetc, CF_HDROP, TYMED_HGLOBAL);
if SUCCEEDED(pDataObject->QueryGetData(&formatetc));
if (SUCCEEDED(pDataObject->QueryGetData(&formatetc)))
{
passthroughtofs = TRUE;
}
@ -1488,4 +1488,53 @@ HRESULT WINAPI CDesktopFolder::Drop(IDataObject *pDataObject,
/* Todo, rewrite the registry such that the icons are well placed.
Blocked by no bags implementation. */
return hr;
}
HRESULT WINAPI CDesktopFolder::_GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut) {
HRESULT hr;
TRACE("CFSFolder::_GetDropTarget entered\n");
if (_ILGetGUIDPointer (pidl) || _ILIsFolder (pidl))
return this->BindToObject(pidl, NULL, IID_IDropTarget, ppvOut);
LPITEMIDLIST pidlNext = NULL;
STRRET strFile;
hr = this->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strFile);
if (SUCCEEDED(hr))
{
WCHAR wszPath[MAX_PATH];
hr = StrRetToBufW(&strFile, pidl, wszPath, _countof(wszPath));
if (SUCCEEDED(hr))
{
PathRemoveFileSpecW (wszPath);
hr = this->ParseDisplayName(NULL, NULL, wszPath, NULL, &pidlNext, NULL);
if (SUCCEEDED(hr))
{
IShellFolder *psf;
hr = this->BindToObject(pidlNext, NULL, IID_IShellFolder, (LPVOID*)&psf);
CoTaskMemFree(pidlNext);
if (SUCCEEDED(hr))
{
hr = psf->GetUIObjectOf(NULL, 1, &pidl, IID_IDropTarget, NULL, ppvOut);
psf->Release();
if (FAILED(hr))
ERR("FS GetUIObjectOf failed: %x\n", hr);
}
else
ERR("BindToObject failed: %x\n", hr);
}
else
ERR("ParseDisplayName failed: %x\n", hr);
}
else
ERR("StrRetToBufW failed: %x\n", hr);
}
else
ERR("GetDisplayNameOf failed: %x\n", hr);
return hr;
}

View file

@ -40,6 +40,7 @@ class CDesktopFolder :
BOOL fAcceptFmt; /* flag for pending Drop */
BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect);
void SF_RegisterClipFmt();
virtual HRESULT WINAPI _GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut);
public:
CDesktopFolder();

View file

@ -81,6 +81,7 @@ CFSFolder::CFSFolder()
cfShellIDList = 0;
SF_RegisterClipFmt();
fAcceptFmt = FALSE;
m_bGroupPolicyActive = 0;
}
CFSFolder::~CFSFolder()
@ -502,7 +503,7 @@ HRESULT WINAPI CFSFolder::GetUIObjectOf(HWND hwndOwner,
else if (IsEqualIID (riid, IID_IDropTarget))
{
/* only interested in attempting to bind to shell folders, not files (except exe), so if we fail, rebind to root */
if (cidl == 1 && SUCCEEDED(hr = this->BindToObject(apidl[0], NULL, IID_IDropTarget, (LPVOID*)&pObj)));
if (cidl == 1 && SUCCEEDED(hr = this->_GetDropTarget(apidl[0], (LPVOID*)&pObj)));
else
hr = this->QueryInterface(IID_IDropTarget, (LPVOID*)&pObj);
}
@ -1617,6 +1618,9 @@ HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
}
hr = ppf->Save(wszTarget, FALSE);
if (FAILED(hr))
break;
SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, wszTarget, NULL);
}
else
{
@ -1653,6 +1657,9 @@ HRESULT WINAPI CFSFolder::_DoDrop(IDataObject *pDataObject,
break;
hr = ppf->Save(wszTarget, TRUE);
if (FAILED(hr))
break;
SHChangeNotify(SHCNE_CREATE, SHCNF_PATHW, wszTarget, NULL);
}
}
}
@ -1748,4 +1755,114 @@ DWORD WINAPI CFSFolder::_DoDropThreadProc(LPVOID lpParameter) {
//Release the parameter from the heap.
HeapFree(GetProcessHeap(), 0, data);
return 0;
}
HRESULT WINAPI CFSFolder::_GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut) {
HKEY hKey;
HRESULT hr;
TRACE("CFSFolder::_GetDropTarget entered\n");
if (_ILGetGUIDPointer (pidl) || _ILIsFolder (pidl))
return this->BindToObject(pidl, NULL, IID_IDropTarget, ppvOut);
STRRET strFile;
hr = this->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strFile);
if (hr == S_OK)
{
WCHAR wszPath[MAX_PATH];
hr = StrRetToBufW(&strFile, pidl, wszPath, _countof(wszPath));
if (hr == S_OK)
{
LPCWSTR pwszExt = PathFindExtensionW(wszPath);
if (pwszExt[0])
{
/* enumerate dynamic/static for a given file class */
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, pwszExt, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
/* load dynamic extensions from file extension key, for example .jpg */
_LoadDynamicDropTargetHandlerForKey(hKey, wszPath, ppvOut);
RegCloseKey(hKey);
}
WCHAR wszTemp[40];
DWORD dwSize = sizeof(wszTemp);
if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, NULL, RRF_RT_REG_SZ, NULL, wszTemp, &dwSize) == ERROR_SUCCESS)
{
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszTemp, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
/* load dynamic extensions from progid key, for example jpegfile */
_LoadDynamicDropTargetHandlerForKey(hKey, wszPath, ppvOut);
RegCloseKey(hKey);
}
}
}
}
}
else
ERR("GetDisplayNameOf failed: %x\n", hr);
return hr;
}
HRESULT WINAPI CFSFolder::_LoadDynamicDropTargetHandlerForKey(HKEY hRootKey, LPCWSTR pwcsname, LPVOID *ppvOut)
{
TRACE("CFSFolder::_LoadDynamicDropTargetHandlerForKey entered\n");
WCHAR wszName[MAX_PATH], *pwszClsid;
DWORD dwSize = sizeof(wszName);
HRESULT hr;
if (RegGetValueW(hRootKey, L"shellex\\DropHandler", NULL, RRF_RT_REG_SZ, NULL, wszName, &dwSize) == ERROR_SUCCESS)
{
CLSID clsid;
hr = CLSIDFromString(wszName, &clsid);
if (hr == S_OK)
pwszClsid = wszName;
if (m_bGroupPolicyActive)
{
if (RegGetValueW(HKEY_LOCAL_MACHINE,
L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
pwszClsid,
RRF_RT_REG_SZ,
NULL,
NULL,
NULL) == ERROR_SUCCESS)
{
hr = _LoadDynamicDropTargetHandler(&clsid, pwcsname, ppvOut);
}
}
else
{
hr = _LoadDynamicDropTargetHandler(&clsid, pwcsname, ppvOut);
}
}
else
return E_FAIL;
return hr;
}
HRESULT WINAPI CFSFolder::_LoadDynamicDropTargetHandler(const CLSID *pclsid, LPCWSTR pwcsname, LPVOID *ppvOut)
{
TRACE("CFSFolder::_LoadDynamicDropTargetHandler entered\n");
HRESULT hr;
IPersistFile *pp;
hr = SHCoCreateInstance(NULL, pclsid, NULL, IID_PPV_ARG(IPersistFile, &pp));
if (hr != S_OK)
{
ERR("SHCoCreateInstance failed %x\n", GetLastError());
}
pp->Load(pwcsname, 0);
hr = pp->QueryInterface(IID_PPV_ARG(IDropTarget, (IDropTarget**) ppvOut));
if (hr != S_OK)
{
ERR("Failed to query for interface IID_IShellExtInit hr %x pclsid %s\n", hr, wine_dbgstr_guid(pclsid));
return hr;
}
pp->Release();
return hr;
}

View file

@ -44,10 +44,14 @@ class CFSFolder :
UINT cfShellIDList; /* clipboardformat for IDropTarget */
BOOL fAcceptFmt; /* flag for pending Drop */
BOOL QueryDrop (DWORD dwKeyState, LPDWORD pdwEffect);
DWORD m_bGroupPolicyActive;
void SF_RegisterClipFmt();
BOOL GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut);
static DWORD WINAPI _DoDropThreadProc(LPVOID lpParameter);
virtual HRESULT WINAPI _DoDrop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI _GetDropTarget(LPCITEMIDLIST pidl, LPVOID *ppvOut);
virtual HRESULT WINAPI _LoadDynamicDropTargetHandlerForKey(HKEY hRootKey, LPCWSTR pwcsname, LPVOID *ppvOut);
virtual HRESULT WINAPI _LoadDynamicDropTargetHandler(const CLSID *pclsid, LPCWSTR pwcsname, LPVOID *ppvOut);
public:
CFSFolder();

View file

@ -78,6 +78,7 @@ CMyDocsFolder::CMyDocsFolder()
{
pidlRoot = NULL;
sPathTarget = NULL;
mFSDropTarget = NULL;
}
CMyDocsFolder::~CMyDocsFolder()
@ -85,6 +86,7 @@ CMyDocsFolder::~CMyDocsFolder()
TRACE ("-- destroying IShellFolder(%p)\n", this);
SHFree(pidlRoot);
HeapFree(GetProcessHeap(), 0, sPathTarget);
mFSDropTarget->Release();
}
HRESULT WINAPI CMyDocsFolder::FinalConstruct()
@ -98,6 +100,29 @@ HRESULT WINAPI CMyDocsFolder::FinalConstruct()
sPathTarget = (LPWSTR)SHAlloc((wcslen(szMyPath) + 1) * sizeof(WCHAR));
wcscpy(sPathTarget, szMyPath);
LPITEMIDLIST pidl = NULL;
WCHAR szPath[MAX_PATH];
lstrcpynW(szPath, sPathTarget, MAX_PATH);
PathAddBackslashW(szPath);
CComPtr<IShellFolder> psfDesktop = NULL;
HRESULT hr = SHGetDesktopFolder(&psfDesktop);
if (SUCCEEDED(hr))
hr = psfDesktop->ParseDisplayName(NULL, NULL, szPath, NULL, &pidl, NULL);
else
ERR("Error getting desktop folder\n");
if (SUCCEEDED(hr))
{
hr = psfDesktop->BindToObject(pidl, NULL, IID_IDropTarget, (LPVOID*) &mFSDropTarget);
CoTaskMemFree(pidl);
if (FAILED(hr))
ERR("Error Binding");
}
else
ERR("Error creating from %s\n", debugstr_w(szPath));
return S_OK;
}
@ -271,8 +296,7 @@ HRESULT WINAPI CMyDocsFolder::CreateViewObject(HWND hwndOwner, REFIID riid, LPVO
if (IsEqualIID (riid, IID_IDropTarget))
{
WARN ("IDropTarget not implemented\n");
hr = E_NOTIMPL;
hr = this->QueryInterface (IID_IDropTarget, ppvOut);
}
else if (IsEqualIID (riid, IID_IContextMenu))
{
@ -679,3 +703,26 @@ HRESULT WINAPI CMyDocsFolder::GetCurFolder(LPITEMIDLIST *pidl)
*pidl = ILClone (pidlRoot);
return S_OK;
}
HRESULT WINAPI CMyDocsFolder::DragEnter(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
return mFSDropTarget->DragEnter(pDataObject, dwKeyState, pt, pdwEffect);
}
HRESULT WINAPI CMyDocsFolder::DragOver(DWORD dwKeyState, POINTL pt,
DWORD *pdwEffect)
{
return mFSDropTarget->DragOver(dwKeyState, pt, pdwEffect);
}
HRESULT WINAPI CMyDocsFolder::DragLeave()
{
return mFSDropTarget->DragLeave();
}
HRESULT WINAPI CMyDocsFolder::Drop(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
return mFSDropTarget->Drop(pDataObject, dwKeyState, pt, pdwEffect);
}

View file

@ -26,12 +26,14 @@ class CMyDocsFolder :
public CComCoClass<CMyDocsFolder, &CLSID_MyDocuments>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellFolder2,
public IPersistFolder2
public IPersistFolder2,
public IDropTarget
{
private:
/* both paths are parsible from the MyDocuments */
LPWSTR sPathTarget; /* complete path to target used for enumeration and ChangeNotify */
LPITEMIDLIST pidlRoot; /* absolute pidl */
IDropTarget *mFSDropTarget;
public:
CMyDocsFolder();
~CMyDocsFolder();
@ -67,6 +69,12 @@ class CMyDocsFolder :
// IPersistFolder2
virtual HRESULT WINAPI GetCurFolder(LPITEMIDLIST * pidl);
// IDropTarget
virtual HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI DragLeave();
virtual HRESULT WINAPI Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
DECLARE_REGISTRY_RESOURCEID(IDR_MYDOCUMENTS)
DECLARE_NOT_AGGREGATABLE(CMyDocsFolder)
@ -78,6 +86,7 @@ class CMyDocsFolder :
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder, IPersistFolder)
COM_INTERFACE_ENTRY_IID(IID_IPersistFolder2, IPersistFolder2)
COM_INTERFACE_ENTRY_IID(IID_IPersist, IPersist)
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
END_COM_MAP()
};

View file

@ -1416,7 +1416,7 @@ BOOL CRecycleBin::QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
HRESULT WINAPI CRecycleBin::DragEnter(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
FIXME("Recycle bin drag over (%p)\n", this);
TRACE("Recycle bin drag over (%p)\n", this);
/* The recycle bin accepts pretty much everything, and sets a CSIDL flag. */
fAcceptFmt = TRUE;
@ -1449,7 +1449,7 @@ HRESULT WINAPI CRecycleBin::DragLeave()
HRESULT WINAPI CRecycleBin::Drop(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
FIXME("(%p) object dropped on recycle bin, effect %u\n", this, *pdwEffect);
TRACE("(%p) object dropped on recycle bin, effect %u\n", this, *pdwEffect);
/* TODO: pdwEffect should be read and make the drop object be permanently deleted in the move case (shift held) */

View file

@ -55,6 +55,7 @@
#include "folders/printers.h"
#include "folders/admintools.h"
#include "folders/recyclebin.h"
#include "droptargets/CexeDropHandler.h"
#include "openwithmenu.h"
#include "newmenu.h"
#include "startmenu.h"

View file

@ -0,0 +1,13 @@
HKCR
{
NoRemove CLSID
{
ForceRemove {86C86720-42A0-1069-A2E8-08002B30309D} = s 'Executable Drag and Drop target'
{
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Apartment'
}
}
}
}

View file

@ -23,3 +23,4 @@ IDR_STARTMENU REGISTRY "res/rgs/startmenu.rgs"
IDR_OPENWITHMENU REGISTRY "res/rgs/openwithmenu.rgs"
IDR_FILEDEFEXT REGISTRY "res/rgs/shellfiledefext.rgs"
IDR_DRVDEFEXT REGISTRY "res/rgs/shelldrvdefext.rgs"
IDR_EXEDROPHANDLER REGISTRY "res/rgs/exedrophandler.rgs"

View file

@ -1371,6 +1371,7 @@ BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_MenuBandSite, CMenuBandSite)
OBJECT_ENTRY(CLSID_MenuBand, CMenuBand)
OBJECT_ENTRY(CLSID_MenuDeskBar, CMenuDeskBar)
OBJECT_ENTRY(CLSID_ExeDropHandler, CExeDropHandler)
END_OBJECT_MAP()
CShell32Module gModule;

View file

@ -2168,6 +2168,68 @@ HRESULT WINAPI CShellLink::GetSite(REFIID iid, void ** ppvSite)
return site->QueryInterface(iid, ppvSite);
}
HRESULT WINAPI CShellLink::DragEnter(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
LPCITEMIDLIST pidlLast;
IShellFolder *psf;
HRESULT hr = SHBindToParent(pPidl, IID_PPV_ARG(IShellFolder, &psf), &pidlLast);
if (SUCCEEDED(hr))
{
hr = psf->GetUIObjectOf(0, 1, &pidlLast, IID_IDropTarget, NULL, (LPVOID*)&mDropTarget);
if (SUCCEEDED(hr))
hr = mDropTarget->DragEnter(pDataObject, dwKeyState, pt, pdwEffect);
else
*pdwEffect = DROPEFFECT_NONE;
psf->Release();
}
else
*pdwEffect = DROPEFFECT_NONE;
return S_OK;
}
HRESULT WINAPI CShellLink::DragOver(DWORD dwKeyState, POINTL pt,
DWORD *pdwEffect)
{
TRACE("(%p)\n", this);
HRESULT hr = S_OK;
if (mDropTarget)
hr = mDropTarget->DragOver(dwKeyState, pt, pdwEffect);
return hr;
}
HRESULT WINAPI CShellLink::DragLeave()
{
TRACE("(%p)\n", this);
HRESULT hr = S_OK;
if (mDropTarget)
{
hr = mDropTarget->DragLeave();
mDropTarget->Release();
}
return hr;
}
HRESULT WINAPI CShellLink::Drop(IDataObject *pDataObject,
DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
{
TRACE("(%p)\n", this);
HRESULT hr = S_OK;
if (mDropTarget)
hr = mDropTarget->Drop(pDataObject, dwKeyState, pt, pdwEffect);
return hr;
}
/**************************************************************************
* IShellLink_ConstructFromFile
*/

View file

@ -25,140 +25,148 @@
#define _SHELLLINK_H_
class CShellLink :
public CComCoClass<CShellLink, &CLSID_ShellLink>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellLinkA,
public IShellLinkW,
public IPersistFile,
public IPersistStream,
public IShellLinkDataList,
public IShellExtInit,
public IContextMenu,
public IObjectWithSite,
public IShellPropSheetExt
public CComCoClass<CShellLink, &CLSID_ShellLink>,
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public IShellLinkA,
public IShellLinkW,
public IPersistFile,
public IPersistStream,
public IShellLinkDataList,
public IShellExtInit,
public IContextMenu,
public IDropTarget,
public IObjectWithSite,
public IShellPropSheetExt
{
public:
/* link file formats */
/* link file formats */
#include "pshpack1.h"
#include "pshpack1.h"
struct volume_info
{
DWORD type;
DWORD serial;
WCHAR label[12]; /* assume 8.3 */
};
struct volume_info
{
DWORD type;
DWORD serial;
WCHAR label[12]; /* assume 8.3 */
};
#include "poppack.h"
#include "poppack.h"
private:
/* data structures according to the information in the link */
LPITEMIDLIST pPidl;
WORD wHotKey;
SYSTEMTIME time1;
SYSTEMTIME time2;
SYSTEMTIME time3;
/* data structures according to the information in the link */
LPITEMIDLIST pPidl;
WORD wHotKey;
SYSTEMTIME time1;
SYSTEMTIME time2;
SYSTEMTIME time3;
DWORD iShowCmd;
LPWSTR sIcoPath;
INT iIcoNdx;
LPWSTR sPath;
LPWSTR sArgs;
LPWSTR sWorkDir;
LPWSTR sDescription;
LPWSTR sPathRel;
LPWSTR sProduct;
LPWSTR sComponent;
volume_info volume;
LPWSTR sLinkPath;
BOOL bRunAs;
BOOL bDirty;
INT iIdOpen; /* id of the "Open" entry in the context menu */
CComPtr<IUnknown> site;
DWORD iShowCmd;
LPWSTR sIcoPath;
INT iIcoNdx;
LPWSTR sPath;
LPWSTR sArgs;
LPWSTR sWorkDir;
LPWSTR sDescription;
LPWSTR sPathRel;
LPWSTR sProduct;
LPWSTR sComponent;
volume_info volume;
LPWSTR sLinkPath;
BOOL bRunAs;
BOOL bDirty;
INT iIdOpen; /* id of the "Open" entry in the context menu */
CComPtr<IUnknown> site;
IDropTarget *mDropTarget;
public:
CShellLink();
~CShellLink();
LPWSTR ShellLink_GetAdvertisedArg(LPCWSTR str);
HRESULT ShellLink_SetAdvertiseInfo(LPCWSTR str);
static INT_PTR CALLBACK SH_ShellLinkDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
CShellLink();
~CShellLink();
LPWSTR ShellLink_GetAdvertisedArg(LPCWSTR str);
HRESULT ShellLink_SetAdvertiseInfo(LPCWSTR str);
static INT_PTR CALLBACK SH_ShellLinkDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
// IPersistFile
virtual HRESULT WINAPI GetClassID(CLSID *pclsid);
virtual HRESULT WINAPI IsDirty();
virtual HRESULT WINAPI Load(LPCOLESTR pszFileName, DWORD dwMode);
virtual HRESULT WINAPI Save(LPCOLESTR pszFileName, BOOL fRemember);
virtual HRESULT WINAPI SaveCompleted(LPCOLESTR pszFileName);
virtual HRESULT WINAPI GetCurFile(LPOLESTR *ppszFileName);
// IPersistFile
virtual HRESULT WINAPI GetClassID(CLSID *pclsid);
virtual HRESULT WINAPI IsDirty();
virtual HRESULT WINAPI Load(LPCOLESTR pszFileName, DWORD dwMode);
virtual HRESULT WINAPI Save(LPCOLESTR pszFileName, BOOL fRemember);
virtual HRESULT WINAPI SaveCompleted(LPCOLESTR pszFileName);
virtual HRESULT WINAPI GetCurFile(LPOLESTR *ppszFileName);
// IPersistStream
// virtual WINAPI HRESULT GetClassID(CLSID *pclsid);
// virtual HRESULT WINAPI IsDirty();
virtual HRESULT WINAPI Load(IStream *stm);
virtual HRESULT WINAPI Save(IStream *stm, BOOL fClearDirty);
virtual HRESULT WINAPI GetSizeMax(ULARGE_INTEGER *pcbSize);
// IPersistStream
// virtual WINAPI HRESULT GetClassID(CLSID *pclsid);
// virtual HRESULT WINAPI IsDirty();
virtual HRESULT WINAPI Load(IStream *stm);
virtual HRESULT WINAPI Save(IStream *stm, BOOL fClearDirty);
virtual HRESULT WINAPI GetSizeMax(ULARGE_INTEGER *pcbSize);
// IShellLinkA
virtual HRESULT WINAPI GetPath(LPSTR pszFile, INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags);
virtual HRESULT WINAPI GetIDList(LPITEMIDLIST * ppidl);
virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl);
virtual HRESULT WINAPI GetDescription(LPSTR pszName,INT cchMaxName);
virtual HRESULT WINAPI SetDescription(LPCSTR pszName);
virtual HRESULT WINAPI GetWorkingDirectory(LPSTR pszDir,INT cchMaxPath);
virtual HRESULT WINAPI SetWorkingDirectory(LPCSTR pszDir);
virtual HRESULT WINAPI GetArguments(LPSTR pszArgs,INT cchMaxPath);
virtual HRESULT WINAPI SetArguments(LPCSTR pszArgs);
virtual HRESULT WINAPI GetHotkey(WORD *pwHotkey);
virtual HRESULT WINAPI SetHotkey(WORD wHotkey);
virtual HRESULT WINAPI GetShowCmd(INT *piShowCmd);
virtual HRESULT WINAPI SetShowCmd(INT iShowCmd);
virtual HRESULT WINAPI GetIconLocation(LPSTR pszIconPath,INT cchIconPath,INT *piIcon);
virtual HRESULT WINAPI SetIconLocation(LPCSTR pszIconPath,INT iIcon);
virtual HRESULT WINAPI SetRelativePath(LPCSTR pszPathRel, DWORD dwReserved);
virtual HRESULT WINAPI Resolve(HWND hwnd, DWORD fFlags);
virtual HRESULT WINAPI SetPath(LPCSTR pszFile);
// IShellLinkA
virtual HRESULT WINAPI GetPath(LPSTR pszFile, INT cchMaxPath, WIN32_FIND_DATAA *pfd, DWORD fFlags);
virtual HRESULT WINAPI GetIDList(LPITEMIDLIST * ppidl);
virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl);
virtual HRESULT WINAPI GetDescription(LPSTR pszName,INT cchMaxName);
virtual HRESULT WINAPI SetDescription(LPCSTR pszName);
virtual HRESULT WINAPI GetWorkingDirectory(LPSTR pszDir,INT cchMaxPath);
virtual HRESULT WINAPI SetWorkingDirectory(LPCSTR pszDir);
virtual HRESULT WINAPI GetArguments(LPSTR pszArgs,INT cchMaxPath);
virtual HRESULT WINAPI SetArguments(LPCSTR pszArgs);
virtual HRESULT WINAPI GetHotkey(WORD *pwHotkey);
virtual HRESULT WINAPI SetHotkey(WORD wHotkey);
virtual HRESULT WINAPI GetShowCmd(INT *piShowCmd);
virtual HRESULT WINAPI SetShowCmd(INT iShowCmd);
virtual HRESULT WINAPI GetIconLocation(LPSTR pszIconPath,INT cchIconPath,INT *piIcon);
virtual HRESULT WINAPI SetIconLocation(LPCSTR pszIconPath,INT iIcon);
virtual HRESULT WINAPI SetRelativePath(LPCSTR pszPathRel, DWORD dwReserved);
virtual HRESULT WINAPI Resolve(HWND hwnd, DWORD fFlags);
virtual HRESULT WINAPI SetPath(LPCSTR pszFile);
// IShellLinkW
virtual HRESULT WINAPI GetPath(LPWSTR pszFile, INT cchMaxPath, WIN32_FIND_DATAW *pfd, DWORD fFlags);
// virtual HRESULT WINAPI GetIDList(LPITEMIDLIST *ppidl);
// virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl);
virtual HRESULT WINAPI GetDescription(LPWSTR pszName, INT cchMaxName);
virtual HRESULT WINAPI SetDescription(LPCWSTR pszName);
virtual HRESULT WINAPI GetWorkingDirectory(LPWSTR pszDir, INT cchMaxPath);
virtual HRESULT WINAPI SetWorkingDirectory(LPCWSTR pszDir);
virtual HRESULT WINAPI GetArguments(LPWSTR pszArgs,INT cchMaxPath);
virtual HRESULT WINAPI SetArguments(LPCWSTR pszArgs);
// virtual HRESULT WINAPI GetHotkey(WORD *pwHotkey);
// virtual HRESULT WINAPI SetHotkey(WORD wHotkey);
// virtual HRESULT WINAPI GetShowCmd(INT *piShowCmd);
// virtual HRESULT WINAPI SetShowCmd(INT iShowCmd);
virtual HRESULT WINAPI GetIconLocation(LPWSTR pszIconPath,INT cchIconPath,INT *piIcon);
virtual HRESULT WINAPI SetIconLocation(LPCWSTR pszIconPath,INT iIcon);
virtual HRESULT WINAPI SetRelativePath(LPCWSTR pszPathRel, DWORD dwReserved);
// virtual HRESULT WINAPI Resolve(HWND hwnd, DWORD fFlags);
virtual HRESULT WINAPI SetPath(LPCWSTR pszFile);
// IShellLinkW
virtual HRESULT WINAPI GetPath(LPWSTR pszFile, INT cchMaxPath, WIN32_FIND_DATAW *pfd, DWORD fFlags);
// virtual HRESULT WINAPI GetIDList(LPITEMIDLIST *ppidl);
// virtual HRESULT WINAPI SetIDList(LPCITEMIDLIST pidl);
virtual HRESULT WINAPI GetDescription(LPWSTR pszName, INT cchMaxName);
virtual HRESULT WINAPI SetDescription(LPCWSTR pszName);
virtual HRESULT WINAPI GetWorkingDirectory(LPWSTR pszDir, INT cchMaxPath);
virtual HRESULT WINAPI SetWorkingDirectory(LPCWSTR pszDir);
virtual HRESULT WINAPI GetArguments(LPWSTR pszArgs,INT cchMaxPath);
virtual HRESULT WINAPI SetArguments(LPCWSTR pszArgs);
// virtual HRESULT WINAPI GetHotkey(WORD *pwHotkey);
// virtual HRESULT WINAPI SetHotkey(WORD wHotkey);
// virtual HRESULT WINAPI GetShowCmd(INT *piShowCmd);
// virtual HRESULT WINAPI SetShowCmd(INT iShowCmd);
virtual HRESULT WINAPI GetIconLocation(LPWSTR pszIconPath,INT cchIconPath,INT *piIcon);
virtual HRESULT WINAPI SetIconLocation(LPCWSTR pszIconPath,INT iIcon);
virtual HRESULT WINAPI SetRelativePath(LPCWSTR pszPathRel, DWORD dwReserved);
// virtual HRESULT WINAPI Resolve(HWND hwnd, DWORD fFlags);
virtual HRESULT WINAPI SetPath(LPCWSTR pszFile);
// IShellLinkDataList
virtual HRESULT WINAPI AddDataBlock(void *pDataBlock);
virtual HRESULT WINAPI CopyDataBlock(DWORD dwSig, void **ppDataBlock);
virtual HRESULT WINAPI RemoveDataBlock(DWORD dwSig);
virtual HRESULT WINAPI GetFlags(DWORD *pdwFlags);
virtual HRESULT WINAPI SetFlags(DWORD dwFlags);
// IShellLinkDataList
virtual HRESULT WINAPI AddDataBlock(void *pDataBlock);
virtual HRESULT WINAPI CopyDataBlock(DWORD dwSig, void **ppDataBlock);
virtual HRESULT WINAPI RemoveDataBlock(DWORD dwSig);
virtual HRESULT WINAPI GetFlags(DWORD *pdwFlags);
virtual HRESULT WINAPI SetFlags(DWORD dwFlags);
// IShellExtInit
virtual HRESULT WINAPI Initialize(LPCITEMIDLIST pidlFolder, IDataObject *pdtobj, HKEY hkeyProgID);
// IShellExtInit
virtual HRESULT WINAPI 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);
// 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);
// 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);
// IObjectWithSite
virtual HRESULT WINAPI SetSite(IUnknown *punk);
virtual HRESULT WINAPI GetSite(REFIID iid, void **ppvSite);
// IDropTarget
virtual HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
virtual HRESULT WINAPI DragLeave();
virtual HRESULT WINAPI Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect);
DECLARE_REGISTRY_RESOURCEID(IDR_SHELLLINK)
DECLARE_NOT_AGGREGATABLE(CShellLink)
@ -166,16 +174,17 @@ DECLARE_NOT_AGGREGATABLE(CShellLink)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CShellLink)
COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistFile)
COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
COM_INTERFACE_ENTRY_IID(IID_IShellLinkA, IShellLinkA)
COM_INTERFACE_ENTRY_IID(IID_IShellLinkW, IShellLinkW)
COM_INTERFACE_ENTRY_IID(IID_IShellLinkDataList, IShellLinkDataList)
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)
COM_INTERFACE_ENTRY2_IID(IID_IPersist, IPersist, IPersistFile)
COM_INTERFACE_ENTRY_IID(IID_IPersistFile, IPersistFile)
COM_INTERFACE_ENTRY_IID(IID_IPersistStream, IPersistStream)
COM_INTERFACE_ENTRY_IID(IID_IShellLinkA, IShellLinkA)
COM_INTERFACE_ENTRY_IID(IID_IShellLinkW, IShellLinkW)
COM_INTERFACE_ENTRY_IID(IID_IShellLinkDataList, IShellLinkDataList)
COM_INTERFACE_ENTRY_IID(IID_IShellExtInit, IShellExtInit)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
COM_INTERFACE_ENTRY_IID(IID_IDropTarget, IDropTarget)
COM_INTERFACE_ENTRY_IID(IID_IShellPropSheetExt, IShellPropSheetExt)
COM_INTERFACE_ENTRY_IID(IID_IObjectWithSite, IObjectWithSite)
END_COM_MAP()
};

View file

@ -1,10 +1,10 @@
/*
* Virtual Folder
* common definitions
* Virtual Folder
* common definitions
*
* Copyright 1997 Marcus Meissner
* Copyright 1998, 1999, 2002 Juergen Schmied
* Copyright 1997 Marcus Meissner
* Copyright 1998, 1999, 2002 Juergen Schmied
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -40,13 +40,13 @@ BOOL SHELL32_GetCustomFolderAttribute (LPCITEMIDLIST pidl, LPCWSTR pwszHeading,
LPCWSTR GetNextElementW (LPCWSTR pszNext, LPWSTR pszOut, DWORD dwOut);
HRESULT SHELL32_ParseNextElement (IShellFolder2 * psf, HWND hwndOwner, LPBC pbc, LPITEMIDLIST * pidlInOut,
LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes);
LPOLESTR szNext, DWORD * pEaten, DWORD * pdwAttributes);
HRESULT SHELL32_GetItemAttributes (IShellFolder * psf, LPCITEMIDLIST pidl, LPDWORD pdwAttributes);
HRESULT SHELL32_GetDisplayNameOfChild (IShellFolder2 * psf, LPCITEMIDLIST pidl, DWORD dwFlags, LPWSTR szOut,
DWORD dwOutLen);
DWORD dwOutLen);
HRESULT SHELL32_BindToChild (LPCITEMIDLIST pidlRoot,
LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
LPCWSTR pathRoot, LPCITEMIDLIST pidlComplete, REFIID riid, LPVOID * ppvOut);
HRESULT SHELL32_CompareIDs (IShellFolder * iface, LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
LPITEMIDLIST SHELL32_CreatePidlFromBindCtx(IBindCtx *pbc, LPCWSTR path);

View file

@ -42,7 +42,7 @@ static const WCHAR wWildcardChars[] = {'*','?',0};
static DWORD SHNotifyCreateDirectoryW(LPCWSTR path, LPSECURITY_ATTRIBUTES sec);
static DWORD SHNotifyRemoveDirectoryW(LPCWSTR path);
static DWORD SHNotifyDeleteFileW(LPCWSTR path);
static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest);
static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest, BOOL isdir);
static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bFailIfExists);
static DWORD SHFindAttrW(LPCWSTR pName, BOOL fileOnly);
@ -531,7 +531,7 @@ EXTERN_C DWORD WINAPI Win32DeleteFileW(LPCWSTR path)
* RETURNS
* ERORR_SUCCESS if successful
*/
static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest)
static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest, BOOL isdir)
{
BOOL ret;
@ -559,7 +559,8 @@ static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest)
}
if (ret)
{
SHChangeNotify(SHCNE_RENAMEITEM, SHCNF_PATHW, src, dest);
SHChangeNotify(isdir ? SHCNE_MKDIR : SHCNE_CREATE, SHCNF_PATHW, dest, NULL);
SHChangeNotify(isdir ? SHCNE_RMDIR : SHCNE_DELETE, SHCNF_PATHW, src, NULL);
return ERROR_SUCCESS;
}
return GetLastError();
@ -1474,7 +1475,10 @@ static HRESULT delete_files(LPSHFILEOPSTRUCTW lpFileOp, const FILE_LIST *flFrom)
{
BOOL bDelete;
if (TRASH_TrashFile(fileEntry->szFullPath))
{
SHChangeNotify(SHCNE_DELETE, SHCNF_PATHW, fileEntry->szFullPath, NULL);
continue;
}
/* Note: Windows silently deletes the file in such a situation, we show a dialog */
if (!(lpFileOp->fFlags & FOF_NOCONFIRMATION) || (lpFileOp->fFlags & FOF_WANTNUKEWARNING))
@ -1491,7 +1495,10 @@ static HRESULT delete_files(LPSHFILEOPSTRUCTW lpFileOp, const FILE_LIST *flFrom)
/* delete the file or directory */
if (IsAttribFile(fileEntry->attributes))
{
bPathExists = DeleteFileW(fileEntry->szFullPath);
SHChangeNotify(SHCNE_DELETE, SHCNF_PATHW, fileEntry->szFullPath, NULL);
}
else
bPathExists = SHELL_DeleteDirectoryW(lpFileOp->hwnd, fileEntry->szFullPath, FALSE);
@ -1548,7 +1555,7 @@ static void move_to_dir(LPSHFILEOPSTRUCTW lpFileOp, const FILE_ENTRY *feFrom, co
PathCombineW(szDestPath, feTo->szFullPath, feFrom->szFilename);
if (IsAttribFile(feFrom->attributes))
SHNotifyMoveFileW(feFrom->szFullPath, szDestPath);
SHNotifyMoveFileW(feFrom->szFullPath, szDestPath, FALSE);
else if (!(lpFileOp->fFlags & FOF_FILESONLY && feFrom->bFromWildcard))
move_dir_to_dir(lpFileOp, feFrom, szDestPath);
}
@ -1599,7 +1606,7 @@ static HRESULT move_files(LPSHFILEOPSTRUCTW lpFileOp, const FILE_LIST *flFrom, c
if (fileDest->bExists && IsAttribDir(fileDest->attributes))
move_to_dir(lpFileOp, entryToMove, fileDest);
else
SHNotifyMoveFileW(entryToMove->szFullPath, fileDest->szFullPath);
SHNotifyMoveFileW(entryToMove->szFullPath, fileDest->szFullPath, IsAttribDir(entryToMove->attributes));
}
return ERROR_SUCCESS;
@ -1628,7 +1635,7 @@ static HRESULT rename_files(LPSHFILEOPSTRUCTW lpFileOp, const FILE_LIST *flFrom,
if (feTo->bExists)
return ERROR_ALREADY_EXISTS;
return SHNotifyMoveFileW(feFrom->szFullPath, feTo->szFullPath);
return SHNotifyMoveFileW(feFrom->szFullPath, feTo->szFullPath, IsAttribDir(feFrom->attributes));
}
/* alert the user if an unsupported flag is used */

View file

@ -1807,9 +1807,13 @@ LRESULT CDefView::OnChangeNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &
break;
case SHCNE_UPDATEITEM:
LV_RenameItem(Pidls[0], Pidls[0]);
break;
case SHCNE_UPDATEDIR:
Refresh();
break;
}
return TRUE;
}
@ -2493,12 +2497,10 @@ HRESULT WINAPI CDefView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINT
{
m_pCurDropTarget->Drop(pDataObject, grfKeyState, pt, pdwEffect);
m_pCurDropTarget.Release();
this->Refresh();
}
m_pCurDataObject.Release(); m_iDragOverItem = 0;
m_pCurDataObject.Release();
m_iDragOverItem = 0;
return S_OK;
}

View file

@ -523,3 +523,4 @@
#define IDR_DRVDEFEXT 148
#define IDR_MENUBAND 149
#define IDR_MENUDESKBAR 150
#define IDR_EXEDROPHANDLER 151

View file

@ -105,6 +105,8 @@ DEFINE_GUID(CLSID_ShellFileDefExt, 0x21B22460, 0x3AEA, 0x1069, 0xA2, 0xD
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);
DEFINE_GUID(CLSID_ExeDropHandler, 0x86C86720, 0x42A0, 0x1069, 0xA2, 0xE8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
#define CGID_IExplorerToolbar IID_IExplorerToolbar
#define SID_IExplorerToolbar IID_IExplorerToolbar
#define SID_ITargetFrame2 IID_ITargetFrame2