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)
46 #include "undocshell.h"
47 #include "shell32_main.h"
50 #include "wine/unicode.h"
51 #include "wine/debug.h"
53 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
55 HRESULT (WINAPI
*pOleInitialize
)(LPVOID reserved
);
56 void (WINAPI
*pOleUninitialize
)(void);
57 HRESULT (WINAPI
*pRegisterDragDrop
)(HWND hwnd
, IDropTarget
* pDropTarget
);
58 HRESULT (WINAPI
*pRevokeDragDrop
)(HWND hwnd
);
59 HRESULT (WINAPI
*pDoDragDrop
)(LPDATAOBJECT
,LPDROPSOURCE
,DWORD
,DWORD
*);
60 void (WINAPI
*pReleaseStgMedium
)(STGMEDIUM
* pmedium
);
61 HRESULT (WINAPI
*pOleSetClipboard
)(IDataObject
* pDataObj
);
62 HRESULT (WINAPI
*pOleGetClipboard
)(IDataObject
** ppDataObj
);
64 /**************************************************************************
67 * make sure OLE32.DLL is loaded
69 BOOL
GetShellOle(void)
71 static HANDLE hOle32
= NULL
;
74 hOle32
= LoadLibraryA("ole32.dll");
77 pOleInitialize
=(void*)GetProcAddress(hOle32
,"OleInitialize");
78 pOleUninitialize
=(void*)GetProcAddress(hOle32
,"OleUninitialize");
79 pRegisterDragDrop
=(void*)GetProcAddress(hOle32
,"RegisterDragDrop");
80 pRevokeDragDrop
=(void*)GetProcAddress(hOle32
,"RevokeDragDrop");
81 pDoDragDrop
=(void*)GetProcAddress(hOle32
,"DoDragDrop");
82 pReleaseStgMedium
=(void*)GetProcAddress(hOle32
,"ReleaseStgMedium");
83 pOleSetClipboard
=(void*)GetProcAddress(hOle32
,"OleSetClipboard");
84 pOleGetClipboard
=(void*)GetProcAddress(hOle32
,"OleGetClipboard");
92 /**************************************************************************
95 * creates a CF_HDROP structure
97 HGLOBAL
RenderHDROP(LPITEMIDLIST pidlRoot
, LPITEMIDLIST
* apidl
, UINT cidl
)
100 int rootsize
= 0,size
= 0;
101 char szRootPath
[MAX_PATH
];
102 char szFileName
[MAX_PATH
];
104 DROPFILES
*pDropFiles
;
107 TRACE("(%p,%p,%u)\n", pidlRoot
, apidl
, cidl
);
109 /* get the size needed */
110 size
= sizeof(DROPFILES
);
112 SHGetPathFromIDListA(pidlRoot
, szRootPath
);
113 PathAddBackslashA(szRootPath
);
114 rootsize
= strlen(szRootPath
);
116 for (i
=0; i
<cidl
;i
++)
118 _ILSimpleGetText(apidl
[i
], szFileName
, MAX_PATH
);
119 size
+= rootsize
+ strlen(szFileName
) + 1;
124 /* Fill the structure */
125 hGlobal
= GlobalAlloc(GHND
|GMEM_SHARE
, size
);
126 if(!hGlobal
) return hGlobal
;
128 pDropFiles
= (DROPFILES
*)GlobalLock(hGlobal
);
129 pDropFiles
->pFiles
= sizeof(DROPFILES
);
130 pDropFiles
->fWide
= FALSE
;
132 offset
= pDropFiles
->pFiles
;
133 strcpy(szFileName
, szRootPath
);
135 for (i
=0; i
<cidl
;i
++)
138 _ILSimpleGetText(apidl
[i
], szFileName
+ rootsize
, MAX_PATH
- rootsize
);
139 size
= strlen(szFileName
) + 1;
140 strcpy(((char*)pDropFiles
)+offset
, szFileName
);
144 ((char*)pDropFiles
)[offset
] = 0;
145 GlobalUnlock(hGlobal
);
150 HGLOBAL
RenderSHELLIDLIST (LPITEMIDLIST pidlRoot
, LPITEMIDLIST
* apidl
, UINT cidl
)
153 int offset
= 0, sizePidl
, size
;
157 TRACE("(%p,%p,%u)\n", pidlRoot
, apidl
, cidl
);
159 /* get the size needed */
160 size
= sizeof(CIDA
) + sizeof (UINT
)*(cidl
); /* header */
161 size
+= ILGetSize (pidlRoot
); /* root pidl */
162 for(i
=0; i
<cidl
; i
++)
164 size
+= ILGetSize(apidl
[i
]); /* child pidls */
167 /* fill the structure */
168 hGlobal
= GlobalAlloc(GHND
|GMEM_SHARE
, size
);
169 if(!hGlobal
) return hGlobal
;
170 pcida
= GlobalLock (hGlobal
);
174 offset
= sizeof(CIDA
) + sizeof (UINT
)*(cidl
);
175 pcida
->aoffset
[0] = offset
; /* first element */
176 sizePidl
= ILGetSize (pidlRoot
);
177 memcpy(((LPBYTE
)pcida
)+offset
, pidlRoot
, sizePidl
);
180 for(i
=0; i
<cidl
; i
++) /* child pidls */
182 pcida
->aoffset
[i
+1] = offset
;
183 sizePidl
= ILGetSize(apidl
[i
]);
184 memcpy(((LPBYTE
)pcida
)+offset
, apidl
[i
], sizePidl
);
188 GlobalUnlock(hGlobal
);
192 HGLOBAL
RenderSHELLIDLISTOFFSET (LPITEMIDLIST pidlRoot
, LPITEMIDLIST
* apidl
, UINT cidl
)
198 HGLOBAL
RenderFILECONTENTS (LPITEMIDLIST pidlRoot
, LPITEMIDLIST
* apidl
, UINT cidl
)
204 HGLOBAL
RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot
, LPITEMIDLIST
* apidl
, UINT cidl
)
210 HGLOBAL
RenderFILENAMEA (LPITEMIDLIST pidlRoot
, LPITEMIDLIST
* apidl
, UINT cidl
)
213 char szTemp
[MAX_PATH
], *szFileName
;
216 TRACE("(%p,%p,%u)\n", pidlRoot
, apidl
, cidl
);
218 /* build name of first file */
219 SHGetPathFromIDListA(pidlRoot
, szTemp
);
220 PathAddBackslashA(szTemp
);
221 len
= strlen(szTemp
);
222 _ILSimpleGetText(apidl
[0], szTemp
+len
, MAX_PATH
- len
);
223 size
= strlen(szTemp
) + 1;
225 /* fill the structure */
226 hGlobal
= GlobalAlloc(GHND
|GMEM_SHARE
, size
);
227 if(!hGlobal
) return hGlobal
;
228 szFileName
= (char *)GlobalLock(hGlobal
);
229 memcpy(szFileName
, szTemp
, size
);
230 GlobalUnlock(hGlobal
);
234 HGLOBAL
RenderFILENAMEW (LPITEMIDLIST pidlRoot
, LPITEMIDLIST
* apidl
, UINT cidl
)
237 WCHAR szTemp
[MAX_PATH
], *szFileName
;
240 TRACE("(%p,%p,%u)\n", pidlRoot
, apidl
, cidl
);
242 /* build name of first file */
243 SHGetPathFromIDListW(pidlRoot
, szTemp
);
244 PathAddBackslashW(szTemp
);
245 len
= strlenW(szTemp
);
246 _ILSimpleGetTextW(apidl
[0], szTemp
+len
, MAX_PATH
- len
);
247 size
= sizeof(WCHAR
) * (strlenW(szTemp
)+1);
249 /* fill the structure */
250 hGlobal
= GlobalAlloc(GHND
|GMEM_SHARE
, size
);
251 if(!hGlobal
) return hGlobal
;
252 szFileName
= (WCHAR
*)GlobalLock(hGlobal
);
253 memcpy(szFileName
, szTemp
, size
);
254 GlobalUnlock(hGlobal
);
258 HGLOBAL
RenderPREFEREDDROPEFFECT (DWORD dwFlags
)
263 TRACE("(0x%08lx)\n", dwFlags
);
265 hGlobal
= GlobalAlloc(GHND
|GMEM_SHARE
, sizeof(DWORD
));
266 if(!hGlobal
) return hGlobal
;
267 pdwFlag
= (DWORD
*)GlobalLock(hGlobal
);
269 GlobalUnlock(hGlobal
);
273 /**************************************************************************
276 * checks if there is something in the clipboard we can use
278 BOOL
IsDataInClipboard (HWND hwnd
)
282 if (OpenClipboard(hwnd
))
284 if (GetOpenClipboardWindow())
286 ret
= IsClipboardFormatAvailable(CF_TEXT
);