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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 * Prefered Drop Effect
30 * Shell Object Offsets
34 * OlePrivateData (ClipboardDataObjectInterface)
42 #include "undocshell.h"
43 #include "shell32_main.h"
46 #include "wine/unicode.h"
47 #include "wine/debug.h"
49 WINE_DEFAULT_DEBUG_CHANNEL(shell);
51 HRESULT (WINAPI *pOleInitialize)(LPVOID reserved);
52 void (WINAPI *pOleUninitialize)(void);
53 HRESULT (WINAPI *pRegisterDragDrop)(HWND hwnd, IDropTarget* pDropTarget);
54 HRESULT (WINAPI *pRevokeDragDrop)(HWND hwnd);
55 HRESULT (WINAPI *pDoDragDrop)(LPDATAOBJECT,LPDROPSOURCE,DWORD,DWORD*);
56 void (WINAPI *pReleaseStgMedium)(STGMEDIUM* pmedium);
57 HRESULT (WINAPI *pOleSetClipboard)(IDataObject* pDataObj);
58 HRESULT (WINAPI *pOleGetClipboard)(IDataObject** ppDataObj);
60 /**************************************************************************
63 * make sure OLE32.DLL is loaded
65 BOOL GetShellOle(void)
67 static HANDLE hOle32 = NULL;
70 hOle32 = LoadLibraryA("ole32.dll");
73 pOleInitialize=(void*)GetProcAddress(hOle32,"OleInitialize");
74 pOleUninitialize=(void*)GetProcAddress(hOle32,"OleUninitialize");
75 pRegisterDragDrop=(void*)GetProcAddress(hOle32,"RegisterDragDrop");
76 pRevokeDragDrop=(void*)GetProcAddress(hOle32,"RevokeDragDrop");
77 pDoDragDrop=(void*)GetProcAddress(hOle32,"DoDragDrop");
78 pReleaseStgMedium=(void*)GetProcAddress(hOle32,"ReleaseStgMedium");
79 pOleSetClipboard=(void*)GetProcAddress(hOle32,"OleSetClipboard");
80 pOleGetClipboard=(void*)GetProcAddress(hOle32,"OleGetClipboard");
88 /**************************************************************************
91 * creates a CF_HDROP structure
93 HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
96 int rootsize = 0,size = 0;
97 char szRootPath[MAX_PATH];
98 char szFileName[MAX_PATH];
100 DROPFILES *pDropFiles;
103 TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
105 /* get the size needed */
106 size = sizeof(DROPFILES);
108 SHGetPathFromIDListA(pidlRoot, szRootPath);
109 PathAddBackslashA(szRootPath);
110 rootsize = strlen(szRootPath);
112 for (i=0; i<cidl;i++)
114 _ILSimpleGetText(apidl[i], szFileName, MAX_PATH);
115 size += rootsize + strlen(szFileName) + 1;
120 /* Fill the structure */
121 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
122 if(!hGlobal) return hGlobal;
124 pDropFiles = (DROPFILES *)GlobalLock(hGlobal);
125 pDropFiles->pFiles = sizeof(DROPFILES);
126 pDropFiles->fWide = FALSE;
128 offset = pDropFiles->pFiles;
129 strcpy(szFileName, szRootPath);
131 for (i=0; i<cidl;i++)
134 _ILSimpleGetText(apidl[i], szFileName + rootsize, MAX_PATH - rootsize);
135 size = strlen(szFileName) + 1;
136 strcpy(((char*)pDropFiles)+offset, szFileName);
140 ((char*)pDropFiles)[offset] = 0;
141 GlobalUnlock(hGlobal);
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 RenderSHELLIDLISTOFFSET (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
194 HGLOBAL RenderFILECONTENTS (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
200 HGLOBAL RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
206 HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
209 char szTemp[MAX_PATH], *szFileName;
212 TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
214 /* build name of first file */
215 SHGetPathFromIDListA(pidlRoot, szTemp);
216 PathAddBackslashA(szTemp);
217 len = strlen(szTemp);
218 _ILSimpleGetText(apidl[0], szTemp+len, MAX_PATH - len);
219 size = strlen(szTemp) + 1;
221 /* fill the structure */
222 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
223 if(!hGlobal) return hGlobal;
224 szFileName = (char *)GlobalLock(hGlobal);
225 memcpy(szFileName, szTemp, size);
226 GlobalUnlock(hGlobal);
230 HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
233 WCHAR szTemp[MAX_PATH], *szFileName;
236 TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
238 /* build name of first file */
239 SHGetPathFromIDListW(pidlRoot, szTemp);
240 PathAddBackslashW(szTemp);
241 len = strlenW(szTemp);
242 _ILSimpleGetTextW(apidl[0], szTemp+len, MAX_PATH - len);
243 size = sizeof(WCHAR) * (strlenW(szTemp)+1);
245 /* fill the structure */
246 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
247 if(!hGlobal) return hGlobal;
248 szFileName = (WCHAR *)GlobalLock(hGlobal);
249 memcpy(szFileName, szTemp, size);
250 GlobalUnlock(hGlobal);
254 HGLOBAL RenderPREFEREDDROPEFFECT (DWORD dwFlags)
259 TRACE("(0x%08lx)\n", dwFlags);
261 hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD));
262 if(!hGlobal) return hGlobal;
263 pdwFlag = (DWORD*)GlobalLock(hGlobal);
265 GlobalUnlock(hGlobal);
269 /**************************************************************************
272 * checks if there is something in the clipboard we can use
274 BOOL IsDataInClipboard (HWND hwnd)
278 if (OpenClipboard(hwnd))
280 if (GetOpenClipboardWindow())
282 ret = IsClipboardFormatAvailable(CF_TEXT);