shell32: Add a test for ABM_GETTASKBARPOS.
[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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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  *      Preferred Drop Effect
30  *      Shell Object Offsets
31  *      HDROP
32  *      FileName
33  *  ole:
34  *      OlePrivateData (ClipboardDataObjectInterface)
35  *
36  */
37
38 #include <stdarg.h>
39 #include <string.h>
40
41 #include "windef.h"
42 #include "winbase.h"
43 #include "winreg.h"
44 #include "wingdi.h"
45 #include "pidl.h"
46 #include "undocshell.h"
47 #include "shell32_main.h"
48 #include "shlwapi.h"
49
50 #include "wine/unicode.h"
51 #include "wine/debug.h"
52
53 WINE_DEFAULT_DEBUG_CHANNEL(shell);
54
55 /**************************************************************************
56  * RenderHDROP
57  *
58  * creates a CF_HDROP structure
59  */
60 HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
61 {
62         UINT i;
63         int rootlen = 0,size = 0;
64         WCHAR wszRootPath[MAX_PATH];
65         WCHAR wszFileName[MAX_PATH];
66         HGLOBAL hGlobal;
67         DROPFILES *pDropFiles;
68         int offset;
69
70         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
71
72         /* get the size needed */
73         size = sizeof(DROPFILES);
74
75         SHGetPathFromIDListW(pidlRoot, wszRootPath);
76         PathAddBackslashW(wszRootPath);
77         rootlen = strlenW(wszRootPath);
78
79         for (i=0; i<cidl;i++)
80         {
81           _ILSimpleGetTextW(apidl[i], wszFileName, MAX_PATH);
82           size += (rootlen + strlenW(wszFileName) + 1) * sizeof(WCHAR);
83         }
84
85         size += sizeof(WCHAR);
86
87         /* Fill the structure */
88         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
89         if(!hGlobal) return hGlobal;
90
91         pDropFiles = (DROPFILES *)GlobalLock(hGlobal);
92         offset = (sizeof(DROPFILES) + sizeof(WCHAR) - 1) / sizeof(WCHAR);
93         pDropFiles->pFiles = offset * sizeof(WCHAR);
94         pDropFiles->fWide = TRUE;
95
96         strcpyW(wszFileName, wszRootPath);
97
98         for (i=0; i<cidl;i++)
99         {
100
101           _ILSimpleGetTextW(apidl[i], wszFileName + rootlen, MAX_PATH - rootlen);
102           strcpyW(((WCHAR*)pDropFiles)+offset, wszFileName);
103           offset += strlenW(wszFileName) + 1;
104         }
105
106         ((WCHAR*)pDropFiles)[offset] = 0;
107         GlobalUnlock(hGlobal);
108
109         return hGlobal;
110 }
111
112 HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
113 {
114         UINT i;
115         int offset = 0, sizePidl, size;
116         HGLOBAL hGlobal;
117         LPIDA   pcida;
118
119         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
120
121         /* get the size needed */
122         size = sizeof(CIDA) + sizeof (UINT)*(cidl);     /* header */
123         size += ILGetSize (pidlRoot);                   /* root pidl */
124         for(i=0; i<cidl; i++)
125         {
126           size += ILGetSize(apidl[i]);                  /* child pidls */
127         }
128
129         /* fill the structure */
130         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
131         if(!hGlobal) return hGlobal;
132         pcida = GlobalLock (hGlobal);
133         pcida->cidl = cidl;
134
135         /* root pidl */
136         offset = sizeof(CIDA) + sizeof (UINT)*(cidl);
137         pcida->aoffset[0] = offset;                     /* first element */
138         sizePidl = ILGetSize (pidlRoot);
139         memcpy(((LPBYTE)pcida)+offset, pidlRoot, sizePidl);
140         offset += sizePidl;
141
142         for(i=0; i<cidl; i++)                           /* child pidls */
143         {
144           pcida->aoffset[i+1] = offset;
145           sizePidl = ILGetSize(apidl[i]);
146           memcpy(((LPBYTE)pcida)+offset, apidl[i], sizePidl);
147           offset += sizePidl;
148         }
149
150         GlobalUnlock(hGlobal);
151         return hGlobal;
152 }
153
154 HGLOBAL RenderSHELLIDLISTOFFSET (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
155 {
156         FIXME("\n");
157         return 0;
158 }
159
160 HGLOBAL RenderFILECONTENTS (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
161 {
162         FIXME("\n");
163         return 0;
164 }
165
166 HGLOBAL RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
167 {
168         FIXME("\n");
169         return 0;
170 }
171
172 HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
173 {
174         int size = 0;
175         char szTemp[MAX_PATH], *szFileName;
176         LPITEMIDLIST pidl;
177         HGLOBAL hGlobal;
178         BOOL bSuccess;
179
180         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
181
182         /* get path of combined pidl */
183         pidl = ILCombine(pidlRoot, apidl[0]);
184         if (!pidl)
185                 return 0;
186
187         bSuccess = SHGetPathFromIDListA(pidl, szTemp);
188         SHFree(pidl);
189         if (!bSuccess)
190                 return 0;
191
192         size = strlen(szTemp) + 1;
193
194         /* fill the structure */
195         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
196         if(!hGlobal) return hGlobal;
197         szFileName = (char *)GlobalLock(hGlobal);
198         memcpy(szFileName, szTemp, size);
199         GlobalUnlock(hGlobal);
200
201         return hGlobal;
202 }
203
204 HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
205 {
206         int size = 0;
207         WCHAR szTemp[MAX_PATH], *szFileName;
208         LPITEMIDLIST pidl;
209         HGLOBAL hGlobal;
210         BOOL bSuccess;
211
212         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
213
214         /* get path of combined pidl */
215         pidl = ILCombine(pidlRoot, apidl[0]);
216         if (!pidl)
217                 return 0;
218
219         bSuccess = SHGetPathFromIDListW(pidl, szTemp);
220         SHFree(pidl);
221         if (!bSuccess)
222                 return 0;
223
224         size = (strlenW(szTemp)+1) * sizeof(WCHAR);
225
226         /* fill the structure */
227         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
228         if(!hGlobal) return hGlobal;
229         szFileName = (WCHAR *)GlobalLock(hGlobal);
230         memcpy(szFileName, szTemp, size);
231         GlobalUnlock(hGlobal);
232
233         return hGlobal;
234 }
235
236 HGLOBAL RenderPREFEREDDROPEFFECT (DWORD dwFlags)
237 {
238         DWORD * pdwFlag;
239         HGLOBAL hGlobal;
240
241         TRACE("(0x%08x)\n", dwFlags);
242
243         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD));
244         if(!hGlobal) return hGlobal;
245         pdwFlag = (DWORD*)GlobalLock(hGlobal);
246         *pdwFlag = dwFlags;
247         GlobalUnlock(hGlobal);
248         return hGlobal;
249 }