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