2 * clipboard helper functions
4 * Copyright 2000 Juergen Schmied <juergen.schmied@debitel.de>
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.
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.
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
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
26 * - a right mousebutton-copy sets the following formats:
29 * Preferred Drop Effect
30 * Shell Object Offsets
34 * OlePrivateData (ClipboardDataObjectInterface)
38 #define WIN32_NO_STATUS
44 #include <wine/debug.h>
45 #include <wine/unicode.h>
47 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
49 /**************************************************************************
52 * creates a CF_HDROP structure
54 HGLOBAL
RenderHDROP(LPITEMIDLIST pidlRoot
, LPITEMIDLIST
* apidl
, UINT cidl
)
60 int rootlen
= 0,size
= 0;
61 WCHAR wszRootPath
[MAX_PATH
];
63 WCHAR wszFileName
[MAX_PATH
];
64 HGLOBAL hGlobal
= NULL
;
65 DROPFILES
*pDropFiles
;
71 TRACE("(%p,%p,%u)\n", pidlRoot
, apidl
, cidl
);
74 pidls
= (LPITEMIDLIST
*)HeapAlloc(GetProcessHeap(), 0, cidl
* sizeof(*pidls
));
79 /* get the size needed */
80 size
= sizeof(DROPFILES
);
83 SHGetPathFromIDListW(pidlRoot
, wszRootPath
);
84 PathAddBackslashW(wszRootPath
);
85 rootlen
= strlenW(wszRootPath
);
91 pidls
[i
] = ILCombine(pidlRoot
, apidl
[i
]);
92 SHGetPathFromIDListW(pidls
[i
], wszFileName
);
93 size
+= (wcslen(wszFileName
) + 1) * sizeof(WCHAR
);
95 _ILSimpleGetTextW(apidl
[i
], wszFileName
, MAX_PATH
);
96 size
+= (rootlen
+ strlenW(wszFileName
) + 1) * sizeof(WCHAR
);
100 size
+= sizeof(WCHAR
);
102 /* Fill the structure */
103 hGlobal
= GlobalAlloc(GHND
|GMEM_SHARE
, size
);
105 if(!hGlobal
) goto cleanup
;
107 if(!hGlobal
) return hGlobal
;
110 pDropFiles
= GlobalLock(hGlobal
);
111 offset
= (sizeof(DROPFILES
) + sizeof(WCHAR
) - 1) / sizeof(WCHAR
);
112 pDropFiles
->pFiles
= offset
* sizeof(WCHAR
);
113 pDropFiles
->fWide
= TRUE
;
116 strcpyW(wszFileName
, wszRootPath
);
119 for (i
=0; i
<cidl
;i
++)
123 SHGetPathFromIDListW(pidls
[i
], wszFileName
);
124 wcscpy(((WCHAR
*)pDropFiles
)+offset
, wszFileName
);
125 offset
+= wcslen(wszFileName
) + 1;
128 _ILSimpleGetTextW(apidl
[i
], wszFileName
+ rootlen
, MAX_PATH
- rootlen
);
129 strcpyW(((WCHAR
*)pDropFiles
)+offset
, wszFileName
);
130 offset
+= strlenW(wszFileName
) + 1;
134 ((WCHAR
*)pDropFiles
)[offset
] = 0;
135 GlobalUnlock(hGlobal
);
140 HeapFree(GetProcessHeap(), 0, pidls
);
146 HGLOBAL
RenderSHELLIDLIST (LPITEMIDLIST pidlRoot
, LPITEMIDLIST
* apidl
, UINT cidl
)
149 int offset
= 0, sizePidl
, size
;
153 TRACE("(%p,%p,%u)\n", pidlRoot
, apidl
, cidl
);
155 /* get the size needed */
156 size
= sizeof(CIDA
) + sizeof (UINT
)*(cidl
); /* header */
157 size
+= ILGetSize (pidlRoot
); /* root pidl */
158 for(i
=0; i
<cidl
; i
++)
160 size
+= ILGetSize(apidl
[i
]); /* child pidls */
163 /* fill the structure */
164 hGlobal
= GlobalAlloc(GHND
|GMEM_SHARE
, size
);
165 if(!hGlobal
) return hGlobal
;
166 pcida
= GlobalLock (hGlobal
);
170 offset
= sizeof(CIDA
) + sizeof (UINT
)*(cidl
);
171 pcida
->aoffset
[0] = offset
; /* first element */
172 sizePidl
= ILGetSize (pidlRoot
);
173 memcpy(((LPBYTE
)pcida
)+offset
, pidlRoot
, sizePidl
);
176 for(i
=0; i
<cidl
; i
++) /* child pidls */
178 pcida
->aoffset
[i
+1] = offset
;
179 sizePidl
= ILGetSize(apidl
[i
]);
180 memcpy(((LPBYTE
)pcida
)+offset
, apidl
[i
], sizePidl
);
184 GlobalUnlock(hGlobal
);
188 HGLOBAL
RenderFILENAMEA (LPITEMIDLIST pidlRoot
, LPITEMIDLIST
* apidl
, UINT cidl
)
191 char szTemp
[MAX_PATH
], *szFileName
;
196 TRACE("(%p,%p,%u)\n", pidlRoot
, apidl
, cidl
);
198 /* get path of combined pidl */
199 pidl
= ILCombine(pidlRoot
, apidl
[0]);
203 bSuccess
= SHGetPathFromIDListA(pidl
, szTemp
);
208 size
= strlen(szTemp
) + 1;
210 /* fill the structure */
211 hGlobal
= GlobalAlloc(GHND
|GMEM_SHARE
, size
);
212 if(!hGlobal
) return hGlobal
;
213 szFileName
= GlobalLock(hGlobal
);
214 memcpy(szFileName
, szTemp
, size
);
215 GlobalUnlock(hGlobal
);
220 HGLOBAL
RenderFILENAMEW (LPITEMIDLIST pidlRoot
, LPITEMIDLIST
* apidl
, UINT cidl
)
223 WCHAR szTemp
[MAX_PATH
], *szFileName
;
228 TRACE("(%p,%p,%u)\n", pidlRoot
, apidl
, cidl
);
230 /* get path of combined pidl */
231 pidl
= ILCombine(pidlRoot
, apidl
[0]);
235 bSuccess
= SHGetPathFromIDListW(pidl
, szTemp
);
240 size
= (strlenW(szTemp
)+1) * sizeof(WCHAR
);
242 /* fill the structure */
243 hGlobal
= GlobalAlloc(GHND
|GMEM_SHARE
, size
);
244 if(!hGlobal
) return hGlobal
;
245 szFileName
= GlobalLock(hGlobal
);
246 memcpy(szFileName
, szTemp
, size
);
247 GlobalUnlock(hGlobal
);