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
6d1ef3a6
Commit
6d1ef3a6
authored
Jul 22, 2010
by
Huw Davies
Committed by
Alexandre Julliard
Jul 22, 2010
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ole32: Implement cross-process drag and drop.
parent
a2e1dd29
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
188 additions
and
31 deletions
+188
-31
ole2.c
dlls/ole32/ole2.c
+188
-31
No files found.
dlls/ole32/ole2.c
View file @
6d1ef3a6
...
...
@@ -116,6 +116,10 @@ static const WCHAR prop_olemenuW[] =
static
const
WCHAR
prop_oledroptarget
[]
=
{
'O'
,
'l'
,
'e'
,
'D'
,
'r'
,
'o'
,
'p'
,
'T'
,
'a'
,
'r'
,
'g'
,
'e'
,
't'
,
'I'
,
'n'
,
't'
,
'e'
,
'r'
,
'f'
,
'a'
,
'c'
,
'e'
,
0
};
/* property to store Marshalled IDropTarget pointer */
static
const
WCHAR
prop_marshalleddroptarget
[]
=
{
'W'
,
'i'
,
'n'
,
'e'
,
'M'
,
'a'
,
'r'
,
's'
,
'h'
,
'a'
,
'l'
,
'l'
,
'e'
,
'd'
,
'D'
,
'r'
,
'o'
,
'p'
,
'T'
,
'a'
,
'r'
,
'g'
,
'e'
,
't'
,
0
};
static
const
WCHAR
clsidfmtW
[]
=
{
'C'
,
'L'
,
'S'
,
'I'
,
'D'
,
'\\'
,
'{'
,
'%'
,
'0'
,
'8'
,
'x'
,
'-'
,
'%'
,
'0'
,
'4'
,
'x'
,
'-'
,
'%'
,
'0'
,
'4'
,
'x'
,
'-'
,
'%'
,
'0'
,
'2'
,
'x'
,
'%'
,
'0'
,
'2'
,
'x'
,
'-'
,
'%'
,
'0'
,
'2'
,
'x'
,
'%'
,
'0'
,
'2'
,
'x'
,
'%'
,
'0'
,
'2'
,
'x'
,
'%'
,
'0'
,
'2'
,
'x'
,
...
...
@@ -266,14 +270,134 @@ HRESULT WINAPI OleInitializeWOW(DWORD x, DWORD y) {
return
0
;
}
/***
* OLEDD_FindDropTarget()
/*************************************************************
* get_droptarget_handle
*
* Retrieve a handle to the map containing the marshalled IDropTarget.
* This handle belongs to the process that called RegisterDragDrop.
* See get_droptarget_local_handle().
*/
static
inline
HANDLE
get_droptarget_handle
(
HWND
hwnd
)
{
return
GetPropW
(
hwnd
,
prop_marshalleddroptarget
);
}
/*************************************************************
* is_droptarget
*
* Is the window a droptarget.
*/
static
inline
BOOL
is_droptarget
(
HWND
hwnd
)
{
return
get_droptarget_handle
(
hwnd
)
?
TRUE
:
FALSE
;
}
/*************************************************************
* get_droptarget_local_handle
*
* Retrieve a handle to the map containing the marshalled IDropTarget.
* The handle should be closed when finished with.
*/
static
HANDLE
get_droptarget_local_handle
(
HWND
hwnd
)
{
HANDLE
handle
,
local_handle
=
0
;
handle
=
get_droptarget_handle
(
hwnd
);
if
(
handle
)
{
DWORD
pid
;
HANDLE
process
;
GetWindowThreadProcessId
(
hwnd
,
&
pid
);
process
=
OpenProcess
(
PROCESS_DUP_HANDLE
,
FALSE
,
pid
);
if
(
process
)
{
DuplicateHandle
(
process
,
handle
,
GetCurrentProcess
(),
&
local_handle
,
0
,
FALSE
,
DUPLICATE_SAME_ACCESS
);
CloseHandle
(
process
);
}
}
return
local_handle
;
}
/***********************************************************************
* create_map_from_stream
*
* Helper for RegisterDragDrop. Creates a file mapping object
* with the contents of the provided stream. The stream must
* be a global memory backed stream.
*/
static
HRESULT
create_map_from_stream
(
IStream
*
stream
,
HANDLE
*
map
)
{
HGLOBAL
hmem
;
DWORD
size
;
HRESULT
hr
;
void
*
data
;
hr
=
GetHGlobalFromStream
(
stream
,
&
hmem
);
if
(
FAILED
(
hr
))
return
hr
;
size
=
GlobalSize
(
hmem
);
*
map
=
CreateFileMappingW
(
INVALID_HANDLE_VALUE
,
NULL
,
PAGE_READWRITE
,
0
,
size
,
NULL
);
if
(
!*
map
)
return
E_OUTOFMEMORY
;
data
=
MapViewOfFile
(
*
map
,
FILE_MAP_WRITE
,
0
,
0
,
size
);
memcpy
(
data
,
GlobalLock
(
hmem
),
size
);
GlobalUnlock
(
hmem
);
UnmapViewOfFile
(
data
);
return
S_OK
;
}
/***********************************************************************
* create_stream_from_map
*
* Creates a stream from the provided map.
*/
static
HRESULT
create_stream_from_map
(
HANDLE
map
,
IStream
**
stream
)
{
HRESULT
hr
=
E_OUTOFMEMORY
;
HGLOBAL
hmem
;
void
*
data
;
MEMORY_BASIC_INFORMATION
info
;
data
=
MapViewOfFile
(
map
,
FILE_MAP_READ
,
0
,
0
,
0
);
if
(
!
data
)
return
hr
;
VirtualQuery
(
data
,
&
info
,
sizeof
(
info
));
TRACE
(
"size %d
\n
"
,
(
int
)
info
.
RegionSize
);
hmem
=
GlobalAlloc
(
GMEM_MOVEABLE
,
info
.
RegionSize
);
if
(
hmem
)
{
memcpy
(
GlobalLock
(
hmem
),
data
,
info
.
RegionSize
);
GlobalUnlock
(
hmem
);
hr
=
CreateStreamOnHGlobal
(
hmem
,
TRUE
,
stream
);
}
UnmapViewOfFile
(
data
);
return
hr
;
}
/***********************************************************************
* get_droptarget_pointer
*
* Ret
urns IDropTarget pointer registered for this
window.
* Ret
rieves the marshalled IDropTarget from the
window.
*/
static
inline
IDropTarget
*
OLEDD_FindDropTarget
(
HWND
hwnd
)
static
IDropTarget
*
get_droptarget_pointer
(
HWND
hwnd
)
{
return
GetPropW
(
hwnd
,
prop_oledroptarget
);
IDropTarget
*
droptarget
=
NULL
;
HANDLE
map
;
IStream
*
stream
;
map
=
get_droptarget_local_handle
(
hwnd
);
if
(
!
map
)
return
NULL
;
if
(
SUCCEEDED
(
create_stream_from_map
(
map
,
&
stream
)))
{
CoUnmarshalInterface
(
stream
,
&
IID_IDropTarget
,
(
void
**
)
&
droptarget
);
IStream_Release
(
stream
);
}
CloseHandle
(
map
);
return
droptarget
;
}
/***********************************************************************
...
...
@@ -282,6 +406,9 @@ static inline IDropTarget* OLEDD_FindDropTarget(HWND hwnd)
HRESULT
WINAPI
RegisterDragDrop
(
HWND
hwnd
,
LPDROPTARGET
pDropTarget
)
{
DWORD
pid
=
0
;
HRESULT
hr
;
IStream
*
stream
;
HANDLE
map
;
TRACE
(
"(%p,%p)
\n
"
,
hwnd
,
pDropTarget
);
...
...
@@ -309,13 +436,40 @@ HRESULT WINAPI RegisterDragDrop(HWND hwnd, LPDROPTARGET pDropTarget)
}
/* check if the window is already registered */
if
(
OLEDD_FindDropT
arget
(
hwnd
))
if
(
is_dropt
arget
(
hwnd
))
return
DRAGDROP_E_ALREADYREGISTERED
;
IDropTarget_AddRef
(
pDropTarget
);
SetPropW
(
hwnd
,
prop_oledroptarget
,
pDropTarget
);
/*
* Marshal the drop target pointer into a shared memory map and
* store the map's handle in a Wine specific window prop. We also
* store the drop target pointer itself in the
* "OleDropTargetInterface" prop for compatibility with Windows.
*/
hr
=
CreateStreamOnHGlobal
(
NULL
,
TRUE
,
&
stream
);
if
(
FAILED
(
hr
))
return
hr
;
return
S_OK
;
hr
=
CoMarshalInterface
(
stream
,
&
IID_IDropTarget
,
(
IUnknown
*
)
pDropTarget
,
MSHCTX_LOCAL
,
NULL
,
MSHLFLAGS_TABLESTRONG
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
create_map_from_stream
(
stream
,
&
map
);
if
(
SUCCEEDED
(
hr
))
{
IDropTarget_AddRef
(
pDropTarget
);
SetPropW
(
hwnd
,
prop_oledroptarget
,
pDropTarget
);
SetPropW
(
hwnd
,
prop_marshalleddroptarget
,
map
);
}
else
{
LARGE_INTEGER
zero
;
zero
.
QuadPart
=
0
;
IStream_Seek
(
stream
,
zero
,
STREAM_SEEK_SET
,
NULL
);
CoReleaseMarshalData
(
stream
);
}
}
IStream_Release
(
stream
);
return
hr
;
}
/***********************************************************************
...
...
@@ -323,7 +477,10 @@ HRESULT WINAPI RegisterDragDrop(HWND hwnd, LPDROPTARGET pDropTarget)
*/
HRESULT
WINAPI
RevokeDragDrop
(
HWND
hwnd
)
{
IDropTarget
*
droptarget
;
HANDLE
map
;
IStream
*
stream
;
IDropTarget
*
drop_target
;
HRESULT
hr
;
TRACE
(
"(%p)
\n
"
,
hwnd
);
...
...
@@ -334,13 +491,24 @@ HRESULT WINAPI RevokeDragDrop(HWND hwnd)
}
/* no registration data */
if
(
!
(
droptarget
=
OLEDD_FindDropTarget
(
hwnd
)))
if
(
!
(
map
=
get_droptarget_handle
(
hwnd
)))
return
DRAGDROP_E_NOTREGISTERED
;
IDropTarget_Release
(
droptarget
);
drop_target
=
GetPropW
(
hwnd
,
prop_oledroptarget
);
if
(
drop_target
)
IDropTarget_Release
(
drop_target
);
RemovePropW
(
hwnd
,
prop_oledroptarget
);
RemovePropW
(
hwnd
,
prop_marshalleddroptarget
);
return
S_OK
;
hr
=
create_stream_from_map
(
map
,
&
stream
);
if
(
SUCCEEDED
(
hr
))
{
CoReleaseMarshalData
(
stream
);
IStream_Release
(
stream
);
}
CloseHandle
(
map
);
return
hr
;
}
/***********************************************************************
...
...
@@ -1975,30 +2143,17 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo)
* Find-out if there is a drag target under the mouse
*/
HWND
next_target_wnd
=
hwndNewTarget
;
IDropTarget
*
new_target
;
DWORD
pid
;
trackerInfo
->
curTargetHWND
=
hwndNewTarget
;
do
{
new_target
=
OLEDD_FindDropTarget
(
next_target_wnd
);
}
while
(
!
new_target
&&
(
next_target_wnd
=
GetParent
(
next_target_wnd
)));
while
(
next_target_wnd
&&
!
is_droptarget
(
next_target_wnd
))
next_target_wnd
=
GetParent
(
next_target_wnd
);
if
(
next_target_wnd
)
hwndNewTarget
=
next_target_wnd
;
GetWindowThreadProcessId
(
hwndNewTarget
,
&
pid
);
if
(
pid
!=
GetCurrentProcessId
())
{
FIXME
(
"drop to another process window is unsupported
\n
"
);
trackerInfo
->
curDragTargetHWND
=
0
;
trackerInfo
->
curTargetHWND
=
0
;
trackerInfo
->
curDragTarget
=
0
;
}
else
{
trackerInfo
->
curDragTargetHWND
=
hwndNewTarget
;
trackerInfo
->
curDragTarget
=
new_target
;
}
trackerInfo
->
curDragTargetHWND
=
hwndNewTarget
;
if
(
trackerInfo
->
curDragTarget
)
IDropTarget_Release
(
trackerInfo
->
curDragTarget
);
trackerInfo
->
curDragTarget
=
get_droptarget_pointer
(
hwndNewTarget
);
/*
* If there is, notify it that we just dragged-in
...
...
@@ -2016,6 +2171,7 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo)
{
trackerInfo
->
curDragTargetHWND
=
0
;
trackerInfo
->
curTargetHWND
=
0
;
IDropTarget_Release
(
trackerInfo
->
curDragTarget
);
trackerInfo
->
curDragTarget
=
0
;
}
}
...
...
@@ -2027,6 +2183,7 @@ static void OLEDD_TrackMouseMove(TrackerWindowInfo* trackerInfo)
*/
trackerInfo
->
curDragTargetHWND
=
0
;
trackerInfo
->
curTargetHWND
=
0
;
if
(
trackerInfo
->
curDragTarget
)
IDropTarget_Release
(
trackerInfo
->
curDragTarget
);
trackerInfo
->
curDragTarget
=
0
;
}
}
...
...
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