Added stub for ExtractAssociatedIconExA.
[wine] / dlls / shell32 / clipboard.c
1 /*
2  *      clipboard helper functions
3  *
4  *      Copyright 2000  Juergen Schmied <juergen.schmied@debitel.de>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * NOTES:
21  *
22  * For copy & paste functions within contextmenus does the shell use
23  * the OLE clipboard functions in combination with dataobjects.
24  * The OLE32.DLL gets loaded with LoadLibrary
25  *
26  * - a right mousebutton-copy sets the following formats:
27  *  classic:
28  *      Shell IDList Array
29  *      Prefered Drop Effect
30  *      Shell Object Offsets
31  *      HDROP
32  *      FileName
33  *  ole:
34  *      OlePrivateData (ClipboardDataObjectInterface)
35  *
36  */
37
38 #include <string.h>
39
40 #include "winreg.h"
41 #include "pidl.h"
42 #include "undocshell.h"
43 #include "shell32_main.h"
44 #include "shlwapi.h"
45
46 #include "wine/debug.h"
47
48 WINE_DEFAULT_DEBUG_CHANNEL(shell);
49
50 static int refClipCount = 0;
51 static HINSTANCE hShellOle32 = 0;
52
53 /**************************************************************************
54  * InitShellOle
55  *
56  * 
57  */
58 void InitShellOle(void)
59 {
60 }
61
62 /**************************************************************************
63  * FreeShellOle
64  *
65  * unload OLE32.DLL
66  */
67 void FreeShellOle(void)
68 {
69         if (!--refClipCount)
70         {
71           pOleUninitialize();
72           FreeLibrary(hShellOle32);
73         }
74 }
75
76 /**************************************************************************
77  * LoadShellOle
78  *
79  * make sure OLE32.DLL is loaded
80  */
81 BOOL GetShellOle(void)
82 {
83         if(!refClipCount)
84         {
85           hShellOle32 = LoadLibraryA("ole32.dll");
86           if(hShellOle32)
87           {
88             pOleInitialize=(void*)GetProcAddress(hShellOle32,"OleInitialize");
89             pOleUninitialize=(void*)GetProcAddress(hShellOle32,"OleUninitialize");
90             pRegisterDragDrop=(void*)GetProcAddress(hShellOle32,"RegisterDragDrop");
91             pRevokeDragDrop=(void*)GetProcAddress(hShellOle32,"RevokeDragDrop");
92             pDoDragDrop=(void*)GetProcAddress(hShellOle32,"DoDragDrop");
93             pReleaseStgMedium=(void*)GetProcAddress(hShellOle32,"ReleaseStgMedium");
94             pOleSetClipboard=(void*)GetProcAddress(hShellOle32,"OleSetClipboard");
95             pOleGetClipboard=(void*)GetProcAddress(hShellOle32,"OleGetClipboard");
96
97             pOleInitialize(NULL);
98             refClipCount++;
99           }
100         }
101         return TRUE;
102 }
103
104 /**************************************************************************
105  * RenderHDROP
106  *
107  * creates a CF_HDROP structure
108  */
109 HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
110 {
111         int i;
112         int rootsize = 0,size = 0;
113         char szRootPath[MAX_PATH];
114         char szFileName[MAX_PATH];
115         HGLOBAL hGlobal;
116         DROPFILES *pDropFiles;
117         int offset;
118         
119         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
120
121         /* get the size needed */
122         size = sizeof(DROPFILES);
123
124         SHGetPathFromIDListA(pidlRoot, szRootPath);
125         PathAddBackslashA(szRootPath);
126         rootsize = strlen(szRootPath);
127         
128         for (i=0; i<cidl;i++)
129         {
130           _ILSimpleGetText(apidl[i], szFileName, MAX_PATH);
131           size += rootsize + strlen(szFileName) + 1;
132         }
133
134         size++;
135
136         /* Fill the structure */
137         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
138         if(!hGlobal) return hGlobal;
139
140         pDropFiles = (DROPFILES *)GlobalLock(hGlobal);
141         pDropFiles->pFiles = sizeof(DROPFILES);
142         pDropFiles->fWide = FALSE;
143
144         offset = pDropFiles->pFiles;
145         strcpy(szFileName, szRootPath);
146         
147         for (i=0; i<cidl;i++)
148         {
149           
150           _ILSimpleGetText(apidl[i], szFileName + rootsize, MAX_PATH - rootsize);
151           size = strlen(szFileName) + 1;
152           strcpy(((char*)pDropFiles)+offset, szFileName);
153           offset += size;
154         }
155
156         ((char*)pDropFiles)[offset] = 0;
157         GlobalUnlock(hGlobal);
158
159         return hGlobal;
160 }
161
162 HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
163 {
164         int i,offset = 0, sizePidl, size;
165         HGLOBAL hGlobal;
166         LPCIDA  pcida;
167
168         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
169
170         /* get the size needed */
171         size = sizeof(CIDA) + sizeof (UINT)*(cidl);     /* header */
172         size += ILGetSize (pidlRoot);                   /* root pidl */
173         for(i=0; i<cidl; i++)
174         {
175           size += ILGetSize(apidl[i]);                  /* child pidls */
176         }
177
178         /* fill the structure */
179         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);           
180         if(!hGlobal) return hGlobal;
181         pcida = GlobalLock (hGlobal);
182         pcida->cidl = cidl;
183
184         /* root pidl */
185         offset = sizeof(CIDA) + sizeof (UINT)*(cidl);
186         pcida->aoffset[0] = offset;                     /* first element */
187         sizePidl = ILGetSize (pidlRoot);
188         memcpy(((LPBYTE)pcida)+offset, pidlRoot, sizePidl);
189         offset += sizePidl;
190
191         for(i=0; i<cidl; i++)                           /* child pidls */
192         {
193           pcida->aoffset[i+1] = offset;
194           sizePidl = ILGetSize(apidl[i]);
195           memcpy(((LPBYTE)pcida)+offset, apidl[i], sizePidl);
196           offset += sizePidl;
197         }
198
199         GlobalUnlock(hGlobal);
200         return hGlobal;
201 }
202
203 HGLOBAL RenderSHELLIDLISTOFFSET (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
204 {
205         FIXME("\n");
206         return 0;
207 }
208
209 HGLOBAL RenderFILECONTENTS (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
210 {
211         FIXME("\n");
212         return 0;
213 }
214
215 HGLOBAL RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
216 {
217         FIXME("\n");
218         return 0;
219 }
220
221 HGLOBAL RenderFILENAME (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
222 {
223         int len, size = 0;
224         char szTemp[MAX_PATH], *szFileName;
225         HGLOBAL hGlobal;
226         
227         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
228
229         /* build name of first file */
230         SHGetPathFromIDListA(pidlRoot, szTemp);
231         PathAddBackslashA(szTemp);
232         len = strlen(szTemp);
233         _ILSimpleGetText(apidl[0], szTemp+len, MAX_PATH - len);
234         size = strlen(szTemp) + 1;
235
236         /* fill the structure */
237         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
238         if(!hGlobal) return hGlobal;
239         szFileName = (char *)GlobalLock(hGlobal);
240         GlobalUnlock(hGlobal);
241         return hGlobal;
242 }
243
244 HGLOBAL RenderPREFEREDDROPEFFECT (DWORD dwFlags)
245 {
246         DWORD * pdwFlag;
247         HGLOBAL hGlobal;
248         
249         TRACE("(0x%08lx)\n", dwFlags);
250
251         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD));
252         if(!hGlobal) return hGlobal;
253         pdwFlag = (DWORD*)GlobalLock(hGlobal);
254         *pdwFlag = dwFlags;
255         GlobalUnlock(hGlobal);
256         return hGlobal;
257 }
258
259 /**************************************************************************
260  * IsDataInClipboard
261  *
262  * checks if there is something in the clipboard we can use
263  */
264 BOOL IsDataInClipboard (HWND hwnd)
265 {
266         BOOL ret = FALSE;
267         
268         if (OpenClipboard(hwnd))
269         {
270           if (GetOpenClipboardWindow())
271           {
272             ret = IsClipboardFormatAvailable(CF_TEXT);
273           }
274           CloseClipboard();
275         }
276         return ret;
277 }