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