| /* | |
| * IContextMenu | |
| * ShellView Background Context Menu (shv_bg_cm) | |
| * | |
| * Copyright 1999 Juergen Schmied <juergen.schmied@metronet.de> | |
| */ | |
| #include <string.h> | |
| #include "debugtools.h" | |
| #include "pidl.h" | |
| #include "wine/obj_base.h" | |
| #include "wine/obj_contextmenu.h" | |
| #include "wine/obj_shellbrowser.h" | |
| #include "shell32_main.h" | |
| #include "shellfolder.h" | |
| #include "shell.h" /* DROPFILESTRUCT */ | |
| DEFAULT_DEBUG_CHANNEL(shell) | |
| /************************************************************************** | |
| * IContextMenu Implementation | |
| */ | |
| typedef struct | |
| { | |
| ICOM_VFIELD(IContextMenu); | |
| IShellFolder* pSFParent; | |
| DWORD ref; | |
| } BgCmImpl; | |
| static struct ICOM_VTABLE(IContextMenu) cmvt; | |
| /************************************************************************** | |
| * ISVBgCm_Constructor() | |
| */ | |
| IContextMenu *ISvBgCm_Constructor(IShellFolder* pSFParent) | |
| { | |
| BgCmImpl* cm; | |
| cm = (BgCmImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(BgCmImpl)); | |
| ICOM_VTBL(cm)=&cmvt; | |
| cm->ref = 1; | |
| cm->pSFParent = pSFParent; | |
| if(pSFParent) IShellFolder_AddRef(pSFParent); | |
| TRACE("(%p)->()\n",cm); | |
| shell32_ObjCount++; | |
| return (IContextMenu*)cm; | |
| } | |
| /************************************************************************** | |
| * ISVBgCm_fnQueryInterface | |
| */ | |
| static HRESULT WINAPI ISVBgCm_fnQueryInterface(IContextMenu *iface, REFIID riid, LPVOID *ppvObj) | |
| { | |
| ICOM_THIS(BgCmImpl, iface); | |
| TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj); | |
| *ppvObj = NULL; | |
| if(IsEqualIID(riid, &IID_IUnknown)) /*IUnknown*/ | |
| { | |
| *ppvObj = This; | |
| } | |
| else if(IsEqualIID(riid, &IID_IContextMenu)) /*IContextMenu*/ | |
| { | |
| *ppvObj = This; | |
| } | |
| else if(IsEqualIID(riid, &IID_IShellExtInit)) /*IShellExtInit*/ | |
| { | |
| FIXME("-- LPSHELLEXTINIT pointer requested\n"); | |
| } | |
| if(*ppvObj) | |
| { | |
| IUnknown_AddRef((IUnknown*)*ppvObj); | |
| TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); | |
| return S_OK; | |
| } | |
| TRACE("-- Interface: E_NOINTERFACE\n"); | |
| return E_NOINTERFACE; | |
| } | |
| /************************************************************************** | |
| * ISVBgCm_fnAddRef | |
| */ | |
| static ULONG WINAPI ISVBgCm_fnAddRef(IContextMenu *iface) | |
| { | |
| ICOM_THIS(BgCmImpl, iface); | |
| TRACE("(%p)->(count=%lu)\n",This, This->ref); | |
| shell32_ObjCount++; | |
| return ++(This->ref); | |
| } | |
| /************************************************************************** | |
| * ISVBgCm_fnRelease | |
| */ | |
| static ULONG WINAPI ISVBgCm_fnRelease(IContextMenu *iface) | |
| { | |
| ICOM_THIS(BgCmImpl, iface); | |
| TRACE("(%p)->()\n",This); | |
| if (!--(This->ref)) | |
| { | |
| TRACE(" destroying IContextMenu(%p)\n",This); | |
| if(This->pSFParent) | |
| IShellFolder_Release(This->pSFParent); | |
| HeapFree(GetProcessHeap(),0,This); | |
| return 0; | |
| } | |
| shell32_ObjCount--; | |
| return This->ref; | |
| } | |
| /************************************************************************** | |
| * ISVBgCm_fnQueryContextMenu() | |
| */ | |
| static HRESULT WINAPI ISVBgCm_fnQueryContextMenu( | |
| IContextMenu *iface, | |
| HMENU hMenu, | |
| UINT indexMenu, | |
| UINT idCmdFirst, | |
| UINT idCmdLast, | |
| UINT uFlags) | |
| { | |
| HMENU hMyMenu; | |
| UINT idMax; | |
| ICOM_THIS(BgCmImpl, iface); | |
| TRACE("(%p)->(hmenu=%x indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",This, hMenu, indexMenu, idCmdFirst, idCmdLast, uFlags); | |
| hMyMenu = LoadMenuA(shell32_hInstance, "MENU_002"); | |
| idMax = Shell_MergeMenus (hMenu, GetSubMenu(hMyMenu,0), indexMenu, idCmdFirst, idCmdLast, MM_SUBMENUSHAVEIDS); | |
| DestroyMenu(hMyMenu); | |
| return ResultFromShort(idMax - idCmdFirst); | |
| } | |
| /************************************************************************** | |
| * DoNewFolder | |
| */ | |
| static void DoNewFolder( | |
| IContextMenu *iface, | |
| IShellView *psv) | |
| { | |
| ICOM_THIS(BgCmImpl, iface); | |
| ISFHelper * psfhlp; | |
| char szName[MAX_PATH]; | |
| IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlp); | |
| if (psfhlp) | |
| { | |
| LPITEMIDLIST pidl; | |
| ISFHelper_GetUniqueName(psfhlp, szName, MAX_PATH); | |
| ISFHelper_AddFolder(psfhlp, 0, szName, &pidl); | |
| if(psv) | |
| { | |
| /* if we are in a shellview do labeledit */ | |
| IShellView_SelectItem(psv, | |
| pidl,(SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | |
| |SVSI_FOCUSED|SVSI_SELECT)); | |
| } | |
| SHFree(pidl); | |
| ISFHelper_Release(psfhlp); | |
| } | |
| } | |
| /************************************************************************** | |
| * DoPaste | |
| */ | |
| static BOOL DoPaste( | |
| IContextMenu *iface) | |
| { | |
| ICOM_THIS(BgCmImpl, iface); | |
| BOOL bSuccess = FALSE; | |
| IDataObject * pda; | |
| TRACE("\n"); | |
| if(SUCCEEDED(pOleGetClipboard(&pda))); | |
| { | |
| STGMEDIUM medium; | |
| FORMATETC formatetc; | |
| TRACE("pda=%p\n", pda); | |
| /* Set the FORMATETC structure*/ | |
| InitFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLIST), TYMED_HGLOBAL); | |
| /* Get the pidls from IDataObject */ | |
| if(SUCCEEDED(IDataObject_GetData(pda,&formatetc,&medium))) | |
| { | |
| LPITEMIDLIST * apidl; | |
| LPITEMIDLIST pidl; | |
| IShellFolder *psfFrom = NULL, *psfDesktop; | |
| LPCIDA lpcida = GlobalLock(medium.u.hGlobal); | |
| TRACE("cida=%p\n", lpcida); | |
| apidl = _ILCopyCidaToaPidl(&pidl, lpcida); | |
| /* bind to the source shellfolder */ | |
| SHGetDesktopFolder(&psfDesktop); | |
| if(psfDesktop) | |
| { | |
| IShellFolder_BindToObject(psfDesktop, pidl, NULL, &IID_IShellFolder, (LPVOID*)&psfFrom); | |
| IShellFolder_Release(psfDesktop); | |
| } | |
| if (psfFrom) | |
| { | |
| /* get source and destination shellfolder */ | |
| ISFHelper *psfhlpdst, *psfhlpsrc; | |
| IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlpdst); | |
| IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (LPVOID*)&psfhlpsrc); | |
| /* do the copy/move */ | |
| if (psfhlpdst && psfhlpsrc) | |
| { | |
| ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, apidl); | |
| /* fixme handle move | |
| ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl); | |
| */ | |
| } | |
| if(psfhlpdst) ISFHelper_Release(psfhlpdst); | |
| if(psfhlpsrc) ISFHelper_Release(psfhlpsrc); | |
| IShellFolder_Release(psfFrom); | |
| } | |
| _ILFreeaPidl(apidl, lpcida->cidl); | |
| SHFree(pidl); | |
| /* release the medium*/ | |
| pReleaseStgMedium(&medium); | |
| } | |
| IDataObject_Release(pda); | |
| } | |
| #if 0 | |
| HGLOBAL hMem; | |
| OpenClipboard(NULL); | |
| hMem = GetClipboardData(CF_HDROP); | |
| if(hMem) | |
| { | |
| char * pDropFiles = (char *)GlobalLock(hMem); | |
| if(pDropFiles) | |
| { | |
| int len, offset = sizeof(DROPFILESTRUCT); | |
| while( pDropFiles[offset] != 0) | |
| { | |
| len = strlen(pDropFiles + offset); | |
| TRACE("%s\n", pDropFiles + offset); | |
| offset += len+1; | |
| } | |
| } | |
| GlobalUnlock(hMem); | |
| } | |
| CloseClipboard(); | |
| #endif | |
| return bSuccess; | |
| } | |
| /************************************************************************** | |
| * ISVBgCm_fnInvokeCommand() | |
| */ | |
| static HRESULT WINAPI ISVBgCm_fnInvokeCommand( | |
| IContextMenu *iface, | |
| LPCMINVOKECOMMANDINFO lpcmi) | |
| { | |
| ICOM_THIS(BgCmImpl, iface); | |
| LPSHELLBROWSER lpSB; | |
| LPSHELLVIEW lpSV; | |
| HWND hWndSV; | |
| TRACE("(%p)->(invcom=%p verb=%p wnd=%x)\n",This,lpcmi,lpcmi->lpVerb, lpcmi->hwnd); | |
| /* get the active IShellView */ | |
| if((lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER,0,0))) | |
| { | |
| if(SUCCEEDED(IShellBrowser_QueryActiveShellView(lpSB, &lpSV))) | |
| { | |
| IShellView_GetWindow(lpSV, &hWndSV); | |
| } | |
| } | |
| if(lpSV) | |
| { | |
| if(HIWORD(lpcmi->lpVerb)) | |
| { | |
| TRACE("%s\n",lpcmi->lpVerb); | |
| if (! strcmp(lpcmi->lpVerb,CMDSTR_NEWFOLDERA)) | |
| { | |
| if(lpSV) DoNewFolder(iface, lpSV); | |
| } | |
| else if (! strcmp(lpcmi->lpVerb,CMDSTR_VIEWLISTA)) | |
| { | |
| if(hWndSV) SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(FCIDM_SHVIEW_LISTVIEW,0),0 ); | |
| } | |
| else if (! strcmp(lpcmi->lpVerb,CMDSTR_VIEWDETAILSA)) | |
| { | |
| if(hWndSV) SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(FCIDM_SHVIEW_REPORTVIEW,0),0 ); | |
| } | |
| else | |
| { | |
| FIXME("please report: unknown verb %s\n",lpcmi->lpVerb); | |
| } | |
| } | |
| else | |
| { | |
| switch(LOWORD(lpcmi->lpVerb)) | |
| { | |
| case FCIDM_SHVIEW_NEWFOLDER: | |
| DoNewFolder(iface, lpSV); | |
| break; | |
| case FCIDM_SHVIEW_INSERT: | |
| DoPaste(iface); | |
| break; | |
| default: | |
| /* if it's a id just pass it to the parent shv */ | |
| SendMessageA(hWndSV, WM_COMMAND, MAKEWPARAM(LOWORD(lpcmi->lpVerb), 0),0 ); | |
| break; | |
| } | |
| } | |
| IShellView_Release(lpSV); /* QueryActiveShellView does AddRef*/ | |
| } | |
| return NOERROR; | |
| } | |
| /************************************************************************** | |
| * ISVBgCm_fnGetCommandString() | |
| * | |
| */ | |
| static HRESULT WINAPI ISVBgCm_fnGetCommandString( | |
| IContextMenu *iface, | |
| UINT idCommand, | |
| UINT uFlags, | |
| LPUINT lpReserved, | |
| LPSTR lpszName, | |
| UINT uMaxNameLen) | |
| { | |
| ICOM_THIS(BgCmImpl, iface); | |
| TRACE("(%p)->(idcom=%x flags=%x %p name=%p len=%x)\n",This, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen); | |
| /* test the existance of the menu items, the file dialog enables | |
| the buttons according to this */ | |
| if (uFlags == GCS_VALIDATEA) | |
| { | |
| if(HIWORD(idCommand)) | |
| { | |
| if (!strcmp((LPSTR)idCommand, CMDSTR_VIEWLISTA) || | |
| !strcmp((LPSTR)idCommand, CMDSTR_VIEWDETAILSA) || | |
| !strcmp((LPSTR)idCommand, CMDSTR_NEWFOLDERA)) | |
| { | |
| return NOERROR; | |
| } | |
| } | |
| } | |
| FIXME("unknown command string\n"); | |
| return E_FAIL; | |
| } | |
| /************************************************************************** | |
| * ISVBgCm_fnHandleMenuMsg() | |
| */ | |
| static HRESULT WINAPI ISVBgCm_fnHandleMenuMsg( | |
| IContextMenu *iface, | |
| UINT uMsg, | |
| WPARAM wParam, | |
| LPARAM lParam) | |
| { | |
| ICOM_THIS(BgCmImpl, iface); | |
| FIXME("(%p)->(msg=%x wp=%x lp=%lx)\n",This, uMsg, wParam, lParam); | |
| return E_NOTIMPL; | |
| } | |
| /************************************************************************** | |
| * IContextMenu VTable | |
| * | |
| */ | |
| static struct ICOM_VTABLE(IContextMenu) cmvt = | |
| { | |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE | |
| ISVBgCm_fnQueryInterface, | |
| ISVBgCm_fnAddRef, | |
| ISVBgCm_fnRelease, | |
| ISVBgCm_fnQueryContextMenu, | |
| ISVBgCm_fnInvokeCommand, | |
| ISVBgCm_fnGetCommandString, | |
| ISVBgCm_fnHandleMenuMsg, | |
| (void *) 0xdeadbabe /* just paranoia (IContextMenu3) */ | |
| }; | |