Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
df9c67d1
Commit
df9c67d1
authored
Sep 10, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shell32: Merge the drag & drop implementation from the Unix shell folder.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
aef981df
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
100 additions
and
34 deletions
+100
-34
shfldr_fs.c
dlls/shell32/shfldr_fs.c
+100
-34
No files found.
dlls/shell32/shfldr_fs.c
View file @
df9c67d1
...
...
@@ -72,11 +72,11 @@ typedef struct {
LPWSTR
sPathTarget
;
/* complete path to target used for enumeration and ChangeNotify */
LPITEMIDLIST
pidlRoot
;
/* absolute pidl */
UINT
cfShellIDList
;
/* clipboardformat for IDropTarget */
BOOL
fAcceptFmt
;
/* flag for pending Drop */
DWORD
drop_effects_mask
;
}
IGenericSFImpl
;
static
UINT
cfShellIDList
;
static
inline
IGenericSFImpl
*
impl_from_IUnknown
(
IUnknown
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
IGenericSFImpl
,
IUnknown_inner
);
...
...
@@ -103,18 +103,6 @@ static inline IGenericSFImpl *impl_from_ISFHelper(ISFHelper *iface)
}
/**************************************************************************
* registers clipboardformat once
*/
static
void
SF_RegisterClipFmt
(
IGenericSFImpl
*
This
)
{
TRACE
(
"(%p)
\n
"
,
This
);
if
(
!
This
->
cfShellIDList
)
{
This
->
cfShellIDList
=
RegisterClipboardFormatW
(
CFSTR_SHELLIDLISTW
);
}
}
/**************************************************************************
* inner IUnknown
*/
static
HRESULT
WINAPI
IUnknown_fnQueryInterface
(
IUnknown
*
iface
,
REFIID
riid
,
void
**
ppvObj
)
...
...
@@ -136,7 +124,7 @@ static HRESULT WINAPI IUnknown_fnQueryInterface(IUnknown *iface, REFIID riid, vo
*
ppvObj
=
&
This
->
ISFHelper_iface
;
else
if
(
IsEqualIID
(
riid
,
&
IID_IDropTarget
))
{
*
ppvObj
=
&
This
->
IDropTarget_iface
;
SF_RegisterClipFmt
(
This
);
if
(
!
cfShellIDList
)
cfShellIDList
=
RegisterClipboardFormatW
(
CFSTR_SHELLIDLISTW
);
}
if
(
*
ppvObj
)
{
...
...
@@ -1543,22 +1531,42 @@ static ULONG WINAPI ISFDropTarget_Release(IDropTarget *iface)
return
IUnknown_Release
(
This
->
outer_unk
);
}
#define HIDA_GetPIDLFolder(pida) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[0])
#define HIDA_GetPIDLItem(pida, i) (LPCITEMIDLIST)(((LPBYTE)pida)+(pida)->aoffset[i+1])
static
HRESULT
WINAPI
ISFDropTarget_DragEnter
(
IDropTarget
*
iface
,
IDataObject
*
pDataObject
,
DWORD
dwKeyState
,
POINTL
pt
,
DWORD
*
pdwEffect
)
{
FORMATETC
fmt
;
IGenericSFImpl
*
This
=
impl_from_IDropTarget
(
iface
);
FORMATETC
format
;
STGMEDIUM
medium
;
TRACE
(
"(%p)->(DataObject=%p)
\n
"
,
This
,
pDataObj
ect
);
TRACE
(
"(%p)->(%p 0x%08x {.x=%d, .y=%d} %p)
\n
"
,
This
,
pDataObject
,
dwKeyState
,
pt
.
x
,
pt
.
y
,
pdwEff
ect
);
InitFormatEtc
(
fmt
,
This
->
cfShellIDList
,
TYMED_HGLOBAL
);
This
->
fAcceptFmt
=
IDataObject_QueryGetData
(
pDataObject
,
&
fmt
)
==
S_OK
;
if
(
This
->
fAcceptFmt
)
*
pdwEffect
=
KeyStateToDropEffect
(
dwKeyState
);
else
*
pdwEffect
=
DROPEFFECT_NONE
;
if
(
!
pdwEffect
||
!
pDataObject
)
return
E_INVALIDARG
;
/* Compute a mask of supported drop-effects for this shellfolder object and the given data
* object. Dropping is only supported on folders, which represent filesystem locations. One
* can't drop on file objects. And the 'move' drop effect is only supported, if the source
* folder is not identical to the target folder. */
This
->
drop_effects_mask
=
DROPEFFECT_NONE
;
InitFormatEtc
(
format
,
cfShellIDList
,
TYMED_HGLOBAL
);
if
(
_ILIsFolder
(
ILFindLastID
(
This
->
pidlRoot
))
&&
/* Only drop to folders, not to files */
SUCCEEDED
(
IDataObject_GetData
(
pDataObject
,
&
format
,
&
medium
)))
/* Only ShellIDList format */
{
LPIDA
pidaShellIDList
=
GlobalLock
(
medium
.
u
.
hGlobal
);
This
->
drop_effects_mask
|=
DROPEFFECT_COPY
|
DROPEFFECT_LINK
;
if
(
pidaShellIDList
)
{
/* Files can only be moved between two different folders */
if
(
!
ILIsEqual
(
HIDA_GetPIDLFolder
(
pidaShellIDList
),
This
->
pidlRoot
))
This
->
drop_effects_mask
|=
DROPEFFECT_MOVE
;
GlobalUnlock
(
medium
.
u
.
hGlobal
);
}
}
*
pdwEffect
=
KeyStateToDropEffect
(
dwKeyState
)
&
This
->
drop_effects_mask
;
return
S_OK
;
}
...
...
@@ -1569,15 +1577,12 @@ ISFDropTarget_DragOver (IDropTarget * iface, DWORD dwKeyState, POINTL pt,
{
IGenericSFImpl
*
This
=
impl_from_IDropTarget
(
iface
);
TRACE
(
"(%p)
\n
"
,
This
);
TRACE
(
"(%p)->(0x%08x {.x=%d, .y=%d} %p)
\n
"
,
This
,
dwKeyState
,
pt
.
x
,
pt
.
y
,
pdwEffect
);
if
(
!
pdwEffect
)
return
E_INVALIDARG
;
if
(
This
->
fAcceptFmt
)
*
pdwEffect
=
KeyStateToDropEffect
(
dwKeyState
);
else
*
pdwEffect
=
DROPEFFECT_NONE
;
*
pdwEffect
=
KeyStateToDropEffect
(
dwKeyState
)
&
This
->
drop_effects_mask
;
return
S_OK
;
}
...
...
@@ -1586,10 +1591,9 @@ static HRESULT WINAPI ISFDropTarget_DragLeave (IDropTarget * iface)
{
IGenericSFImpl
*
This
=
impl_from_IDropTarget
(
iface
);
TRACE
(
"(%p)
\n
"
,
This
);
This
->
fAcceptFmt
=
FALSE
;
TRACE
(
"(%p)
\n
"
,
This
);
This
->
drop_effects_mask
=
DROPEFFECT_NONE
;
return
S_OK
;
}
...
...
@@ -1598,8 +1602,70 @@ ISFDropTarget_Drop (IDropTarget * iface, IDataObject * pDataObject,
DWORD
dwKeyState
,
POINTL
pt
,
DWORD
*
pdwEffect
)
{
IGenericSFImpl
*
This
=
impl_from_IDropTarget
(
iface
);
FORMATETC
format
;
STGMEDIUM
medium
;
HRESULT
hr
;
TRACE
(
"(%p)->(%p %d {.x=%d, .y=%d} %p) semi-stub
\n
"
,
This
,
pDataObject
,
dwKeyState
,
pt
.
x
,
pt
.
y
,
pdwEffect
);
InitFormatEtc
(
format
,
cfShellIDList
,
TYMED_HGLOBAL
);
hr
=
IDataObject_GetData
(
pDataObject
,
&
format
,
&
medium
);
if
(
FAILED
(
hr
))
return
hr
;
if
(
medium
.
tymed
==
TYMED_HGLOBAL
)
{
IShellFolder
*
psfSourceFolder
,
*
psfDesktopFolder
;
LPIDA
pidaShellIDList
=
GlobalLock
(
medium
.
u
.
hGlobal
);
STRRET
strret
;
UINT
i
;
if
(
!
pidaShellIDList
)
return
HRESULT_FROM_WIN32
(
GetLastError
());
hr
=
SHGetDesktopFolder
(
&
psfDesktopFolder
);
if
(
FAILED
(
hr
))
{
GlobalUnlock
(
medium
.
u
.
hGlobal
);
return
hr
;
}
hr
=
IShellFolder_BindToObject
(
psfDesktopFolder
,
HIDA_GetPIDLFolder
(
pidaShellIDList
),
NULL
,
&
IID_IShellFolder
,
(
LPVOID
*
)
&
psfSourceFolder
);
IShellFolder_Release
(
psfDesktopFolder
);
if
(
FAILED
(
hr
))
{
GlobalUnlock
(
medium
.
u
.
hGlobal
);
return
hr
;
}
FIXME
(
"(%p) object dropped
\n
"
,
This
);
for
(
i
=
0
;
i
<
pidaShellIDList
->
cidl
;
i
++
)
{
WCHAR
wszSourcePath
[
MAX_PATH
];
hr
=
IShellFolder_GetDisplayNameOf
(
psfSourceFolder
,
HIDA_GetPIDLItem
(
pidaShellIDList
,
i
),
SHGDN_FORPARSING
,
&
strret
);
if
(
FAILED
(
hr
))
break
;
hr
=
StrRetToBufW
(
&
strret
,
NULL
,
wszSourcePath
,
MAX_PATH
);
if
(
FAILED
(
hr
))
break
;
switch
(
*
pdwEffect
)
{
case
DROPEFFECT_MOVE
:
FIXME
(
"Move %s to %s!
\n
"
,
debugstr_w
(
wszSourcePath
),
debugstr_w
(
This
->
sPathTarget
));
break
;
case
DROPEFFECT_COPY
:
FIXME
(
"Copy %s to %s!
\n
"
,
debugstr_w
(
wszSourcePath
),
debugstr_w
(
This
->
sPathTarget
));
break
;
case
DROPEFFECT_LINK
:
FIXME
(
"Link %s from %s!
\n
"
,
debugstr_w
(
wszSourcePath
),
debugstr_w
(
This
->
sPathTarget
));
break
;
}
}
IShellFolder_Release
(
psfSourceFolder
);
GlobalUnlock
(
medium
.
u
.
hGlobal
);
return
hr
;
}
return
E_NOTIMPL
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment