]> git.sesse.net Git - vlc/blob - modules/gui/skins2/win32/win32_dragdrop.cpp
video_output/opengl.c:
[vlc] / modules / gui / skins2 / win32 / win32_dragdrop.cpp
1 /*****************************************************************************
2  * win32_dragdrop.cpp
3  *****************************************************************************
4  * Copyright (C) 2003 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
8  *          Olivier Teulière <ipkiss@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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 #ifdef WIN32_SKINS
26
27 #include <windows.h>
28 #include "win32_dragdrop.hpp"
29 #include "../commands/cmd_add_item.hpp"
30
31
32 Win32DragDrop::Win32DragDrop( intf_thread_t *pIntf, bool playOnDrop ):
33     SkinObject( pIntf ), IDropTarget(), m_references( 1 ),
34     m_playOnDrop( playOnDrop )
35 {
36 }
37
38
39 STDMETHODIMP Win32DragDrop::QueryInterface( REFIID iid, void FAR* FAR* ppv )
40 {
41     // Tell other objects about our capabilities
42     if( iid == IID_IUnknown || iid == IID_IDropTarget )
43     {
44         *ppv = this;
45         AddRef();
46         return S_OK;
47     }
48     *ppv = NULL;
49     return ResultFromScode( E_NOINTERFACE );
50 }
51
52
53 STDMETHODIMP_(ULONG) Win32DragDrop::AddRef()
54 {
55     return ++m_references;
56 }
57
58
59 STDMETHODIMP_(ULONG) Win32DragDrop::Release()
60 {
61     if( --m_references == 0 )
62     {
63         delete this;
64         return 0;
65     }
66     return m_references;
67 }
68
69
70 STDMETHODIMP Win32DragDrop::DragEnter( LPDATAOBJECT pDataObj,
71     DWORD grfKeyState, POINTL pt, DWORD *pdwEffect )
72 {
73     FORMATETC fmtetc;
74
75     fmtetc.cfFormat = CF_HDROP;
76     fmtetc.ptd      = NULL;
77     fmtetc.dwAspect = DVASPECT_CONTENT;
78     fmtetc.lindex   = -1;
79     fmtetc.tymed    = TYMED_HGLOBAL;
80
81     // Check that the drag source provides CF_HDROP,
82     // which is the only format we accept
83     if( pDataObj->QueryGetData( &fmtetc ) == S_OK )
84     {
85         *pdwEffect = DROPEFFECT_COPY;
86     }
87     else
88     {
89         *pdwEffect = DROPEFFECT_NONE;
90     }
91
92     return S_OK;
93 }
94
95
96 STDMETHODIMP Win32DragDrop::DragOver( DWORD grfKeyState, POINTL pt,
97                                       DWORD *pdwEffect )
98 {
99     // For visual feedback
100     return S_OK;
101 }
102
103
104 STDMETHODIMP Win32DragDrop::DragLeave()
105 {
106     // Remove visual feedback
107     return S_OK;
108 }
109
110
111 STDMETHODIMP Win32DragDrop::Drop( LPDATAOBJECT pDataObj, DWORD grfKeyState,
112     POINTL pt, DWORD *pdwEffect )
113 {
114     // User has dropped on us -- get the CF_HDROP data from drag source
115     FORMATETC fmtetc;
116     fmtetc.cfFormat = CF_HDROP;
117     fmtetc.ptd      = NULL;
118     fmtetc.dwAspect = DVASPECT_CONTENT;
119     fmtetc.lindex   = -1;
120     fmtetc.tymed    = TYMED_HGLOBAL;
121
122     STGMEDIUM medium;
123     HRESULT hr = pDataObj->GetData( &fmtetc, &medium );
124
125     if( !FAILED(hr) )
126     {
127         // Grab a pointer to the data
128         HGLOBAL HFiles = medium.hGlobal;
129         HDROP HDrop = (HDROP)GlobalLock( HFiles );
130
131         // Notify VLC of the drop
132         HandleDrop( HDrop );
133
134         // Release the pointer to the memory
135         GlobalUnlock( HFiles );
136 //        ReleaseStgMedium( &medium );
137     }
138     else
139     {
140         *pdwEffect = DROPEFFECT_NONE;
141         return hr;
142     }
143     return S_OK;
144 }
145
146
147 void Win32DragDrop::HandleDrop( HDROP HDrop )
148 {
149     if( GetVersion() < 0x80000000 )
150     {
151         // Use Unicode for Windows NT and above
152
153         // Get the number of dropped files
154         int nbFiles = DragQueryFileW( HDrop, 0xFFFFFFFF, NULL, 0 );
155
156         // For each dropped file
157         for( int i = 0; i < nbFiles; i++ )
158         {
159             // Get the name of the file
160             int nameLength = DragQueryFileW( HDrop, i, NULL, 0 ) + 1;
161             wchar_t *psz_fileName = new WCHAR[nameLength];
162             DragQueryFileW( HDrop, i, psz_fileName, nameLength );
163
164             // Add the file
165             CmdAddItem cmd(getIntf(),sFromWide(psz_fileName),m_playOnDrop);
166             cmd.execute();
167
168             delete[] psz_fileName;
169         }
170     }
171     else
172     {
173         int nbFiles = DragQueryFile( HDrop, 0xFFFFFFFF, NULL, 0 );
174
175         for( int i = 0; i < nbFiles; i++ )
176         {
177             int nameLength = DragQueryFile( HDrop, i, NULL, 0 ) + 1;
178             char *psz_fileName = new char[nameLength];
179             DragQueryFile( HDrop, i, psz_fileName, nameLength );
180
181             CmdAddItem cmd(getIntf(),sFromLocale(psz_fileName),m_playOnDrop);
182             cmd.execute();
183
184             delete[] psz_fileName;
185         }
186     }
187
188     DragFinish( HDrop );
189 }
190
191
192 #endif