/
dragdrop-listener.factor
75 lines (67 loc) · 2.59 KB
/
dragdrop-listener.factor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
! Copyright (C) 2008, 2009 Joe Groff, Slava Pestov.
! Copyright (C) 2017-2018 Alexander Ilin.
! See https://factorcode.org/license.txt for BSD license.
USING: accessors alien.accessors classes.struct kernel
namespaces sequences ui.backend.windows ui.gadgets.worlds
ui.gestures windows.com windows.com.wrapper windows.dropfiles
windows.kernel32 windows.ole32 windows.user32 ;
IN: windows.dragdrop-listener
: handle-data-object ( handler: ( hdrop -- x ) data-object -- filenames )
FORMATETC new
CF_HDROP >>cfFormat
f >>ptd
DVASPECT_CONTENT >>dwAspect
-1 >>lindex
TYMED_HGLOBAL >>tymed
STGMEDIUM new
[ IDataObject::GetData ] keep swap succeeded? [
dup data>>
[ rot execute( hdrop -- x ) ] with-global-lock
swap ReleaseStgMedium
] [ 2drop f ] if ;
: filenames-from-data-object ( data-object -- filenames )
\ filenames-from-hdrop swap handle-data-object ;
: filecount-from-data-object ( data-object -- n )
\ filecount-from-hdrop swap handle-data-object ;
TUPLE: listener-dragdrop world last-drop-effect ;
: <listener-dragdrop> ( world -- object )
DROPEFFECT_NONE listener-dragdrop boa ;
<<
SYMBOL: +listener-dragdrop-wrapper+
>>
<<
{
{ IDropTarget {
[ ! HRESULT DragEnter ( IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect )
DROPEFFECT_COPY swap 0 set-alien-unsigned-4 3drop
DROPEFFECT_COPY >>last-drop-effect drop
S_OK
] [ ! HRESULT DragOver ( DWORD grfKeyState, POINTL pt, DWORD* pdwEffect )
[
2drop
[ world>> children>> first hand-gadget set-global ]
[ last-drop-effect>> ] bi
] dip 0 set-alien-unsigned-4
S_OK
] [ ! HRESULT DragLeave ( )
drop S_OK
] [ ! HRESULT Drop ( IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect )
[
2drop nip
filenames-from-data-object dropped-files set-global
key-modifiers <file-drop> hand-gadget get-global propagate-gesture
DROPEFFECT_COPY
] dip 0 set-alien-unsigned-4
S_OK
]
} }
} <com-wrapper> +listener-dragdrop-wrapper+ set-global
>>
: dragdrop-listener-window ( -- )
world get dup <listener-dragdrop>
+listener-dragdrop-wrapper+ get-global com-wrap [
[ handle>> hWnd>> ] dip
2dup RegisterDragDrop dup E_OUTOFMEMORY =
[ drop ole-initialize RegisterDragDrop ] [ 2nip ] if
check-ole32-error
] with-com-interface ;