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