blob: 82df5341536562b2e155fae9bbb9a17c5fdaf7fe [file] [log] [blame]
Juergen Schmiede2b88042000-02-20 18:46:28 +00001/*
2 * clipboard helper functions
3 *
4 * Copyright 2000 Juergen Schmied <juergen.schmied@debitel.de>
5 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00006 * 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
Jonathan Ernst360a3f92006-05-18 14:49:52 +020018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000019 *
20 * NOTES:
21 *
Juergen Schmiede2b88042000-02-20 18:46:28 +000022 * 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
Francois Gougetfbb33432005-03-02 13:53:50 +000029 * Preferred Drop Effect
Juergen Schmiede2b88042000-02-20 18:46:28 +000030 * Shell Object Offsets
31 * HDROP
32 * FileName
33 * ole:
34 * OlePrivateData (ClipboardDataObjectInterface)
35 *
36 */
37
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000038#include <stdarg.h>
Juergen Schmiede2b88042000-02-20 18:46:28 +000039#include <string.h>
40
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000041#include "windef.h"
42#include "winbase.h"
Guy Albertelliaafec982001-11-06 22:31:19 +000043#include "winreg.h"
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000044#include "wingdi.h"
Guy Albertelliaafec982001-11-06 22:31:19 +000045#include "pidl.h"
Alexandre Julliard39541172001-08-16 18:49:56 +000046#include "undocshell.h"
Juergen Schmiede2b88042000-02-20 18:46:28 +000047#include "shell32_main.h"
Jon Griffiths603f20f2001-12-11 00:30:17 +000048#include "shlwapi.h"
Juergen Schmiede2b88042000-02-20 18:46:28 +000049
Martin Fuchs65b4d2d2003-07-26 20:32:43 +000050#include "wine/unicode.h"
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000051#include "wine/debug.h"
Guy Albertelliaafec982001-11-06 22:31:19 +000052
Alexandre Julliard0799c1a2002-03-09 23:29:33 +000053WINE_DEFAULT_DEBUG_CHANNEL(shell);
Juergen Schmiede2b88042000-02-20 18:46:28 +000054
Juergen Schmiede2b88042000-02-20 18:46:28 +000055/**************************************************************************
56 * RenderHDROP
57 *
58 * creates a CF_HDROP structure
59 */
60HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
61{
Rolf Kalbermattera9644712002-12-13 00:36:52 +000062 UINT i;
Ken Thomases8f5f3f52007-03-14 13:17:29 -050063 int rootlen = 0,size = 0;
64 WCHAR wszRootPath[MAX_PATH];
65 WCHAR wszFileName[MAX_PATH];
Juergen Schmiede2b88042000-02-20 18:46:28 +000066 HGLOBAL hGlobal;
Alexandre Julliard60e17522000-09-25 23:56:41 +000067 DROPFILES *pDropFiles;
Juergen Schmiede2b88042000-02-20 18:46:28 +000068 int offset;
Vincent Béron9a624912002-05-31 23:06:46 +000069
Juergen Schmiede2b88042000-02-20 18:46:28 +000070 TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
71
72 /* get the size needed */
Alexandre Julliard60e17522000-09-25 23:56:41 +000073 size = sizeof(DROPFILES);
Juergen Schmiede2b88042000-02-20 18:46:28 +000074
Ken Thomases8f5f3f52007-03-14 13:17:29 -050075 SHGetPathFromIDListW(pidlRoot, wszRootPath);
76 PathAddBackslashW(wszRootPath);
77 rootlen = strlenW(wszRootPath);
Vincent Béron9a624912002-05-31 23:06:46 +000078
Juergen Schmiede2b88042000-02-20 18:46:28 +000079 for (i=0; i<cidl;i++)
80 {
Ken Thomases8f5f3f52007-03-14 13:17:29 -050081 _ILSimpleGetTextW(apidl[i], wszFileName, MAX_PATH);
82 size += (rootlen + strlenW(wszFileName) + 1) * sizeof(WCHAR);
Juergen Schmiede2b88042000-02-20 18:46:28 +000083 }
84
Ken Thomases8f5f3f52007-03-14 13:17:29 -050085 size += sizeof(WCHAR);
Juergen Schmiede2b88042000-02-20 18:46:28 +000086
87 /* Fill the structure */
88 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
89 if(!hGlobal) return hGlobal;
90
Michael Stefaniucb7de2662008-11-05 23:00:50 +010091 pDropFiles = GlobalLock(hGlobal);
Ken Thomases8f5f3f52007-03-14 13:17:29 -050092 offset = (sizeof(DROPFILES) + sizeof(WCHAR) - 1) / sizeof(WCHAR);
93 pDropFiles->pFiles = offset * sizeof(WCHAR);
94 pDropFiles->fWide = TRUE;
Juergen Schmiede2b88042000-02-20 18:46:28 +000095
Ken Thomases8f5f3f52007-03-14 13:17:29 -050096 strcpyW(wszFileName, wszRootPath);
Vincent Béron9a624912002-05-31 23:06:46 +000097
Juergen Schmiede2b88042000-02-20 18:46:28 +000098 for (i=0; i<cidl;i++)
99 {
Vincent Béron9a624912002-05-31 23:06:46 +0000100
Ken Thomases8f5f3f52007-03-14 13:17:29 -0500101 _ILSimpleGetTextW(apidl[i], wszFileName + rootlen, MAX_PATH - rootlen);
102 strcpyW(((WCHAR*)pDropFiles)+offset, wszFileName);
103 offset += strlenW(wszFileName) + 1;
Juergen Schmiede2b88042000-02-20 18:46:28 +0000104 }
105
Ken Thomases8f5f3f52007-03-14 13:17:29 -0500106 ((WCHAR*)pDropFiles)[offset] = 0;
Juergen Schmiede2b88042000-02-20 18:46:28 +0000107 GlobalUnlock(hGlobal);
108
109 return hGlobal;
110}
111
112HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
113{
Rolf Kalbermattera9644712002-12-13 00:36:52 +0000114 UINT i;
115 int offset = 0, sizePidl, size;
Juergen Schmiede2b88042000-02-20 18:46:28 +0000116 HGLOBAL hGlobal;
Patrik Stridvallced69a92002-11-12 01:05:00 +0000117 LPIDA pcida;
Juergen Schmiede2b88042000-02-20 18:46:28 +0000118
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 */
Vincent Béron9a624912002-05-31 23:06:46 +0000130 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
Juergen Schmiede2b88042000-02-20 18:46:28 +0000131 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
Martin Fuchs65b4d2d2003-07-26 20:32:43 +0000154HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
Juergen Schmiede2b88042000-02-20 18:46:28 +0000155{
Martin Fuchs9d78f672004-01-21 23:50:46 +0000156 int size = 0;
Juergen Schmiede2b88042000-02-20 18:46:28 +0000157 char szTemp[MAX_PATH], *szFileName;
Martin Fuchs9d78f672004-01-21 23:50:46 +0000158 LPITEMIDLIST pidl;
Juergen Schmiede2b88042000-02-20 18:46:28 +0000159 HGLOBAL hGlobal;
Michael Jung81b75092005-06-14 19:17:41 +0000160 BOOL bSuccess;
Vincent Béron9a624912002-05-31 23:06:46 +0000161
Juergen Schmiede2b88042000-02-20 18:46:28 +0000162 TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
163
Martin Fuchs9d78f672004-01-21 23:50:46 +0000164 /* get path of combined pidl */
165 pidl = ILCombine(pidlRoot, apidl[0]);
166 if (!pidl)
167 return 0;
168
Michael Jung81b75092005-06-14 19:17:41 +0000169 bSuccess = SHGetPathFromIDListA(pidl, szTemp);
Martin Fuchs9d78f672004-01-21 23:50:46 +0000170 SHFree(pidl);
Michael Jung81b75092005-06-14 19:17:41 +0000171 if (!bSuccess)
Martin Fuchs9d78f672004-01-21 23:50:46 +0000172 return 0;
173
Juergen Schmiede2b88042000-02-20 18:46:28 +0000174 size = strlen(szTemp) + 1;
175
176 /* fill the structure */
177 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
178 if(!hGlobal) return hGlobal;
Michael Stefaniucb7de2662008-11-05 23:00:50 +0100179 szFileName = GlobalLock(hGlobal);
Martin Fuchs65b4d2d2003-07-26 20:32:43 +0000180 memcpy(szFileName, szTemp, size);
181 GlobalUnlock(hGlobal);
Martin Fuchs9d78f672004-01-21 23:50:46 +0000182
Martin Fuchs65b4d2d2003-07-26 20:32:43 +0000183 return hGlobal;
184}
185
186HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
187{
Martin Fuchs9d78f672004-01-21 23:50:46 +0000188 int size = 0;
Martin Fuchs65b4d2d2003-07-26 20:32:43 +0000189 WCHAR szTemp[MAX_PATH], *szFileName;
Martin Fuchs9d78f672004-01-21 23:50:46 +0000190 LPITEMIDLIST pidl;
Martin Fuchs65b4d2d2003-07-26 20:32:43 +0000191 HGLOBAL hGlobal;
Michael Jung81b75092005-06-14 19:17:41 +0000192 BOOL bSuccess;
Martin Fuchs65b4d2d2003-07-26 20:32:43 +0000193
194 TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
195
Martin Fuchs9d78f672004-01-21 23:50:46 +0000196 /* get path of combined pidl */
197 pidl = ILCombine(pidlRoot, apidl[0]);
198 if (!pidl)
199 return 0;
200
Michael Jung81b75092005-06-14 19:17:41 +0000201 bSuccess = SHGetPathFromIDListW(pidl, szTemp);
Martin Fuchs9d78f672004-01-21 23:50:46 +0000202 SHFree(pidl);
Michael Jung81b75092005-06-14 19:17:41 +0000203 if (!bSuccess)
Martin Fuchs9d78f672004-01-21 23:50:46 +0000204 return 0;
205
206 size = (strlenW(szTemp)+1) * sizeof(WCHAR);
Martin Fuchs65b4d2d2003-07-26 20:32:43 +0000207
208 /* fill the structure */
209 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
210 if(!hGlobal) return hGlobal;
Michael Stefaniucb7de2662008-11-05 23:00:50 +0100211 szFileName = GlobalLock(hGlobal);
Martin Fuchs65b4d2d2003-07-26 20:32:43 +0000212 memcpy(szFileName, szTemp, size);
Juergen Schmiede2b88042000-02-20 18:46:28 +0000213 GlobalUnlock(hGlobal);
Martin Fuchs9d78f672004-01-21 23:50:46 +0000214
Juergen Schmiede2b88042000-02-20 18:46:28 +0000215 return hGlobal;
216}