shell32: Use the plural for 'My Videos' wherever appropriate.
[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 = 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 RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
155 {
156         int size = 0;
157         char szTemp[MAX_PATH], *szFileName;
158         LPITEMIDLIST pidl;
159         HGLOBAL hGlobal;
160         BOOL bSuccess;
161
162         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
163
164         /* get path of combined pidl */
165         pidl = ILCombine(pidlRoot, apidl[0]);
166         if (!pidl)
167                 return 0;
168
169         bSuccess = SHGetPathFromIDListA(pidl, szTemp);
170         SHFree(pidl);
171         if (!bSuccess)
172                 return 0;
173
174         size = strlen(szTemp) + 1;
175
176         /* fill the structure */
177         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
178         if(!hGlobal) return hGlobal;
179         szFileName = GlobalLock(hGlobal);
180         memcpy(szFileName, szTemp, size);
181         GlobalUnlock(hGlobal);
182
183         return hGlobal;
184 }
185
186 HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
187 {
188         int size = 0;
189         WCHAR szTemp[MAX_PATH], *szFileName;
190         LPITEMIDLIST pidl;
191         HGLOBAL hGlobal;
192         BOOL bSuccess;
193
194         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
195
196         /* get path of combined pidl */
197         pidl = ILCombine(pidlRoot, apidl[0]);
198         if (!pidl)
199                 return 0;
200
201         bSuccess = SHGetPathFromIDListW(pidl, szTemp);
202         SHFree(pidl);
203         if (!bSuccess)
204                 return 0;
205
206         size = (strlenW(szTemp)+1) * sizeof(WCHAR);
207
208         /* fill the structure */
209         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
210         if(!hGlobal) return hGlobal;
211         szFileName = GlobalLock(hGlobal);
212         memcpy(szFileName, szTemp, size);
213         GlobalUnlock(hGlobal);
214
215         return hGlobal;
216 }