1bdae63187887d942a9cac30e3ba5f486b454523
[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 rootlen = 0,size = 0;
51 WCHAR wszRootPath[MAX_PATH];
52 WCHAR wszFileName[MAX_PATH];
53 HGLOBAL hGlobal;
54 DROPFILES *pDropFiles;
55 int offset;
56
57 TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
58
59 /* get the size needed */
60 size = sizeof(DROPFILES);
61
62 SHGetPathFromIDListW(pidlRoot, wszRootPath);
63 PathAddBackslashW(wszRootPath);
64 rootlen = wcslen(wszRootPath);
65
66 for (i=0; i<cidl;i++)
67 {
68 _ILSimpleGetTextW(apidl[i], wszFileName, MAX_PATH);
69 size += (rootlen + 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 wcscpy(wszFileName, wszRootPath);
84
85 for (i=0; i<cidl;i++)
86 {
87
88 _ILSimpleGetTextW(apidl[i], wszFileName + rootlen, MAX_PATH - rootlen);
89 wcscpy(((WCHAR*)pDropFiles)+offset, wszFileName);
90 offset += wcslen(wszFileName) + 1;
91 }
92
93 ((WCHAR*)pDropFiles)[offset] = 0;
94 GlobalUnlock(hGlobal);
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 }