af3547b6bec26121feb2d56ac9e78427f6c6b8a4
[vlc.git] / modules / gui / skins / win32 / win32_dragdrop.cpp
1 /*****************************************************************************
2  * win32_dragdrop.cpp: Win32 implementation of the drag & drop
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: win32_dragdrop.cpp,v 1.1 2003/03/18 02:21:47 ipkiss Exp $
6  *
7  * Authors: Olivier Teulière <ipkiss@via.ecp.fr>
8  *          Emmanuel Puig    <karibu@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111,
23  * USA.
24  *****************************************************************************/
25
26
27 //--- GENERAL ---------------------------------------------------------------
28 #include <list>
29 using namespace std;
30
31 //--- WIN32 -----------------------------------------------------------------
32 #include <windows.h>
33
34 //--- SKIN ------------------------------------------------------------------
35 #include "event.h"
36 #include "win32_dragdrop.h"
37
38
39
40 //---------------------------------------------------------------------------
41 Win32DropObject::Win32DropObject() : IDropTarget()
42 {
43     References = 1;
44 }
45 //---------------------------------------------------------------------------
46 Win32DropObject::~Win32DropObject()
47 {
48 }
49 //---------------------------------------------------------------------------
50 void Win32DropObject::HandleDrop( HDROP HDrop )
51 {
52     // Get number of files that are dropped into vlc
53     int NbFiles = DragQueryFile( (HDROP)HDrop, 0xFFFFFFFF, NULL, 0 );
54
55     // For each dropped files
56     for( int i = 0; i < NbFiles; i++ )
57     {
58         // Get the name of the file
59         int NameLength = DragQueryFile( (HDROP)HDrop, i, NULL, 0 ) + 1;
60         char *FileName = new char[NameLength];
61         DragQueryFile( (HDROP)HDrop, i, FileName, NameLength );
62
63         // The pointer must not be deleted here because it will be deleted
64         // in the VLC specific messages processing function
65         PostMessage( NULL, VLC_DROP, (WPARAM)FileName, 0 );
66     }
67
68     DragFinish( (HDROP)HDrop );
69
70 }
71 //---------------------------------------------------------------------------
72 STDMETHODIMP Win32DropObject::QueryInterface( REFIID iid, void FAR* FAR* ppv )
73 {
74     // Tell other objects about our capabilities
75     if( iid == IID_IUnknown || iid == IID_IDropTarget )
76     {
77         *ppv = this;
78         AddRef();
79         return S_OK;
80     }
81     *ppv = NULL;
82     return ResultFromScode( E_NOINTERFACE );
83 }
84 //---------------------------------------------------------------------------
85 STDMETHODIMP_(ULONG) Win32DropObject::AddRef()
86 {
87     return ++References;
88 }
89 //---------------------------------------------------------------------------
90 STDMETHODIMP_(ULONG) Win32DropObject::Release()
91 {
92     if( --References == 0 )
93     {
94         delete this;
95         return 0;
96     }
97     return References;
98 }
99 //---------------------------------------------------------------------------
100 STDMETHODIMP Win32DropObject::DragEnter( LPDATAOBJECT pDataObj,
101     DWORD grfKeyState, POINTL pt, DWORD *pdwEffect )
102 {
103     FORMATETC fmtetc;
104
105     fmtetc.cfFormat = CF_HDROP;
106     fmtetc.ptd      = NULL;
107     fmtetc.dwAspect = DVASPECT_CONTENT;
108     fmtetc.lindex   = -1;
109     fmtetc.tymed    = TYMED_HGLOBAL;
110
111     // Check that the drag source provides CF_HDROP,
112     // which is the only format we accept
113     if( pDataObj->QueryGetData( &fmtetc ) == S_OK )
114         *pdwEffect = DROPEFFECT_COPY;
115     else
116         *pdwEffect = DROPEFFECT_NONE;
117
118     return S_OK;
119 }
120 //---------------------------------------------------------------------------
121 STDMETHODIMP Win32DropObject::DragOver( DWORD grfKeyState, POINTL pt,
122    DWORD *pdwEffect )
123 {
124     // For visual feedback
125     // TODO
126     return S_OK;
127 }
128 //---------------------------------------------------------------------------
129 STDMETHODIMP Win32DropObject::DragLeave()
130 {
131     // Remove visual feedback
132     // TODO
133     return S_OK;
134 }
135 //---------------------------------------------------------------------------
136 STDMETHODIMP Win32DropObject::Drop( LPDATAOBJECT pDataObj, DWORD grfKeyState,
137    POINTL pt, DWORD *pdwEffect )
138 {
139     // User has dropped on us -- get the CF_HDROP data from drag source
140     FORMATETC fmtetc;
141     fmtetc.cfFormat = CF_HDROP;
142     fmtetc.ptd      = NULL;
143     fmtetc.dwAspect = DVASPECT_CONTENT;
144     fmtetc.lindex   = -1;
145     fmtetc.tymed    = TYMED_HGLOBAL;
146
147     STGMEDIUM medium;
148     HRESULT hr = pDataObj->GetData( &fmtetc, &medium );
149
150     if( !FAILED(hr) )
151     {
152         // Grab a pointer to the data
153         HGLOBAL HFiles = medium.hGlobal;
154         HDROP HDrop = (HDROP)GlobalLock( HFiles );
155
156         // Notify the Form of the drop
157         HandleDrop( HDrop );
158
159         // Release the pointer to the memory
160         GlobalUnlock( HFiles );
161 //        ReleaseStgMedium( &medium );
162     }
163     else
164     {
165         *pdwEffect = DROPEFFECT_NONE;
166         return hr;
167     }
168     return S_OK;
169 }
170