📄 shv_item_cmenu.c
字号:
/*
* IContextMenu for items in the shellview
*
* Copyright 1998, 2000 Juergen Schmied <juergen.schmied@debitel.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <string.h>
#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "winerror.h"
#include "wine/debug.h"
#include "windef.h"
#include "wingdi.h"
#include "pidl.h"
#include "shlguid.h"
#include "undocshell.h"
#include "shlobj.h"
#include "shell32_main.h"
#include "shellfolder.h"
WINE_DEFAULT_DEBUG_CHANNEL(shell);
/* ugly hack for cut&psate files */
BOOL fileMoving = FALSE;
/**************************************************************************
* IContextMenu Implementation
*/
typedef struct
{ const IContextMenu2Vtbl *lpVtbl;
LONG ref;
IShellFolder* pSFParent;
LPITEMIDLIST pidl; /* root pidl */
LPITEMIDLIST *apidl; /* array of child pidls */
UINT cidl;
BOOL bAllValues;
} ItemCmImpl;
static const IContextMenu2Vtbl 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, (LPCITEMIDLIST*)This->apidl, &dwAttributes);
return dwAttributes & SFGAO_CANRENAME;
}
return FALSE;
}
/**************************************************************************
* ISvItemCm_Constructor()
*/
IContextMenu2 *ISvItemCm_Constructor(LPSHELLFOLDER pSFParent, LPCITEMIDLIST pidl, LPCITEMIDLIST *apidl, UINT cidl)
{ ItemCmImpl* cm;
UINT u;
cm = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ItemCmImpl));
cm->lpVtbl = &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);
return (IContextMenu2*)cm;
}
/**************************************************************************
* ISvItemCm_fnQueryInterface
*/
static HRESULT WINAPI ISvItemCm_fnQueryInterface(IContextMenu2 *iface, REFIID riid, LPVOID *ppvObj)
{
ItemCmImpl *This = (ItemCmImpl *)iface;
TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),ppvObj);
*ppvObj = NULL;
if(IsEqualIID(riid, &IID_IUnknown) ||
IsEqualIID(riid, &IID_IContextMenu) ||
IsEqualIID(riid, &IID_IContextMenu2))
{
*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(IContextMenu2 *iface)
{
ItemCmImpl *This = (ItemCmImpl *)iface;
ULONG refCount = InterlockedIncrement(&This->ref);
TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
return refCount;
}
/**************************************************************************
* ISvItemCm_fnRelease
*/
static ULONG WINAPI ISvItemCm_fnRelease(IContextMenu2 *iface)
{
ItemCmImpl *This = (ItemCmImpl *)iface;
ULONG refCount = InterlockedDecrement(&This->ref);
TRACE("(%p)->(count=%li)\n", This, refCount + 1);
if (!refCount)
{
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 refCount;
}
/**************************************************************************
* ICM_InsertItem()
*/
void WINAPI _InsertMenuItem (
HMENU hmenu,
UINT indexMenu,
BOOL fByPosition,
UINT wID,
UINT fType,
LPCSTR 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 = (LPSTR) dwTypeData;
mii.fState = fState;
}
mii.wID = wID;
mii.fType = fType;
InsertMenuItemA( hmenu, indexMenu, fByPosition, &mii);
}
/**************************************************************************
* ISvItemCm_fnQueryContextMenu()
* FIXME: load menu MENU_SHV_FILE out of resources instead if creating
* each menu item by calling _InsertMenuItem()
*/
static HRESULT WINAPI ISvItemCm_fnQueryContextMenu(
IContextMenu2 *iface,
HMENU hmenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
ItemCmImpl *This = (ItemCmImpl *)iface;
TRACE("(%p)->(hmenu=%p indexmenu=%x cmdfirst=%x cmdlast=%x flags=%x )\n",This, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
if (idCmdFirst != 0)
FIXME("We should use idCmdFirst=%d and idCmdLast=%d for command ids\n", idCmdFirst, idCmdLast);
if(!(CMF_DEFAULTONLY & uFlags) && This->cidl>0)
{
if(!(uFlags & CMF_EXPLORE))
_InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_OPEN, MFT_STRING, "&Select", MFS_ENABLED);
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);
}
else
{
_InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_EXPLORE, MFT_STRING, "&Explore", MFS_ENABLED);
_InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_OPEN, MFT_STRING, "&Open", MFS_ENABLED);
}
SetMenuDefaultItem(hmenu, 0, MF_BYPOSITION);
_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);
}
_InsertMenuItem(hmenu, indexMenu++, TRUE, 0, MFT_SEPARATOR, NULL, 0);
_InsertMenuItem(hmenu, indexMenu++, TRUE, FCIDM_SHVIEW_PROPERTIES, MFT_STRING, "&Properties::", MFS_ENABLED);
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, (FCIDM_SHVIEWLAST));
}
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0);
}
/**************************************************************************
* DoOpenExplore
*
* for folders only
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -