diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in index 1d94f6dad5e..fe98fcc8cc8 100644 --- a/dlls/shell32/Makefile.in +++ b/dlls/shell32/Makefile.in @@ -16,8 +16,9 @@ SPEC_SRCS = \ C_SRCS = \ brsfolder.c \ + changenotify.c \ classes.c \ - contmenu.c \ + clipboard.c \ dataobject.c \ enumidlist.c \ folders.c \ @@ -33,10 +34,12 @@ C_SRCS = \ shellole.c \ shellord.c \ shellpath.c \ + shlfileop.c \ shlfolder.c \ shlview.c \ shpolicy.c \ shv_bg_cmenu.c \ + shv_item_cmenu.c \ systray.c RC_SRCS= \ diff --git a/dlls/shell32/clipboard.c b/dlls/shell32/clipboard.c new file mode 100644 index 00000000000..88ee2d9df94 --- /dev/null +++ b/dlls/shell32/clipboard.c @@ -0,0 +1,260 @@ +/* + * clipboard helper functions + * + * Copyright 2000 Juergen Schmied + * + * For copy & paste functions within contextmenus does the shell use + * the OLE clipboard functions in combination with dataobjects. + * The OLE32.DLL gets loaded with LoadLibrary + * + * - a right mousebutton-copy sets the following formats: + * classic: + * Shell IDList Array + * Prefered Drop Effect + * Shell Object Offsets + * HDROP + * FileName + * ole: + * OlePrivateData (ClipboardDataObjectInterface) + * + */ + +#include + +#include "debugtools.h" + +#include "pidl.h" +#include "wine/undocshell.h" +#include "shell32_main.h" +#include "shell.h" /* DROPFILESTRUCT */ + +DEFAULT_DEBUG_CHANNEL(shell) + +static int refClipCount = 0; +static HINSTANCE hShellOle32 = 0; + +/************************************************************************** + * InitShellOle + * + * + */ +void InitShellOle(void) +{ +} + +/************************************************************************** + * FreeShellOle + * + * unload OLE32.DLL + */ +void FreeShellOle(void) +{ + if (!--refClipCount) + { + pOleUninitialize(); + FreeLibrary(hShellOle32); + } +} + +/************************************************************************** + * LoadShellOle + * + * make sure OLE32.DLL is loaded + */ +BOOL GetShellOle(void) +{ + if(!refClipCount) + { + hShellOle32 = LoadLibraryA("ole32.dll"); + if(hShellOle32) + { + pOleInitialize=(void*)GetProcAddress(hShellOle32,"OleInitialize"); + pOleUninitialize=(void*)GetProcAddress(hShellOle32,"OleUninitialize"); + pRegisterDragDrop=(void*)GetProcAddress(hShellOle32,"RegisterDragDrop"); + pRevokeDragDrop=(void*)GetProcAddress(hShellOle32,"RevokeDragDrop"); + pDoDragDrop=(void*)GetProcAddress(hShellOle32,"DoDragDrop"); + pReleaseStgMedium=(void*)GetProcAddress(hShellOle32,"ReleaseStgMedium"); + pOleSetClipboard=(void*)GetProcAddress(hShellOle32,"OleSetClipboard"); + pOleGetClipboard=(void*)GetProcAddress(hShellOle32,"OleGetClipboard"); + + pOleInitialize(NULL); + refClipCount++; + } + } + return TRUE; +} + +/************************************************************************** + * RenderHDROP + * + * creates a CF_HDROP structure + */ +HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) +{ + int i; + int rootsize = 0,size = 0; + char szRootPath[MAX_PATH]; + char szFileName[MAX_PATH]; + HGLOBAL hGlobal; + LPDROPFILESTRUCT pDropFiles; + int offset; + + TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); + + /* get the size needed */ + size = sizeof(DROPFILESTRUCT); + + SHGetPathFromIDListA(pidlRoot, szRootPath); + PathAddBackslashA(szRootPath); + rootsize = strlen(szRootPath); + + for (i=0; ilSize = sizeof(DROPFILESTRUCT); + pDropFiles->fWideChar = FALSE; + + offset = pDropFiles->lSize; + strcpy(szFileName, szRootPath); + + for (i=0; icidl = cidl; + + /* root pidl */ + offset = sizeof(CIDA) + sizeof (UINT)*(cidl); + pcida->aoffset[0] = offset; /* first element */ + sizePidl = ILGetSize (pidlRoot); + memcpy(((LPBYTE)pcida)+offset, pidlRoot, sizePidl); + offset += sizePidl; + + for(i=0; iaoffset[i+1] = offset; + sizePidl = ILGetSize(apidl[i]); + memcpy(((LPBYTE)pcida)+offset, apidl[i], sizePidl); + offset += sizePidl; + } + + GlobalUnlock(hGlobal); + return hGlobal; +} + +HGLOBAL RenderSHELLIDLISTOFFSET (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) +{ + FIXME("\n"); + return 0; +} + +HGLOBAL RenderFILECONTENTS (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) +{ + FIXME("\n"); + return 0; +} + +HGLOBAL RenderFILEDESCRIPTOR (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) +{ + FIXME("\n"); + return 0; +} + +HGLOBAL RenderFILENAME (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) +{ + int len, size = 0; + char szTemp[MAX_PATH], *szFileName; + HGLOBAL hGlobal; + + TRACE("(%p,%p,%u)\n", pidlRoot, apidl, cidl); + + /* build name of first file */ + SHGetPathFromIDListA(pidlRoot, szTemp); + PathAddBackslashA(szTemp); + len = strlen(szTemp); + _ILSimpleGetText(apidl[0], szTemp+len, MAX_PATH - len); + size = strlen(szTemp) + 1; + + /* fill the structure */ + hGlobal = GlobalAlloc(GHND|GMEM_SHARE, size); + if(!hGlobal) return hGlobal; + szFileName = (char *)GlobalLock(hGlobal); + GlobalUnlock(hGlobal); + return hGlobal; +} + +HGLOBAL RenderPREFEREDDROPEFFECT (DWORD dwFlags) +{ + DWORD * pdwFlag; + HGLOBAL hGlobal; + + TRACE("(0x%08lx)\n", dwFlags); + + hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD)); + if(!hGlobal) return hGlobal; + pdwFlag = (DWORD*)GlobalLock(hGlobal); + *pdwFlag = dwFlags; + GlobalUnlock(hGlobal); + return hGlobal; +} + +/************************************************************************** + * IsDataInClipboard + * + * checks if there is something in the clipboard we can use + */ +BOOL IsDataInClipboard (HWND hwnd) +{ + BOOL ret = FALSE; + + if (OpenClipboard(hwnd)) + { + if (GetOpenClipboardWindow()) + { + ret = IsClipboardFormatAvailable(CF_TEXT); + } + CloseClipboard(); + } + return ret; +} diff --git a/dlls/shell32/contmenu.c b/dlls/shell32/contmenu.c deleted file mode 100644 index 0b95a77acf7..00000000000 --- a/dlls/shell32/contmenu.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * IContextMenu - * - * Copyright 1998 Juergen Schmied - */ -#include - -#include "winerror.h" -#include "debugtools.h" - -#include "pidl.h" -#include "wine/obj_base.h" -#include "wine/obj_contextmenu.h" -#include "wine/obj_shellbrowser.h" -#include "wine/obj_shellextinit.h" -#include "wine/undocshell.h" - -#include "shell32_main.h" - -DEFAULT_DEBUG_CHANNEL(shell) - -/************************************************************************** -* IContextMenu VTable -* -*/ - -static HRESULT WINAPI IContextMenu_fnQueryInterface(IContextMenu *iface, REFIID riid, LPVOID *ppvObj); -static ULONG WINAPI IContextMenu_fnAddRef(IContextMenu *iface); -static ULONG WINAPI IContextMenu_fnRelease(IContextMenu *iface); -static HRESULT WINAPI IContextMenu_fnQueryContextMenu(IContextMenu *iface, HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags); -static HRESULT WINAPI IContextMenu_fnInvokeCommand(IContextMenu *iface, LPCMINVOKECOMMANDINFO lpcmi); -static HRESULT WINAPI IContextMenu_fnGetCommandString(IContextMenu *iface, UINT idCommand, UINT uFlags, LPUINT lpReserved, LPSTR lpszName, UINT uMaxNameLen); -static HRESULT WINAPI IContextMenu_fnHandleMenuMsg(IContextMenu *iface, UINT uMsg, WPARAM wParam, LPARAM lParam); - -static struct ICOM_VTABLE(IContextMenu) cmvt = -{ - ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE - IContextMenu_fnQueryInterface, - IContextMenu_fnAddRef, - IContextMenu_fnRelease, - IContextMenu_fnQueryContextMenu, - IContextMenu_fnInvokeCommand, - IContextMenu_fnGetCommandString, - IContextMenu_fnHandleMenuMsg, - (void *) 0xdeadbabe /* just paranoia */ -}; - -/************************************************************************** -* IContextMenu Implementation -*/ -typedef struct -{ ICOM_VFIELD(IContextMenu); - DWORD ref; - IShellFolder* pSFParent; - LPITEMIDLIST pidl; /* root pidl */ - LPITEMIDLIST *aPidls; /* array of child pidls */ - BOOL bAllValues; -} IContextMenuImpl; - - -static struct ICOM_VTABLE(IContextMenu) cmvt; - -/************************************************************************** -* IContextMenu_AllocPidlTable() -*/ -static BOOL IContextMenu_AllocPidlTable(IContextMenuImpl *This, DWORD dwEntries) -{ - TRACE("(%p)->(entrys=%lu)\n",This, dwEntries); - - /*add one for NULL terminator */ - dwEntries++; - - This->aPidls = (LPITEMIDLIST*)SHAlloc(dwEntries * sizeof(LPITEMIDLIST)); - - if(This->aPidls) - { ZeroMemory(This->aPidls, dwEntries * sizeof(LPITEMIDLIST)); /*set all of the entries to NULL*/ - } - return (This->aPidls != NULL); -} - -/************************************************************************** -* IContextMenu_FreePidlTable() -*/ -static void IContextMenu_FreePidlTable(IContextMenuImpl *This) -{ - int i; - - TRACE("(%p)->()\n",This); - - if(This->aPidls) - { for(i = 0; This->aPidls[i]; i++) - { SHFree(This->aPidls[i]); - } - - SHFree(This->aPidls); - This->aPidls = NULL; - } -} - -/************************************************************************** -* IContextMenu_FillPidlTable() -*/ -static BOOL IContextMenu_FillPidlTable(IContextMenuImpl *This, LPCITEMIDLIST *aPidls, UINT uItemCount) -{ - UINT i; - - TRACE("(%p)->(apidl=%p count=%u)\n",This, aPidls, uItemCount); - - if(This->aPidls) - { for(i = 0; i < uItemCount; i++) - { This->aPidls[i] = ILClone(aPidls[i]); - } - return TRUE; - } - return FALSE; -} - -/************************************************************************** -* IContextMenu_CanRenameItems() -*/ -static BOOL IContextMenu_CanRenameItems(IContextMenuImpl *This) -{ UINT i; - DWORD dwAttributes; - - TRACE("(%p)->()\n",This); - - if(This->aPidls) - { - for(i = 0; This->aPidls[i]; i++){} /*get the number of items assigned to This object*/ - { if(i > 1) /*you can't rename more than one item at a time*/ - { return FALSE; - } - } - dwAttributes = SFGAO_CANRENAME; - IShellFolder_GetAttributesOf(This->pSFParent, i, (LPCITEMIDLIST*)This->aPidls, &dwAttributes); - - return dwAttributes & SFGAO_CANRENAME; - } - return FALSE; -} - -/************************************************************************** -* IContextMenu_Constructor() -*/ -IContextMenu *IContextMenu_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST pidl, LPCITEMIDLIST *aPidls, UINT uItemCount) -{ IContextMenuImpl* cm; - UINT u; - - cm = (IContextMenuImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IContextMenuImpl)); - ICOM_VTBL(cm)=&cmvt; - cm->ref = 1; - cm->pidl = ILClone(pidl); - - cm->pSFParent = pSFParent; - - if(pSFParent) - IShellFolder_AddRef(pSFParent); - - cm->aPidls = NULL; - - IContextMenu_AllocPidlTable(cm, uItemCount); - - if(cm->aPidls) - { IContextMenu_FillPidlTable(cm, aPidls, uItemCount); - } - - cm->bAllValues = 1; - for(u = 0; u < uItemCount; u++) - { cm->bAllValues &= (_ILIsValue(aPidls[u]) ? 1 : 0); - } - TRACE("(%p)->()\n",cm); - shell32_ObjCount++; - return (IContextMenu*)cm; -} - -/************************************************************************** -* IContextMenu_fnQueryInterface -*/ -static HRESULT WINAPI IContextMenu_fnQueryInterface(IContextMenu *iface, REFIID riid, LPVOID *ppvObj) -{ - ICOM_THIS(IContextMenuImpl, 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) - { - IContextMenu_AddRef((IContextMenu*)*ppvObj); - TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj); - return S_OK; - } - TRACE("-- Interface: E_NOINTERFACE\n"); - return E_NOINTERFACE; -} - -/************************************************************************** -* IContextMenu_fnAddRef -*/ -static ULONG WINAPI IContextMenu_fnAddRef(IContextMenu *iface) -{ - ICOM_THIS(IContextMenuImpl, iface); - - TRACE("(%p)->(count=%lu)\n",This, This->ref); - - shell32_ObjCount++; - return ++(This->ref); -} - -/************************************************************************** -* IContextMenu_fnRelease -*/ -static ULONG WINAPI IContextMenu_fnRelease(IContextMenu *iface) -{ - ICOM_THIS(IContextMenuImpl, iface); - - TRACE("(%p)->()\n",This); - - shell32_ObjCount--; - - if (!--(This->ref)) - { TRACE(" destroying IContextMenu(%p)\n",This); - - if(This->pSFParent) - IShellFolder_Release(This->pSFParent); - - if(This->pidl) - SHFree(This->pidl); - - /*make sure the pidl is freed*/ - if(This->aPidls) - { IContextMenu_FreePidlTable(This); - } - - HeapFree(GetProcessHeap(),0,This); - return 0; - } - return This->ref; -} - -/************************************************************************** -* ICM_InsertItem() -*/ -void WINAPI _InsertMenuItem ( - HMENU hmenu, - UINT indexMenu, - BOOL fByPosition, - UINT wID, - UINT fType, - LPSTR dwTypeData, - UINT fState) -{ - MENUITEMINFOA mii; - - ZeroMemory(&mii, sizeof(mii)); - mii.cbSize = sizeof(mii); - if (fType == MFT_SEPARATOR) - { mii.fMask = MIIM_ID | MIIM_TYPE; - } - else - { mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; - mii.dwTypeData = dwTypeData; - mii.fState = fState; - } - mii.wID = wID; - mii.fType = fType; - InsertMenuItemA( hmenu, indexMenu, fByPosition, &mii); -} -/************************************************************************** -* IContextMenu_fnQueryContextMenu() -*/ - -static HRESULT WINAPI IContextMenu_fnQueryContextMenu( - IContextMenu *iface, - HMENU hmenu, - UINT indexMenu, - UINT idCmdFirst, - UINT idCmdLast, - UINT uFlags) -{ - ICOM_THIS(IContextMenuImpl, iface); - - BOOL fExplore ; - - TRACE("(%p)->(hmenu=%x indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",This, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags); - - if(!(CMF_DEFAULTONLY & uFlags)) - { if(!This->bAllValues) - { /* folder menu */ - fExplore = uFlags & CMF_EXPLORE; - if(fExplore) - { _InsertMenuItem(hmenu, indexMenu++, TRUE, idCmdFirst+IDM_EXPLORE, MFT_STRING, "&Explore", MFS_ENABLED|MFS_DEFAULT); - _InsertMenuItem(hmenu, indexMenu++, TRUE, idCmdFirst+IDM_OPEN, MFT_STRING, "&Open", MFS_ENABLED); - } - else - { _InsertMenuItem(hmenu, indexMenu++, TRUE, idCmdFirst+IDM_OPEN, MFT_STRING, "&Open", MFS_ENABLED|MFS_DEFAULT); - _InsertMenuItem(hmenu, indexMenu++, TRUE, idCmdFirst+IDM_EXPLORE, MFT_STRING, "&Explore", MFS_ENABLED); - } - - if(uFlags & CMF_CANRENAME) - { _InsertMenuItem(hmenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); - _InsertMenuItem(hmenu, indexMenu++, TRUE, idCmdFirst+IDM_RENAME, MFT_STRING, "&Rename", (IContextMenu_CanRenameItems(This) ? MFS_ENABLED : MFS_DISABLED)); - } - } - else /* file menu */ - { _InsertMenuItem(hmenu, indexMenu++, TRUE, idCmdFirst+IDM_OPEN, MFT_STRING, "&Open", MFS_ENABLED|MFS_DEFAULT); - if(uFlags & CMF_CANRENAME) - { _InsertMenuItem(hmenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); - _InsertMenuItem(hmenu, indexMenu++, TRUE, idCmdFirst+IDM_RENAME, MFT_STRING, "&Rename", (IContextMenu_CanRenameItems(This) ? MFS_ENABLED : MFS_DISABLED)); - } - } - return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (IDM_LAST + 1)); - } - return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0); -} - -/************************************************************************** -* IContextMenu_fnInvokeCommand() -*/ -static HRESULT WINAPI IContextMenu_fnInvokeCommand( - IContextMenu *iface, - LPCMINVOKECOMMANDINFO lpcmi) -{ - ICOM_THIS(IContextMenuImpl, iface); - - LPITEMIDLIST pidlFQ; - SHELLEXECUTEINFOA sei; - int i; - - TRACE("(%p)->(invcom=%p verb=%p wnd=%x)\n",This,lpcmi,lpcmi->lpVerb, lpcmi->hwnd); - - if(LOWORD(lpcmi->lpVerb) > IDM_LAST) - return E_INVALIDARG; - - switch(LOWORD(lpcmi->lpVerb)) - { case IDM_EXPLORE: - case IDM_OPEN: - /* Find the first item in the list that is not a value. These commands - should never be invoked if there isn't at least one folder item in the list.*/ - - for(i = 0; This->aPidls[i]; i++) - { if(!_ILIsValue(This->aPidls[i])) - break; - } - - pidlFQ = ILCombine(This->pidl, This->aPidls[i]); - - ZeroMemory(&sei, sizeof(sei)); - sei.cbSize = sizeof(sei); - sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME; - sei.lpIDList = pidlFQ; - sei.lpClass = "folder"; - sei.hwnd = lpcmi->hwnd; - sei.nShow = SW_SHOWNORMAL; - - if(LOWORD(lpcmi->lpVerb) == IDM_EXPLORE) - { sei.lpVerb = "explore"; - } - else - { sei.lpVerb = "open"; - } - ShellExecuteExA(&sei); - SHFree(pidlFQ); - break; - - case IDM_RENAME: - MessageBeep(MB_OK); - /*handle rename for the view here*/ - break; - } - return NOERROR; -} - -/************************************************************************** -* IContextMenu_fnGetCommandString() -*/ -static HRESULT WINAPI IContextMenu_fnGetCommandString( - IContextMenu *iface, - UINT idCommand, - UINT uFlags, - LPUINT lpReserved, - LPSTR lpszName, - UINT uMaxNameLen) -{ - ICOM_THIS(IContextMenuImpl, iface); - - HRESULT hr = E_INVALIDARG; - - TRACE("(%p)->(idcom=%x flags=%x %p name=%p len=%x)\n",This, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen); - - switch(uFlags) - { case GCS_HELPTEXT: - hr = E_NOTIMPL; - break; - - case GCS_VERBA: - switch(idCommand) - { case IDM_RENAME: - strcpy((LPSTR)lpszName, "rename"); - hr = NOERROR; - break; - } - break; - - /* NT 4.0 with IE 3.0x or no IE will always call This with GCS_VERBW. In This - case, you need to do the lstrcpyW to the pointer passed.*/ - case GCS_VERBW: - switch(idCommand) - { case IDM_RENAME: - lstrcpyAtoW((LPWSTR)lpszName, "rename"); - hr = NOERROR; - break; - } - break; - - case GCS_VALIDATE: - hr = NOERROR; - break; - } - TRACE("-- (%p)->(name=%s)\n",This, lpszName); - return hr; -} - -/************************************************************************** -* IContextMenu_fnHandleMenuMsg() -* NOTES -* should be only in IContextMenu2 and IContextMenu3 -* is nevertheless called from word95 -*/ -static HRESULT WINAPI IContextMenu_fnHandleMenuMsg( - IContextMenu *iface, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - ICOM_THIS(IContextMenuImpl, iface); - - TRACE("(%p)->(msg=%x wp=%x lp=%lx)\n",This, uMsg, wParam, lParam); - - return E_NOTIMPL; -} - diff --git a/dlls/shell32/shv_item_cmenu.c b/dlls/shell32/shv_item_cmenu.c new file mode 100644 index 00000000000..c79cc2b2e35 --- /dev/null +++ b/dlls/shell32/shv_item_cmenu.c @@ -0,0 +1,543 @@ +/* + * IContextMenu for items in the shellview + * + * 1998, 2000 Juergen Schmied + */ +#include + +#include "winerror.h" +#include "debugtools.h" + +#include "pidl.h" +#include "wine/obj_base.h" +#include "wine/obj_contextmenu.h" +#include "wine/obj_shellbrowser.h" +#include "wine/obj_shellextinit.h" +#include "wine/undocshell.h" + +#include "shell32_main.h" +#include "shellfolder.h" +#include "shell.h" /* DROPFILESTRUCT */ + +DEFAULT_DEBUG_CHANNEL(shell) + +/************************************************************************** +* IContextMenu Implementation +*/ +typedef struct +{ ICOM_VFIELD(IContextMenu); + DWORD ref; + IShellFolder* pSFParent; + LPITEMIDLIST pidl; /* root pidl */ + LPITEMIDLIST *apidl; /* array of child pidls */ + UINT cidl; + BOOL bAllValues; +} ItemCmImpl; + + +static struct ICOM_VTABLE(IContextMenu) cmvt; + +/************************************************************************** +* ISvItemCm_CanRenameItems() +*/ +static BOOL ISvItemCm_CanRenameItems(ItemCmImpl *This) +{ UINT i; + DWORD dwAttributes; + + TRACE("(%p)->()\n",This); + + if(This->apidl) + { + for(i = 0; i < This->cidl; i++){} + if(i > 1) return FALSE; /* can't rename more than one item at a time*/ + dwAttributes = SFGAO_CANRENAME; + IShellFolder_GetAttributesOf(This->pSFParent, 1, This->apidl, &dwAttributes); + return dwAttributes & SFGAO_CANRENAME; + } + return FALSE; +} + +/************************************************************************** +* ISvItemCm_Constructor() +*/ +IContextMenu *ISvItemCm_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST pidl, LPCITEMIDLIST *apidl, UINT cidl) +{ ItemCmImpl* cm; + UINT u; + + cm = (ItemCmImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ItemCmImpl)); + ICOM_VTBL(cm)=&cmvt; + cm->ref = 1; + cm->pidl = ILClone(pidl); + cm->pSFParent = pSFParent; + + if(pSFParent) IShellFolder_AddRef(pSFParent); + + cm->apidl = _ILCopyaPidl(apidl, cidl); + cm->cidl = cidl; + + cm->bAllValues = 1; + for(u = 0; u < cidl; u++) + { + cm->bAllValues &= (_ILIsValue(apidl[u]) ? 1 : 0); + } + + TRACE("(%p)->()\n",cm); + + shell32_ObjCount++; + return (IContextMenu*)cm; +} + +/************************************************************************** +* ISvItemCm_fnQueryInterface +*/ +static HRESULT WINAPI ISvItemCm_fnQueryInterface(IContextMenu *iface, REFIID riid, LPVOID *ppvObj) +{ + ICOM_THIS(ItemCmImpl, 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; +} + +/************************************************************************** +* ISvItemCm_fnAddRef +*/ +static ULONG WINAPI ISvItemCm_fnAddRef(IContextMenu *iface) +{ + ICOM_THIS(ItemCmImpl, iface); + + TRACE("(%p)->(count=%lu)\n",This, This->ref); + + shell32_ObjCount++; + return ++(This->ref); +} + +/************************************************************************** +* ISvItemCm_fnRelease +*/ +static ULONG WINAPI ISvItemCm_fnRelease(IContextMenu *iface) +{ + ICOM_THIS(ItemCmImpl, iface); + + TRACE("(%p)->()\n",This); + + shell32_ObjCount--; + + if (!--(This->ref)) + { + TRACE(" destroying IContextMenu(%p)\n",This); + + if(This->pSFParent) + IShellFolder_Release(This->pSFParent); + + if(This->pidl) + SHFree(This->pidl); + + /*make sure the pidl is freed*/ + _ILFreeaPidl(This->apidl, This->cidl); + + HeapFree(GetProcessHeap(),0,This); + return 0; + } + return This->ref; +} + +/************************************************************************** +* ICM_InsertItem() +*/ +void WINAPI _InsertMenuItem ( + HMENU hmenu, + UINT indexMenu, + BOOL fByPosition, + UINT wID, + UINT fType, + LPSTR dwTypeData, + UINT fState) +{ + MENUITEMINFOA mii; + + ZeroMemory(&mii, sizeof(mii)); + mii.cbSize = sizeof(mii); + if (fType == MFT_SEPARATOR) + { + mii.fMask = MIIM_ID | MIIM_TYPE; + } + else + { + mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE; + mii.dwTypeData = dwTypeData; + mii.fState = fState; + } + mii.wID = wID; + mii.fType = fType; + InsertMenuItemA( hmenu, indexMenu, fByPosition, &mii); +} +/************************************************************************** +* ISvItemCm_fnQueryContextMenu() +*/ + +static HRESULT WINAPI ISvItemCm_fnQueryContextMenu( + IContextMenu *iface, + HMENU hmenu, + UINT indexMenu, + UINT idCmdFirst, + UINT idCmdLast, + UINT uFlags) +{ + ICOM_THIS(ItemCmImpl, iface); + + TRACE("(%p)->(hmenu=%x indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",This, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags); + + if(!(CMF_DEFAULTONLY & uFlags)) + { + if(uFlags & CMF_EXPLORE) + { + if(This->bAllValues) + { + _InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_OPEN, MFT_STRING, "&Open", MFS_ENABLED); + _InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_EXPLORE, MFT_STRING, "&Explore", MFS_ENABLED|MFS_DEFAULT); + } + else + { + _InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_EXPLORE, MFT_STRING, "&Explore", MFS_ENABLED|MFS_DEFAULT); + _InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_OPEN, MFT_STRING, "&Open", MFS_ENABLED); + } + } + else + { + _InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_OPEN, MFT_STRING, "&Select", MFS_ENABLED|MFS_DEFAULT); + } + _InsertMenuItem(hmenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); + _InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_COPY, MFT_STRING, "&Copy", MFS_ENABLED); + _InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_CUT, MFT_STRING, "&Cut", MFS_ENABLED); + + _InsertMenuItem(hmenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0); + _InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_DELETE, MFT_STRING, "&Delete", MFS_ENABLED); + + if(uFlags & CMF_CANRENAME) + _InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_RENAME, MFT_STRING, "&Rename", ISvItemCm_CanRenameItems(This) ? MFS_ENABLED : MFS_DISABLED); + + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (FCIDM_SHVIEWLAST)); + } + return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0); +} + +/************************************************************************** +* DoOpenExplore +* +* for folders only +*/ + +static void DoOpenExplore( + IContextMenu *iface, + HWND hwnd, + LPCSTR verb) +{ + ICOM_THIS(ItemCmImpl, iface); + + int i, bFolderFound = FALSE; + LPITEMIDLIST pidlFQ; + SHELLEXECUTEINFOA sei; + + /* Find the first item in the list that is not a value. These commands + should never be invoked if there isn't at least one folder item in the list.*/ + + for(i = 0; icidl; i++) + { + if(!_ILIsValue(This->apidl[i])) + { + bFolderFound = TRUE; + break; + } + } + + if (!bFolderFound) return; + + pidlFQ = ILCombine(This->pidl, This->apidl[i]); + + ZeroMemory(&sei, sizeof(sei)); + sei.cbSize = sizeof(sei); + sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME; + sei.lpIDList = pidlFQ; + sei.lpClass = "folder"; + sei.hwnd = hwnd; + sei.nShow = SW_SHOWNORMAL; + sei.lpVerb = verb; + ShellExecuteExA(&sei); + SHFree(pidlFQ); +} + +/************************************************************************** +* DoRename +*/ +static void DoRename( + IContextMenu *iface, + HWND hwnd) +{ + ICOM_THIS(ItemCmImpl, iface); + + LPSHELLBROWSER lpSB; + LPSHELLVIEW lpSV; + + TRACE("(%p)->(wnd=%x)\n",This, hwnd); + + /* get the active IShellView */ + if ((lpSB = (LPSHELLBROWSER)SendMessageA(hwnd, CWM_GETISHELLBROWSER,0,0))) + { + if(SUCCEEDED(IShellBrowser_QueryActiveShellView(lpSB, &lpSV))) + { + TRACE("(sv=%p)\n",lpSV); + IShellView_EditItem(lpSV, This->apidl[0]); + IShellView_Release(lpSV); + } + } +} + +/************************************************************************** + * DoDelete + * + * deletes the currently selected items + */ +static void DoDelete( + IContextMenu *iface, + IShellView *psv) +{ + ICOM_THIS(ItemCmImpl, iface); + ISFHelper * psfhlp; + + IShellFolder_QueryInterface(This->pSFParent, &IID_ISFHelper, (LPVOID*)&psfhlp); + if (psfhlp) + { + ISFHelper_DeleteItems(psfhlp, This->cidl, This->apidl); + if(psv) + IShellView_Refresh(psv); /* fixme: so long we dont have SHChangeNotify */ + ISFHelper_Release(psfhlp); + } +} + +/************************************************************************** + * DoCopyOrCut + * + * copys the currently selected items into the clipboard + */ +static BOOL DoCopyOrCut( + IContextMenu *iface, + HWND hwnd, + BOOL bCut) +{ + ICOM_THIS(ItemCmImpl, iface); + + LPSHELLBROWSER lpSB; + LPSHELLVIEW lpSV; + LPDATAOBJECT lpDo; + + TRACE("(%p)->(wnd=0x%04x,bCut=0x%08x)\n",This, hwnd, bCut); + + if(GetShellOle()) + { + /* get the active IShellView */ + if ((lpSB = (LPSHELLBROWSER)SendMessageA(hwnd, CWM_GETISHELLBROWSER,0,0))) + { + if (SUCCEEDED(IShellBrowser_QueryActiveShellView(lpSB, &lpSV))) + { + if (SUCCEEDED(IShellView_GetItemObject(lpSV, SVGIO_SELECTION, &IID_IDataObject, (LPVOID*)&lpDo))) + { + pOleSetClipboard(lpDo); + IDataObject_Release(lpDo); + } + IShellView_Release(lpSV); + } + } + } + return TRUE; +#if 0 +/* + the following code does the copy operation witout ole32.dll + we might need this possibility too (js) +*/ + BOOL bSuccess = FALSE; + + TRACE("(%p)\n", iface); + + if(OpenClipboard(NULL)) + { + if(EmptyClipboard()) + { + IPersistFolder2 * ppf2; + IShellFolder_QueryInterface(This->pSFParent, &IID_IPersistFolder2, (LPVOID*)&ppf2); + if (ppf2) + { + LPITEMIDLIST pidl; + IPersistFolder2_GetCurFolder(ppf2, &pidl); + if(pidl) + { + HGLOBAL hMem; + + hMem = RenderHDROP(pidl, This->apidl, This->cidl); + + if(SetClipboardData(CF_HDROP, hMem)) + { + bSuccess = TRUE; + } + SHFree(pidl); + } + IPersistFolder2_Release(ppf2); + } + + } + CloseClipboard(); + } + return bSuccess; +#endif +} +/************************************************************************** +* ISvItemCm_fnInvokeCommand() +*/ +static HRESULT WINAPI ISvItemCm_fnInvokeCommand( + IContextMenu *iface, + LPCMINVOKECOMMANDINFO lpcmi) +{ + ICOM_THIS(ItemCmImpl, iface); + + LPSHELLBROWSER lpSB; + LPSHELLVIEW lpSV = NULL; + + TRACE("(%p)->(invcom=%p verb=%p wnd=%x)\n",This,lpcmi,lpcmi->lpVerb, lpcmi->hwnd); + + /* get the active IShellView */ + lpSB = (LPSHELLBROWSER)SendMessageA(lpcmi->hwnd, CWM_GETISHELLBROWSER,0,0); + + /* we are not in a ShellView every time */ + if (lpSB) IShellBrowser_QueryActiveShellView(lpSB, &lpSV); + + if(LOWORD(lpcmi->lpVerb) > FCIDM_SHVIEWLAST) return E_INVALIDARG; + + switch(LOWORD(lpcmi->lpVerb)) + { + case FCIDM_SHVIEW_EXPLORE: + DoOpenExplore(iface, lpcmi->hwnd, "explore"); + break; + case FCIDM_SHVIEW_OPEN: + DoOpenExplore(iface, lpcmi->hwnd, "open"); + break; + case FCIDM_SHVIEW_RENAME: + DoRename(iface, lpcmi->hwnd); + break; + case FCIDM_SHVIEW_DELETE: + DoDelete(iface, lpSV); + break; + case FCIDM_SHVIEW_COPY: + DoCopyOrCut(iface, lpcmi->hwnd, FALSE); + break; + case FCIDM_SHVIEW_CUT: + DoCopyOrCut(iface, lpcmi->hwnd, TRUE); + break; + } + return NOERROR; +} + +/************************************************************************** +* ISvItemCm_fnGetCommandString() +*/ +static HRESULT WINAPI ISvItemCm_fnGetCommandString( + IContextMenu *iface, + UINT idCommand, + UINT uFlags, + LPUINT lpReserved, + LPSTR lpszName, + UINT uMaxNameLen) +{ + ICOM_THIS(ItemCmImpl, iface); + + HRESULT hr = E_INVALIDARG; + + TRACE("(%p)->(idcom=%x flags=%x %p name=%p len=%x)\n",This, idCommand, uFlags, lpReserved, lpszName, uMaxNameLen); + + switch(uFlags) + { + case GCS_HELPTEXT: + hr = E_NOTIMPL; + break; + + case GCS_VERBA: + switch(idCommand) + { + case FCIDM_SHVIEW_RENAME: + strcpy((LPSTR)lpszName, "rename"); + hr = NOERROR; + break; + } + break; + + /* NT 4.0 with IE 3.0x or no IE will always call This with GCS_VERBW. In This + case, you need to do the lstrcpyW to the pointer passed.*/ + case GCS_VERBW: + switch(idCommand) + { case FCIDM_SHVIEW_RENAME: + lstrcpyAtoW((LPWSTR)lpszName, "rename"); + hr = NOERROR; + break; + } + break; + + case GCS_VALIDATE: + hr = NOERROR; + break; + } + TRACE("-- (%p)->(name=%s)\n",This, lpszName); + return hr; +} + +/************************************************************************** +* ISvItemCm_fnHandleMenuMsg() +* NOTES +* should be only in IContextMenu2 and IContextMenu3 +* is nevertheless called from word95 +*/ +static HRESULT WINAPI ISvItemCm_fnHandleMenuMsg( + IContextMenu *iface, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + ICOM_THIS(ItemCmImpl, iface); + + TRACE("(%p)->(msg=%x wp=%x lp=%lx)\n",This, uMsg, wParam, lParam); + + return E_NOTIMPL; +} + +static struct ICOM_VTABLE(IContextMenu) cmvt = +{ + ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE + ISvItemCm_fnQueryInterface, + ISvItemCm_fnAddRef, + ISvItemCm_fnRelease, + ISvItemCm_fnQueryContextMenu, + ISvItemCm_fnInvokeCommand, + ISvItemCm_fnGetCommandString, + ISvItemCm_fnHandleMenuMsg, + (void *) 0xdeadbabe /* just paranoia */ +}; diff --git a/include/wine/obj_contextmenu.h b/include/wine/obj_contextmenu.h index c4e79182bbd..3d9a390de9c 100644 --- a/include/wine/obj_contextmenu.h +++ b/include/wine/obj_contextmenu.h @@ -17,12 +17,6 @@ DEFINE_SHLGUID(IID_IContextMenu, 0x000214E4L, 0, 0); DEFINE_SHLGUID(IID_IContextMenu2, 0x000214F4L, 0, 0); typedef struct IContextMenu IContextMenu, *LPCONTEXTMENU; -/* default menu items*/ -#define IDM_EXPLORE 0 -#define IDM_OPEN 1 -#define IDM_RENAME 2 -#define IDM_LAST IDM_RENAME - /* QueryContextMenu uFlags */ #define CMF_NORMAL 0x00000000 #define CMF_DEFAULTONLY 0x00000001 diff --git a/include/wine/obj_shellview.h b/include/wine/obj_shellview.h index 7c2878b220c..3a0ca45ee93 100644 --- a/include/wine/obj_shellview.h +++ b/include/wine/obj_shellview.h @@ -62,14 +62,25 @@ typedef struct IShellView IShellView, *LPSHELLVIEW; #define FCIDM_SHVIEW_UNDO 0x701B #define FCIDM_SHVIEW_INSERTLINK 0x701C #define FCIDM_SHVIEW_SELECTALL 0x7021 -#define FCIDM_SHVIEW_INVERTSELECTION 0x7022 +#define FCIDM_SHVIEW_INVERTSELECTION 0x7022 + #define FCIDM_SHVIEW_BIGICON 0x7029 #define FCIDM_SHVIEW_SMALLICON 0x702A #define FCIDM_SHVIEW_LISTVIEW 0x702B #define FCIDM_SHVIEW_REPORTVIEW 0x702C -#define FCIDM_SHVIEW_AUTOARRANGE 0x7031 +/* 0x7030-0x703f are used by the shellbrowser */ +#define FCIDM_SHVIEW_AUTOARRANGE 0x7031 #define FCIDM_SHVIEW_SNAPTOGRID 0x7032 + #define FCIDM_SHVIEW_HELP 0x7041 +#define FCIDM_SHVIEW_RENAME 0x7050 +#define FCIDM_SHVIEW_CREATELINK 0x7051 +#define FCIDM_SHVIEW_NEWLINK 0x7052 +#define FCIDM_SHVIEW_NEWFOLDER 0x7053 + +#define FCIDM_SHVIEW_REFRESH 0x7100 /* fixme */ +#define FCIDM_SHVIEW_EXPLORE 0x7101 /* fixme */ +#define FCIDM_SHVIEW_OPEN 0x7102 /* fixme */ #define FCIDM_SHVIEWLAST 0x7fff #define FCIDM_BROWSERFIRST 0xA000 @@ -121,7 +132,8 @@ typedef enum ICOM_METHOD3(HRESULT, AddPropertySheetPages, DWORD, dwReserved, LPFNADDPROPSHEETPAGE, lpfn, LPARAM, lparam) \ ICOM_METHOD (HRESULT, SaveViewState) \ ICOM_METHOD2(HRESULT, SelectItem, LPCITEMIDLIST, pidlItem, UINT, uFlags) \ - ICOM_METHOD3(HRESULT, GetItemObject, UINT, uItem, REFIID, riid, LPVOID*, ppv) + ICOM_METHOD3(HRESULT, GetItemObject, UINT, uItem, REFIID, riid, LPVOID*, ppv) \ + ICOM_METHOD1(HRESULT, EditItem, LPCITEMIDLIST, pidlItem) #define IShellView_IMETHODS \ IOleWindow_IMETHODS \ IShellView_METHODS @@ -146,6 +158,8 @@ ICOM_DEFINE(IShellView,IOleWindow) #define IShellView_SaveViewState(p) ICOM_CALL(SaveViewState,p) #define IShellView_SelectItem(p,a,b) ICOM_CALL2(SelectItem,p,a,b) #define IShellView_GetItemObject(p,a,b,c) ICOM_CALL3(GetItemObject,p,a,b,c) +/* WINE specific */ +#define IShellView_EditItem(p,a) ICOM_CALL1(EditItem,p,a) #ifdef __cplusplus } /* extern "C" */ diff --git a/include/wine/undocshell.h b/include/wine/undocshell.h index f7192a0e3e7..5b7f69b5ed4 100644 --- a/include/wine/undocshell.h +++ b/include/wine/undocshell.h @@ -29,9 +29,9 @@ BOOL WINAPI ILGetDisplayName(LPCITEMIDLIST pidl,LPSTR path); DWORD WINAPI ILFree(LPITEMIDLIST pidl); -LPITEMIDLIST WINAPI SHSimpleIDListFromPathA (LPSTR lpszPath); -LPITEMIDLIST WINAPI SHSimpleIDListFromPathW (LPWSTR lpszPath); -LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW (LPVOID lpszPath); +LPITEMIDLIST WINAPI SHSimpleIDListFromPathA (LPCSTR lpszPath); +LPITEMIDLIST WINAPI SHSimpleIDListFromPathW (LPCWSTR lpszPath); +LPITEMIDLIST WINAPI SHSimpleIDListFromPathAW (LPCVOID lpszPath); HRESULT WINAPI SHILCreateFromPathA (LPCSTR path, LPITEMIDLIST * ppidl, DWORD *attributes); HRESULT WINAPI SHILCreateFromPathW (LPCWSTR path, LPITEMIDLIST * ppidl, DWORD *attributes);