Fix the case of product and company names.
[wine] / dlls / shell32 / shv_bg_cmenu.c
1 /*
2  *      IContextMenu
3  *      ShellView Background Context Menu (shv_bg_cm)
4  *
5  *      Copyright 1999  Juergen Schmied <juergen.schmied@metronet.de>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 #include <string.h>
22
23 #define NONAMELESSUNION
24 #define NONAMELESSSTRUCT
25 #include "wine/debug.h"
26
27 #include "windef.h"
28 #include "wingdi.h"
29 #include "pidl.h"
30 #include "shlguid.h"
31 #include "shlobj.h"
32
33 #include "shell32_main.h"
34 #include "shellfolder.h"
35 #include "undocshell.h"
36
37 WINE_DEFAULT_DEBUG_CHANNEL(shell);
38
39 /**************************************************************************
40 *  IContextMenu Implementation
41 */
42 typedef struct
43 {
44         ICOM_VFIELD(IContextMenu);
45         IShellFolder*   pSFParent;
46         DWORD           ref;
47 } BgCmImpl;
48
49
50 static struct ICOM_VTABLE(IContextMenu) cmvt;
51
52 /**************************************************************************
53 *   ISVBgCm_Constructor()
54 */
55 IContextMenu *ISvBgCm_Constructor(IShellFolder* pSFParent)
56 {
57         BgCmImpl* cm;
58
59         cm = (BgCmImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(BgCmImpl));
60         cm->lpVtbl = &cmvt;
61         cm->ref = 1;
62         cm->pSFParent = pSFParent;
63         if(pSFParent) IShellFolder_AddRef(pSFParent);
64
65         TRACE("(%p)->()\n",cm);
66         return (IContextMenu*)cm;
67 }
68
69 /**************************************************************************
70 *  ISVBgCm_fnQueryInterface
71 */
72 static HRESULT WINAPI ISVBgCm_fnQueryInterface(IContextMenu *iface, REFIID riid, LPVOID *ppvObj)
73 {
74         ICOM_THIS(BgCmImpl, iface);
75
76         TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
77
78         *ppvObj = NULL;
79
80         if(IsEqualIID(riid, &IID_IUnknown))          /*IUnknown*/
81         {
82           *ppvObj = This;
83         }
84         else if(IsEqualIID(riid, &IID_IContextMenu))  /*IContextMenu*/
85         {
86           *ppvObj = This;
87         }
88         else if(IsEqualIID(riid, &IID_IShellExtInit))  /*IShellExtInit*/
89         {
90           FIXME("-- LPSHELLEXTINIT pointer requested\n");
91         }
92
93         if(*ppvObj)
94         {
95           IUnknown_AddRef((IUnknown*)*ppvObj);
96           TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
97           return S_OK;
98         }
99         TRACE("-- Interface: E_NOINTERFACE\n");
100         return E_NOINTERFACE;
101 }
102
103 /**************************************************************************
104 *  ISVBgCm_fnAddRef
105 */
106 static ULONG WINAPI ISVBgCm_fnAddRef(IContextMenu *iface)
107 {
108         ICOM_THIS(BgCmImpl, iface);
109
110         TRACE("(%p)->(count=%lu)\n",This, This->ref);
111
112         return ++(This->ref);
113 }
114
115 /**************************************************************************
116 *  ISVBgCm_fnRelease
117 */
118 static ULONG WINAPI ISVBgCm_fnRelease(IContextMenu *iface)
119 {
120         ICOM_THIS(BgCmImpl, iface);
121
122         TRACE("(%p)->()\n",This);
123
124         if (!--(This->ref))
125         {
126           TRACE(" destroying IContextMenu(%p)\n",This);
127
128           if(This->pSFParent)
129             IShellFolder_Release(This->pSFParent);
130
131           HeapFree(GetProcessHeap(),0,This);
132           return 0;
133         }
134
135         return This->ref;
136 }
137
138 /**************************************************************************
139 * ISVBgCm_fnQueryContextMenu()
140 */
141
142 static HRESULT WINAPI ISVBgCm_fnQueryContextMenu(
143         IContextMenu *iface,
144         HMENU hMenu,
145         UINT indexMenu,
146         UINT idCmdFirst,
147         UINT idCmdLast,
148         UINT uFlags)
149 {
150     HMENU       hMyMenu;
151     UINT        idMax;
152     HRESULT hr;
153
154     ICOM_THIS(BgCmImpl, iface);
155
156     TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",
157           This, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
158
159
160     hMyMenu = LoadMenuA(shell32_hInstance, "MENU_002");
161     if (uFlags & CMF_DEFAULTONLY)
162     {
163         HMENU ourMenu = GetSubMenu(hMyMenu,0);
164         UINT oldDef = GetMenuDefaultItem(hMenu,TRUE,GMDI_USEDISABLED);
165         UINT newDef = GetMenuDefaultItem(ourMenu,TRUE,GMDI_USEDISABLED);
166         if (newDef != oldDef)
167             SetMenuDefaultItem(hMenu,newDef,TRUE);
168         if (newDef!=0xFFFFFFFF)
169             hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, newDef+1);
170         else
171             hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);
172     }
173     else
174     {
175         idMax = Shell_MergeMenus (hMenu, GetSubMenu(hMyMenu,0), indexMenu,
176                                   idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS);
177         hr =  MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, idMax-idCmdFirst+1);
178     }
179     DestroyMenu(hMyMenu);
180
181     TRACE("(%p)->returning 0x%lx\n",This,hr);
182     return hr;
183 }
184
185 /**************************************************************************
186 * DoNewFolder
187 */
188 static void DoNewFolder(
189         IContextMenu *iface,
190         IShellView *psv)
191 {
192         ICOM_THIS(BgCmImpl, iface);
193         ISFHelper * psfhlp;
194         char szName[MAX_PATH];
195
196         IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlp);
197         if (psfhlp)
198         {
199           LPITEMIDLIST pidl;
200           ISFHelper_GetUniqueName(psfhlp, szName, MAX_PATH);
201           ISFHelper_AddFolder(psfhlp, 0, szName, &pidl);
202
203           if(psv)
204           {
205             /* if we are in a shellview do labeledit */
206             IShellView_SelectItem(psv,
207                     pidl,(SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE
208                     |SVSI_FOCUSED|SVSI_SELECT));
209           }
210           SHFree(pidl);
211
212           ISFHelper_Release(psfhlp);
213         }
214 }
215
216 /**************************************************************************
217 * DoPaste
218 */
219 static BOOL DoPaste(
220         IContextMenu *iface)
221 {
222         ICOM_THIS(BgCmImpl, iface);
223         BOOL bSuccess = FALSE;
224         IDataObject * pda;
225
226         TRACE("\n");
227
228         if(SUCCEEDED(pOleGetClipboard(&pda)))
229         {
230           STGMEDIUM medium;
231           FORMATETC formatetc;
232
233           TRACE("pda=%p\n", pda);
234
235           /* Set the FORMATETC structure*/
236           InitFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
237
238           /* Get the pidls from IDataObject */
239           if(SUCCEEDED(IDataObject_GetData(pda,&formatetc,&medium)))
240           {
241             LPITEMIDLIST * apidl;
242             LPITEMIDLIST pidl;
243             IShellFolder *psfFrom = NULL, *psfDesktop;
244
245             LPIDA lpcida = GlobalLock(medium.u.hGlobal);
246             TRACE("cida=%p\n", lpcida);
247
248             apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
249
250             /* bind to the source shellfolder */
251             SHGetDesktopFolder(&psfDesktop);
252             if(psfDesktop)
253             {
254               IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom);
255               IShellFolder_Release(psfDesktop);
256             }
257
258             if (psfFrom)
259             {
260               /* get source and destination shellfolder */
261               ISFHelper *psfhlpdst, *psfhlpsrc;
262               IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlpdst);
263               IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (LPVOID*)&psfhlpsrc);
264
265               /* do the copy/move */
266               if (psfhlpdst && psfhlpsrc)
267               {
268                 ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl);
269                 /* FIXME handle move
270                 ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl);
271                 */
272               }
273               if(psfhlpdst) ISFHelper_Release(psfhlpdst);
274               if(psfhlpsrc) ISFHelper_Release(psfhlpsrc);
275               IShellFolder_Release(psfFrom);
276             }
277
278             _ILFreeaPidl(apidl, lpcida->cidl);
279             SHFree(pidl);
280
281             /* release the medium*/
282             pReleaseStgMedium(&medium);
283           }
284           IDataObject_Release(pda);
285         }
286 #if 0
287         HGLOBAL  hMem;
288
289         OpenClipboard(NULL);
290         hMem = GetClipboardData(CF_HDROP);
291
292         if(hMem)
293         {
294           char * pDropFiles = (char *)GlobalLock(hMem);
295           if(pDropFiles)
296           {
297             int len, offset = sizeof(DROPFILESTRUCT);
298
299             while( pDropFiles[offset] != 0)
300             {
301               len = strlen(pDropFiles + offset);
302               TRACE("%s\n", pDropFiles + offset);
303               offset += len+1;
304             }
305           }
306           GlobalUnlock(hMem);
307         }
308         CloseClipboard();
309 #endif
310         return bSuccess;
311 }
312 /**************************************************************************
313 * ISVBgCm_fnInvokeCommand()
314 */
315 static HRESULT WINAPI ISVBgCm_fnInvokeCommand(
316         IContextMenu *iface,
317         LPCMINVOKECOMMANDINFO lpcmi)
318 {
319         ICOM_THIS(BgCmImpl, iface);
320
321         LPSHELLBROWSER  lpSB;
322         LPSHELLVIEW     lpSV;
323         HWND    hWndSV;
324
325         TRACE("(%p)->(invcom=%p verb=%p wnd=%p)\n",This,lpcmi,lpcmi->lpVerb, lpcmi->hwnd);
326
327         /* get the active IShellView */
328         if((lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER,0,0)))
329         {
330           if(SUCCEEDED(IShellBrowser_QueryActiveShellView(lpSB, &lpSV)))
331           {
332             IShellView_GetWindow(lpSV, &hWndSV);
333           }
334         }
335
336         if(lpSV)
337         {
338           if(HIWORD(lpcmi->lpVerb))
339           {
340             TRACE("%s\n",lpcmi->lpVerb);
341
342             if (! strcmp(lpcmi->lpVerb,CMDSTR_NEWFOLDERA))
343             {
344               if(lpSV) DoNewFolder(iface, lpSV);
345             }
346             else if (! strcmp(lpcmi->lpVerb,CMDSTR_VIEWLISTA))
347             {
348               if(hWndSV) SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(FCIDM_SHVIEW_LISTVIEW,0),0 );
349             }
350             else if (! strcmp(lpcmi->lpVerb,CMDSTR_VIEWDETAILSA))
351             {
352               if(hWndSV) SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(FCIDM_SHVIEW_REPORTVIEW,0),0 );
353             }
354             else
355             {
356               FIXME("please report: unknown verb %s\n",lpcmi->lpVerb);
357             }
358           }
359           else
360           {
361             switch(LOWORD(lpcmi->lpVerb))
362             {
363               case FCIDM_SHVIEW_NEWFOLDER:
364                 DoNewFolder(iface, lpSV);
365                 break;
366               case FCIDM_SHVIEW_INSERT:
367                 DoPaste(iface);
368                 break;
369               default:
370                 /* if it's a id just pass it to the parent shv */
371                 SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0),0 );
372                 break;
373             }
374           }
375
376           IShellView_Release(lpSV);     /* QueryActiveShellView does AddRef*/
377         }
378         return NOERROR;
379 }
380
381 /**************************************************************************
382  *  ISVBgCm_fnGetCommandString()
383  *
384  */
385 static HRESULT WINAPI ISVBgCm_fnGetCommandString(
386         IContextMenu *iface,
387         UINT idCommand,
388         UINT uFlags,
389         UINT* lpReserved,
390         LPSTR lpszName,
391         UINT uMaxNameLen)
392 {
393         ICOM_THIS(BgCmImpl, iface);
394
395         TRACE("(%p)->(idcom=%x flags=%x %p name=%p len=%x)\n",This, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen);
396
397         /* test the existence of the menu items, the file dialog enables
398            the buttons according to this */
399         if (uFlags == GCS_VALIDATEA)
400         {
401           if(HIWORD(idCommand))
402           {
403             if (!strcmp((LPSTR)idCommand, CMDSTR_VIEWLISTA) ||
404                 !strcmp((LPSTR)idCommand, CMDSTR_VIEWDETAILSA) ||
405                 !strcmp((LPSTR)idCommand, CMDSTR_NEWFOLDERA))
406             {
407               return NOERROR;
408             }
409           }
410         }
411
412         FIXME("unknown command string\n");
413         return E_FAIL;
414 }
415
416 /**************************************************************************
417 * ISVBgCm_fnHandleMenuMsg()
418 */
419 static HRESULT WINAPI ISVBgCm_fnHandleMenuMsg(
420         IContextMenu *iface,
421         UINT uMsg,
422         WPARAM wParam,
423         LPARAM lParam)
424 {
425         ICOM_THIS(BgCmImpl, iface);
426
427         FIXME("(%p)->(msg=%x wp=%x lp=%lx)\n",This, uMsg, wParam, lParam);
428
429         return E_NOTIMPL;
430 }
431
432 /**************************************************************************
433 * IContextMenu VTable
434 *
435 */
436 static struct ICOM_VTABLE(IContextMenu) cmvt =
437 {
438         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
439         ISVBgCm_fnQueryInterface,
440         ISVBgCm_fnAddRef,
441         ISVBgCm_fnRelease,
442         ISVBgCm_fnQueryContextMenu,
443         ISVBgCm_fnInvokeCommand,
444         ISVBgCm_fnGetCommandString,
445         ISVBgCm_fnHandleMenuMsg,
446         (void *) 0xdeadbabe     /* just paranoia (IContextMenu3) */
447 };