mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-01 12:23:29 +00:00
Sync to Wine-0_9_3:
Michael Jung <[email protected]> - Use the ANSI codepage in IShellFolder::GetDisplayNameOf. - Implemented scrolling during drag&drop for the shellview class. - Use GetUIObjectOf instead of BindToObject to get a IDropTarget object. - Register the shell view itself as the drop target, not it's parent folder. Forward drag&drop method calls to the folder currently under the cursor. - Initialize OLE instead of just COM, in order to enable Drag & Drop. - Modified KeyStateToDropEffect macro to match native shellview's behaviour. - Also scan HKEY_CURRENT_USER for shell namespace extensions in Desktop folder. Fixed a handle leak in case of failing AddToEnumList call. - Also scan HKEY_CURRENT_USER for shell namespace extensions in MyComputer. - Enhanced UnixFolder's IDropTarget implementation. Use STATIC_CAST macro more consistently. - Initial stubbed implementation of UnixFolder's IDropTarget interface. Francois Gouget <[email protected]> - Assorted spelling fixes. Ge van Geldorp <[email protected]> - Load shortcut icon by resource id instead of by icon index. - Other code in shlexec.c (e.g. the extension handling code in ShellExecute_GetClassKey) expects sei->lpFile to not be enclosed in quotes. Martin Fuchs <[email protected]> - Correctly call HCR_GetFolderAttributes() in SHELL32_GetItemAttributes(). Directly return the correct "My Computer" attributes in ISF_Desktop_fnGetAttributesOf(). Remove "todo_wine" from the "My Computer" attributes test case. Add test case for retrieving the file system path from the CSIDL_PROGRAM_FILES PIDL using SHGetPathFromIDListW(). - Fix context menu handling for more than one entry in order to repair .lnk-file execution: Don't break at the first non-matching entry. Markus Gömmel <[email protected]> - Added CSIDL_MYVIDEO|MYPICTURES|MYMUSIC to _SHRegisterUserShellFolders. svn path=/trunk/; revision=20168
This commit is contained in:
@@ -129,7 +129,10 @@ static HICON SIC_OverlayShortcutImage(HICON SourceIcon, BOOL large)
|
||||
|
||||
/* search for the shortcut icon only once */
|
||||
if (s_imgListIdx == -1)
|
||||
s_imgListIdx = SIC_LoadOverlayIcon(-IDI_SHELL_SHORTCUT);
|
||||
s_imgListIdx = SIC_LoadOverlayIcon(- IDI_SHELL_SHORTCUT);
|
||||
/* FIXME should use icon index 29 instead of the
|
||||
resource id, but not all icons are present yet
|
||||
so we can't use icon indices */
|
||||
|
||||
if (s_imgListIdx != -1)
|
||||
{
|
||||
|
||||
@@ -121,9 +121,9 @@ HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uI
|
||||
};
|
||||
|
||||
#define KeyStateToDropEffect(kst)\
|
||||
(((kst) & MK_CONTROL) ?\
|
||||
(((kst) & MK_SHIFT) ? DROPEFFECT_LINK : DROPEFFECT_COPY):\
|
||||
DROPEFFECT_MOVE)
|
||||
((((kst)&(MK_CONTROL|MK_SHIFT))==(MK_CONTROL|MK_SHIFT)) ? DROPEFFECT_LINK :\
|
||||
(((kst)&(MK_CONTROL|MK_SHIFT)) ? DROPEFFECT_COPY :\
|
||||
DROPEFFECT_MOVE))
|
||||
|
||||
HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl);
|
||||
HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl);
|
||||
|
||||
@@ -1808,12 +1808,15 @@ static HRESULT _SHRegisterUserShellFolders(BOOL bDefault)
|
||||
CSIDL_RECENT,
|
||||
CSIDL_SENDTO,
|
||||
CSIDL_STARTMENU,
|
||||
CSIDL_MYMUSIC,
|
||||
CSIDL_MYVIDEO,
|
||||
CSIDL_DESKTOPDIRECTORY,
|
||||
CSIDL_NETHOOD,
|
||||
CSIDL_TEMPLATES,
|
||||
CSIDL_PRINTHOOD,
|
||||
CSIDL_COOKIES,
|
||||
CSIDL_HISTORY,
|
||||
CSIDL_MYPICTURES
|
||||
};
|
||||
WCHAR userShellFolderPath[MAX_PATH], shellFolderPath[MAX_PATH];
|
||||
LPCWSTR pUserShellFolderPath, pShellFolderPath;
|
||||
|
||||
@@ -428,6 +428,9 @@ static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf (IShellFolder2 * iface,
|
||||
static const DWORD dwDesktopAttributes =
|
||||
SFGAO_STORAGE | SFGAO_HASPROPSHEET | SFGAO_STORAGEANCESTOR |
|
||||
SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_FILESYSTEM | SFGAO_HASSUBFOLDER;
|
||||
static const DWORD dwMyComputerAttributes =
|
||||
SFGAO_CANRENAME | SFGAO_CANDELETE | SFGAO_HASPROPSHEET |
|
||||
SFGAO_DROPTARGET | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
|
||||
|
||||
TRACE ("(%p)->(cidl=%d apidl=%p mask=%p (0x%08lx))\n",
|
||||
This, cidl, apidl, rgfInOut, rgfInOut ? *rgfInOut : 0);
|
||||
@@ -447,6 +450,8 @@ static HRESULT WINAPI ISF_Desktop_fnGetAttributesOf (IShellFolder2 * iface,
|
||||
pdump (*apidl);
|
||||
if (_ILIsDesktop(*apidl)) {
|
||||
*rgfInOut &= dwDesktopAttributes;
|
||||
} else if (_ILIsMyComputer(*apidl)) {
|
||||
*rgfInOut &= dwMyComputerAttributes;
|
||||
} else {
|
||||
SHELL32_GetItemAttributes (_IShellFolder_ (This), *apidl, rgfInOut);
|
||||
}
|
||||
|
||||
@@ -1156,15 +1156,15 @@ static LONG ShellExecute_FromContextMenu( LPSHELLEXECUTEINFOW sei )
|
||||
r = RegEnumKeyW( hkeycm, i++, szguid, 39 );
|
||||
if ( r != ERROR_SUCCESS )
|
||||
break;
|
||||
r = ERROR_FUNCTION_FAILED;
|
||||
|
||||
hr = CLSIDFromString( szguid, &guid );
|
||||
if ( FAILED( hr ) )
|
||||
break;
|
||||
r = ERROR_SUCCESS;
|
||||
/* stop at the first one that succeeds in running */
|
||||
hr = shellex_load_object_and_run( hkey, &guid, sei );
|
||||
if ( SUCCEEDED( hr ) )
|
||||
break;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
/* stop at the first one that succeeds in running */
|
||||
hr = shellex_load_object_and_run( hkey, &guid, sei );
|
||||
if ( SUCCEEDED( hr ) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
RegCloseKey( hkeycm );
|
||||
}
|
||||
|
||||
+166
-37
@@ -100,6 +100,10 @@ typedef struct
|
||||
DWORD dwAspects;
|
||||
DWORD dwAdvf;
|
||||
IAdviseSink *pAdvSink;
|
||||
IDropTarget* pCurDropTarget; /* The sub-item, which is currently dragged over */
|
||||
IDataObject* pCurDataObject; /* The dragged data-object */
|
||||
LONG iDragOverItem; /* Dragged over item's index, iff pCurDropTarget != NULL */
|
||||
UINT iActiveTimersMask; /* Bookkeeping of activated timers for drag scrolling */
|
||||
} IShellViewImpl;
|
||||
|
||||
static const IShellViewVtbl svvt;
|
||||
@@ -190,6 +194,11 @@ IShellView * IShellView_Constructor( IShellFolder * pFolder)
|
||||
if(pFolder) IShellFolder_AddRef(pFolder);
|
||||
IShellFolder_QueryInterface(sv->pSFParent, &IID_IShellFolder2, (LPVOID*)&sv->pSF2Parent);
|
||||
|
||||
sv->pCurDropTarget = NULL;
|
||||
sv->pCurDataObject = NULL;
|
||||
sv->iDragOverItem = 0;
|
||||
sv->iActiveTimersMask = 0;
|
||||
|
||||
TRACE("(%p)->(%p)\n",sv, pFolder);
|
||||
return (IShellView *) sv;
|
||||
}
|
||||
@@ -671,7 +680,7 @@ static LRESULT ShellView_OnCreate(IShellViewImpl * This)
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(IShellFolder_CreateViewObject(This->pSFParent, This->hWnd, &IID_IDropTarget, (LPVOID*)&pdt)))
|
||||
if (SUCCEEDED(IUnknown_QueryInterface((IUnknown*)&This->lpVtbl, &IID_IDropTarget, (LPVOID*)&pdt)))
|
||||
{
|
||||
RegisterDragDrop(This->hWnd, pdt);
|
||||
IDropTarget_Release(pdt);
|
||||
@@ -2169,56 +2178,176 @@ static ULONG WINAPI ISVDropTarget_Release( IDropTarget *iface)
|
||||
return IShellFolder_Release((IShellFolder*)This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ISVDropTarget_DragEnter(
|
||||
IDropTarget *iface,
|
||||
IDataObject *pDataObject,
|
||||
DWORD grfKeyState,
|
||||
POINTL pt,
|
||||
DWORD *pdwEffect)
|
||||
{
|
||||
/******************************************************************************
|
||||
* scroll_timer_proc [Internal]
|
||||
*
|
||||
* Timer callback function for drag&drop scrolling
|
||||
*/
|
||||
|
||||
IShellViewImpl *This = impl_from_IDropTarget(iface);
|
||||
#define IDT_UP 0x1u
|
||||
#define IDT_DOWN 0x2u
|
||||
#define IDT_LEFT 0x4u
|
||||
#define IDT_RIGHT 0x8u
|
||||
|
||||
FIXME("Stub: This=%p, DataObject=%p\n",This,pDataObject);
|
||||
|
||||
return E_NOTIMPL;
|
||||
VOID CALLBACK scroll_timer_proc(HWND hwnd, UINT uMsg, UINT_PTR idTimer, DWORD dwTimer) {
|
||||
switch (idTimer) {
|
||||
case IDT_UP:
|
||||
SendMessageW(hwnd, WM_VSCROLL, SB_LINEUP, 0);
|
||||
break;
|
||||
case IDT_DOWN:
|
||||
SendMessageW(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);
|
||||
break;
|
||||
case IDT_LEFT:
|
||||
SendMessageW(hwnd, WM_HSCROLL, SB_LINEUP, 0);
|
||||
break;
|
||||
case IDT_RIGHT:
|
||||
SendMessageW(hwnd, WM_HSCROLL, SB_LINEDOWN, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ISVDropTarget_DragOver(
|
||||
IDropTarget *iface,
|
||||
DWORD grfKeyState,
|
||||
POINTL pt,
|
||||
DWORD *pdwEffect)
|
||||
{
|
||||
IShellViewImpl *This = impl_from_IDropTarget(iface);
|
||||
|
||||
FIXME("Stub: This=%p\n",This);
|
||||
|
||||
return E_NOTIMPL;
|
||||
/******************************************************************************
|
||||
* start_stop_timer [Internal]
|
||||
*/
|
||||
static inline void start_stop_timer(IShellViewImpl *This, UINT_PTR idTimer, BOOL fStart) {
|
||||
if (fStart && !(This->iActiveTimersMask & idTimer)) {
|
||||
SetTimer(This->hWndList, idTimer, 200, scroll_timer_proc);
|
||||
This->iActiveTimersMask |= idTimer;
|
||||
}
|
||||
if (!fStart && This->iActiveTimersMask & idTimer) {
|
||||
KillTimer(This->hWndList, idTimer);
|
||||
This->iActiveTimersMask &= ~idTimer;
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ISVDropTarget_DragLeave(
|
||||
IDropTarget *iface)
|
||||
/******************************************************************************
|
||||
* drag_notify_subitem [Internal]
|
||||
*
|
||||
* Figure out the shellfolder object, which is currently under the mouse cursor
|
||||
* and notify it via the IDropTarget interface.
|
||||
*/
|
||||
|
||||
#define SCROLLAREAWIDTH 20
|
||||
|
||||
static HRESULT drag_notify_subitem(IShellViewImpl *This, DWORD grfKeyState, POINTL pt,
|
||||
DWORD *pdwEffect)
|
||||
{
|
||||
IShellViewImpl *This = impl_from_IDropTarget(iface);
|
||||
LVHITTESTINFO htinfo;
|
||||
LVITEMA lvItem;
|
||||
LONG lResult;
|
||||
HRESULT hr;
|
||||
RECT clientRect;
|
||||
|
||||
FIXME("Stub: This=%p\n",This);
|
||||
/* Map from global to client coordinates and query the index of the listview-item, which is
|
||||
* currently under the mouse cursor. */
|
||||
htinfo.pt.x = pt.x;
|
||||
htinfo.pt.y = pt.y;
|
||||
htinfo.flags = LVHT_ONITEM;
|
||||
ScreenToClient(This->hWndList, &htinfo.pt);
|
||||
lResult = SendMessageW(This->hWndList, LVM_HITTEST, 0, (LPARAM)&htinfo);
|
||||
|
||||
return E_NOTIMPL;
|
||||
/* Start or stop the drag scrolling timers */
|
||||
GetClientRect(This->hWndList, &clientRect);
|
||||
start_stop_timer(This, IDT_LEFT, htinfo.pt.x < SCROLLAREAWIDTH);
|
||||
start_stop_timer(This, IDT_RIGHT, htinfo.pt.x > clientRect.right - SCROLLAREAWIDTH);
|
||||
start_stop_timer(This, IDT_UP, htinfo.pt.y < SCROLLAREAWIDTH);
|
||||
start_stop_timer(This, IDT_DOWN, htinfo.pt.y > clientRect.bottom - SCROLLAREAWIDTH);
|
||||
|
||||
/* If we are still over the previous sub-item, notify it via DragOver and return. */
|
||||
if (This->pCurDropTarget && lResult == This->iDragOverItem)
|
||||
return IDropTarget_DragOver(This->pCurDropTarget, grfKeyState, pt, pdwEffect);
|
||||
|
||||
/* We've left the previous sub-item, notify it via DragLeave and Release it. */
|
||||
if (This->pCurDropTarget) {
|
||||
IDropTarget_DragLeave(This->pCurDropTarget);
|
||||
IDropTarget_Release(This->pCurDropTarget);
|
||||
This->pCurDropTarget = NULL;
|
||||
}
|
||||
|
||||
This->iDragOverItem = lResult;
|
||||
if (lResult == -1) {
|
||||
/* We are not above one of the listview's subitems. Bind to the parent folder's
|
||||
* DropTarget interface. */
|
||||
hr = IShellFolder_QueryInterface(This->pSFParent, &IID_IDropTarget,
|
||||
(LPVOID*)&This->pCurDropTarget);
|
||||
} else {
|
||||
/* Query the relative PIDL of the shellfolder object represented by the currently
|
||||
* dragged over listview-item ... */
|
||||
ZeroMemory(&lvItem, sizeof(lvItem));
|
||||
lvItem.mask = LVIF_PARAM;
|
||||
lvItem.iItem = lResult;
|
||||
ListView_GetItemA(This->hWndList, &lvItem);
|
||||
|
||||
/* ... and bind pCurDropTarget to the IDropTarget interface of an UIObject of this object */
|
||||
hr = IShellFolder_GetUIObjectOf(This->pSFParent, This->hWndList, 1,
|
||||
(LPCITEMIDLIST*)&lvItem.lParam, &IID_IDropTarget, NULL, (LPVOID*)&This->pCurDropTarget);
|
||||
}
|
||||
|
||||
/* If anything failed, pCurDropTarget should be NULL now, which ought to be a save state. */
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
/* Notify the item just entered via DragEnter. */
|
||||
return IDropTarget_DragEnter(This->pCurDropTarget, This->pCurDataObject, grfKeyState, pt, pdwEffect);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ISVDropTarget_Drop(
|
||||
IDropTarget *iface,
|
||||
IDataObject* pDataObject,
|
||||
DWORD grfKeyState,
|
||||
POINTL pt,
|
||||
DWORD *pdwEffect)
|
||||
static HRESULT WINAPI ISVDropTarget_DragEnter(IDropTarget *iface, IDataObject *pDataObject,
|
||||
DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
|
||||
{
|
||||
IShellViewImpl *This = impl_from_IDropTarget(iface);
|
||||
IShellViewImpl *This = impl_from_IDropTarget(iface);
|
||||
|
||||
FIXME("Stub: This=%p\n",This);
|
||||
/* Get a hold on the data object for later calls to DragEnter on the sub-folders */
|
||||
This->pCurDataObject = pDataObject;
|
||||
IDataObject_AddRef(pDataObject);
|
||||
|
||||
return E_NOTIMPL;
|
||||
return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ISVDropTarget_DragOver(IDropTarget *iface, DWORD grfKeyState, POINTL pt,
|
||||
DWORD *pdwEffect)
|
||||
{
|
||||
IShellViewImpl *This = impl_from_IDropTarget(iface);
|
||||
return drag_notify_subitem(This, grfKeyState, pt, pdwEffect);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ISVDropTarget_DragLeave(IDropTarget *iface) {
|
||||
IShellViewImpl *This = impl_from_IDropTarget(iface);
|
||||
|
||||
IDropTarget_DragLeave(This->pCurDropTarget);
|
||||
|
||||
IDropTarget_Release(This->pCurDropTarget);
|
||||
IDataObject_Release(This->pCurDataObject);
|
||||
This->pCurDataObject = NULL;
|
||||
This->pCurDropTarget = NULL;
|
||||
This->iDragOverItem = 0;
|
||||
|
||||
start_stop_timer(This, IDT_LEFT, FALSE);
|
||||
start_stop_timer(This, IDT_RIGHT, FALSE);
|
||||
start_stop_timer(This, IDT_UP, FALSE);
|
||||
start_stop_timer(This, IDT_DOWN, FALSE);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI ISVDropTarget_Drop(IDropTarget *iface, IDataObject* pDataObject,
|
||||
DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
|
||||
{
|
||||
IShellViewImpl *This = impl_from_IDropTarget(iface);
|
||||
|
||||
IDropTarget_Drop(This->pCurDropTarget, pDataObject, grfKeyState, pt, pdwEffect);
|
||||
|
||||
IDropTarget_Release(This->pCurDropTarget);
|
||||
IDataObject_Release(This->pCurDataObject);
|
||||
This->pCurDataObject = NULL;
|
||||
This->pCurDropTarget = NULL;
|
||||
This->iDragOverItem = 0;
|
||||
|
||||
start_stop_timer(This, IDT_LEFT, FALSE);
|
||||
start_stop_timer(This, IDT_RIGHT, FALSE);
|
||||
start_stop_timer(This, IDT_UP, FALSE);
|
||||
start_stop_timer(This, IDT_DOWN, FALSE);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IDropTargetVtbl dtvt =
|
||||
|
||||
Reference in New Issue
Block a user