Various cosmetic changes.
[wine] / dlls / shell32 / clipboard.c
1 /*
2  *      clipboard helper functions
3  *
4  *      Copyright 2000  Juergen Schmied <juergen.schmied@debitel.de>
5  *
6  * For copy & paste functions within contextmenus does the shell use
7  * the OLE clipboard functions in combination with dataobjects.
8  * The OLE32.DLL gets loaded with LoadLibrary
9  *
10  * - a right mousebutton-copy sets the following formats:
11  *  classic:
12  *      Shell IDList Array
13  *      Prefered Drop Effect
14  *      Shell Object Offsets
15  *      HDROP
16  *      FileName
17  *  ole:
18  *      OlePrivateData (ClipboardDataObjectInterface)
19  *
20  */
21
22 #include <string.h>
23
24 #include "winreg.h"
25 #include "pidl.h"
26 #include "undocshell.h"
27 #include "shell32_main.h"
28 #include "shlwapi.h"
29
30 #include "debugtools.h"
31
32 DEFAULT_DEBUG_CHANNEL(shell);
33
34 static int refClipCount = 0;
35 static HINSTANCE hShellOle32 = 0;
36
37 /**************************************************************************
38  * InitShellOle
39  *
40  * 
41  */
42 void InitShellOle(void)
43 {
44 }
45
46 /**************************************************************************
47  * FreeShellOle
48  *
49  * unload OLE32.DLL
50  */
51 void FreeShellOle(void)
52 {
53         if (!--refClipCount)
54         {
55           pOleUninitialize();
56           FreeLibrary(hShellOle32);
57         }
58 }
59
60 /**************************************************************************
61  * LoadShellOle
62  *
63  * make sure OLE32.DLL is loaded
64  */
65 BOOL GetShellOle(void)
66 {
67         if(!refClipCount)
68         {
69           hShellOle32 = LoadLibraryA("ole32.dll");
70           if(hShellOle32)
71           {
72             pOleInitialize=(void*)GetProcAddress(hShellOle32,"OleInitialize");
73             pOleUninitialize=(void*)GetProcAddress(hShellOle32,"OleUninitialize");
74             pRegisterDragDrop=(void*)GetProcAddress(hShellOle32,"RegisterDragDrop");
75             pRevokeDragDrop=(void*)GetProcAddress(hShellOle32,"RevokeDragDrop");
76             pDoDragDrop=(void*)GetProcAddress(hShellOle32,"DoDragDrop");
77             pReleaseStgMedium=(void*)GetProcAddress(hShellOle32,"ReleaseStgMedium");
78             pOleSetClipboard=(void*)GetProcAddress(hShellOle32,"OleSetClipboard");
79             pOleGetClipboard=(void*)GetProcAddress(hShellOle32,"OleGetClipboard");
80
81             pOleInitialize(NULL);
82             refClipCount++;
83           }
84         }
85         return TRUE;
86 }
87
88 /**************************************************************************
89  * RenderHDROP
90  *
91  * creates a CF_HDROP structure
92  */
93 HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
94 {
95         int i;
96         int rootsize = 0,size = 0;
97         char szRootPath[MAX_PATH];
98         char szFileName[MAX_PATH];
99         HGLOBAL hGlobal;
100         DROPFILES *pDropFiles;
101         int offset;
102         
103         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
104
105         /* get the size needed */
106         size = sizeof(DROPFILES);
107
108         SHGetPathFromIDListA(pidlRoot, szRootPath);
109         PathAddBackslashA(szRootPath);
110         rootsize = strlen(szRootPath);
111         
112         for (i=0; i<cidl;i++)
113         {
114           _ILSimpleGetText(apidl[i], szFileName, MAX_PATH);
115           size += rootsize + strlen(szFileName) + 1;
116         }
117
118         size++;
119
120         /* Fill the structure */
121         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
122         if(!hGlobal) return hGlobal;
123
124         pDropFiles = (DROPFILES *)GlobalLock(hGlobal);
125         pDropFiles->pFiles = sizeof(DROPFILES);
126         pDropFiles->fWide = FALSE;
127
128         offset = pDropFiles->pFiles;
129         strcpy(szFileName, szRootPath);
130         
131         for (i=0; i<cidl;i++)
132         {
133           
134           _ILSimpleGetText(apidl[i], szFileName + rootsize, MAX_PATH - rootsize);
135           size = strlen(szFileName) + 1;
136           strcpy(((char*)pDropFiles)+offset, szFileName);
137           offset += size;
138         }
139
140         ((char*)pDropFiles)[offset] = 0;
141         GlobalUnlock(hGlobal);
142
143         return hGlobal;
144 }
145
146 HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
147 {
148         int i,offset = 0, sizePidl, size;
149         HGLOBAL hGlobal;
150         LPCIDA  pcida;
151
152         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
153
154         /* get the size needed */
155         size = sizeof(CIDA) + sizeof (UINT)*(cidl);     /* header */
156         size += ILGetSize (pidlRoot);                   /* root pidl */
157         for(i=0; i<cidl; i++)
158         {
159           size += ILGetSize(apidl[i]);                  /* child pidls */
160         }
161
162         /* fill the structure */
163         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);           
164         if(!hGlobal) return hGlobal;
165         pcida = GlobalLock (hGlobal);
166         pcida->cidl = cidl;
167
168         /* root pidl */
169         offset = sizeof(CIDA) + sizeof (UINT)*(cidl);
170         pcida->aoffset[0] = offset;                     /* first element */
171         sizePidl = ILGetSize (pidlRoot);
172         memcpy(((LPBYTE)pcida)+offset, pidlRoot, sizePidl);
173         offset += sizePidl;
174
175         for(i=0; i<cidl; i++)                           /* child pidls */
176         {
177           pcida->aoffset[i+1] = offset;
178           sizePidl = ILGetSize(apidl[i]);
179           memcpy(((LPBYTE)pcida)+offset, apidl[i], sizePidl);
180           offset += sizePidl;
181         }
182
183         GlobalUnlock(hGlobal);
184         return hGlobal;
185 }
186
187 HGLOBAL RenderSHELLIDLISTOFFSET (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
188 {
189         FIXME("\n");
190         return 0;
191 }
192
193 HGLOBAL RenderFILECONTENTS (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
194 {
195         FIXME("\n");
196         return 0;
197 }
198
199 HGLOBAL RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
200 {
201         FIXME("\n");
202         return 0;
203 }
204
205 HGLOBAL RenderFILENAME (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
206 {
207         int len, size = 0;
208         char szTemp[MAX_PATH], *szFileName;
209         HGLOBAL hGlobal;
210         
211         TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl);
212
213         /* build name of first file */
214         SHGetPathFromIDListA(pidlRoot, szTemp);
215         PathAddBackslashA(szTemp);
216         len = strlen(szTemp);
217         _ILSimpleGetText(apidl[0], szTemp+len, MAX_PATH - len);
218         size = strlen(szTemp) + 1;
219
220         /* fill the structure */
221         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size);
222         if(!hGlobal) return hGlobal;
223         szFileName = (char *)GlobalLock(hGlobal);
224         GlobalUnlock(hGlobal);
225         return hGlobal;
226 }
227
228 HGLOBAL RenderPREFEREDDROPEFFECT (DWORD dwFlags)
229 {
230         DWORD * pdwFlag;
231         HGLOBAL hGlobal;
232         
233         TRACE("(0x%08lx)\n", dwFlags);
234
235         hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD));
236         if(!hGlobal) return hGlobal;
237         pdwFlag = (DWORD*)GlobalLock(hGlobal);
238         *pdwFlag = dwFlags;
239         GlobalUnlock(hGlobal);
240         return hGlobal;
241 }
242
243 /**************************************************************************
244  * IsDataInClipboard
245  *
246  * checks if there is something in the clipboard we can use
247  */
248 BOOL IsDataInClipboard (HWND hwnd)
249 {
250         BOOL ret = FALSE;
251         
252         if (OpenClipboard(hwnd))
253         {
254           if (GetOpenClipboardWindow())
255           {
256             ret = IsClipboardFormatAvailable(CF_TEXT);
257           }
258           CloseClipboard();
259         }
260         return ret;
261 }