📄 contextmenu.cpp
字号:
//
// ContextMenu.cpp
//
#include <Windows.h>
#include <shlobj.h>
#include "ContextMenu.h"
#include "ShellFolder.h"
#include "resource.h"
// Some #defines for example implemenation
#define ID_ADDLOCALDRIVE 0x0001
#define ID_DELLOCALDRIVE 0x0002
#define SZ_ADDLOCALDRIVE TEXT("&Add Local Drive")
#define SZ_DELLOCALDRIVE TEXT("&Remove Local Drive")
#define SZ_ADDLOCALDRIVE_HELP TEXT("Add a local drive to show")
#define SZ_DELLOCALDRIVE_HELP TEXT("Remove a local drive to show")
/////////////////////////////////////////////////////////////////////////////
// CContextMenu member functions
extern HINSTANCE g_hInstance;
extern UINT g_uiRefThisDll;
CContextMenu::CContextMenu(CShellFolder *pSF,
UINT uiCount, LPCITEMIDLIST *aPidls)
{
g_uiRefThisDll++;
m_uiRef = 1;
SHGetMalloc(&m_pMalloc);
m_pPidlMgr = new CPidlMgr;
m_pSF = pSF;
if (m_pSF)
{
m_pSF->AddRef();
}
m_uiCount = uiCount;
m_aPidls = NULL;
if (m_uiCount)
{
m_aPidls = (LPITEMIDLIST *) m_pMalloc->Alloc((m_uiCount+1)*sizeof(ITEMIDLIST));
ZeroMemory(m_aPidls, sizeof(LPITEMIDLIST)*(m_uiCount+1));
if(m_aPidls && m_pPidlMgr)
{
UINT i;
for(i = 0; i < m_uiCount; i++)
{
m_aPidls[i] = m_pPidlMgr->Copy(aPidls[i]);
}
}
}
}
CContextMenu::~CContextMenu()
{
g_uiRefThisDll--;
if (m_pSF)
{
m_pSF->Release();
}
if(m_aPidls && m_pPidlMgr)
{
UINT i;
for(i = 0; m_aPidls[i]; i++)
{
m_pPidlMgr->Delete(m_aPidls[i]);
}
m_pMalloc->Free(m_aPidls);
}
if(m_pPidlMgr)
{
delete m_pPidlMgr;
}
if(m_pMalloc)
{
m_pMalloc->Release();
}
}
///////////////////////////////////////////////////////////
// IUnknown implementation
//
STDMETHODIMP CContextMenu::QueryInterface (REFIID riid, LPVOID FAR *ppv)
{
if (IsEqualIID (riid, IID_IUnknown))
{
*ppv = this;
m_uiRef++;
return NOERROR;
}
else if (IsEqualIID (riid, IID_IShellExtInit))
{
*ppv = (LPSHELLEXTINIT) this;
m_uiRef++;
return NOERROR;
}
else if (IsEqualIID (riid, IID_IContextMenu))
{
*ppv = (IContextMenu*) this;
m_uiRef++;
return NOERROR;
}
else
{
*ppv = NULL;
return ResultFromScode (E_NOINTERFACE);
}
}
STDMETHODIMP_(ULONG) CContextMenu::AddRef ()
{
return ++m_uiRef;
}
STDMETHODIMP_(ULONG) CContextMenu::Release ()
{
if (--m_uiRef == 0)
delete this;
return m_uiRef;
}
///////////////////////////////////////////////////////////
// IShellExtInit implementation
//
STDMETHODIMP CContextMenu::Initialize (LPCITEMIDLIST pidlFolder,
LPDATAOBJECT lpdobj, HKEY hKeyProgID)
{
return NOERROR;
}
///////////////////////////////////////////////////////////
// IContextMenu methods
STDMETHODIMP CContextMenu::GetCommandString(UINT idCmd, UINT uFlags, UINT *pwReserved,
LPSTR pszName, UINT cchMax)
{
// TODO : Add extra code here
HRESULT hr = S_OK;
switch (idCmd)
{
case ID_ADDLOCALDRIVE:
strncpy(pszName, SZ_ADDLOCALDRIVE_HELP, cchMax);
break;
case ID_DELLOCALDRIVE:
strncpy(pszName, SZ_DELLOCALDRIVE_HELP, cchMax);
break;
default:
hr = E_NOTIMPL;
break;
}
return hr;
}
STDMETHODIMP CContextMenu::QueryContextMenu(HMENU hMenu, UINT uiIndexMenu, UINT idCmdFirst,
UINT idCmdLast, UINT uFlags)
{
// TODO : Add extra code here
int i = uiIndexMenu;
if (m_pSF == NULL) // RClick on our root
{
MENUITEMINFO mii = { 0 };
mii.fMask = MIIM_TYPE | MIIM_STATE;
mii.fType = MFT_SEPARATOR;
mii.dwTypeData = NULL;
mii.fState = MFS_ENABLED;
InsertMenuItem(hMenu, uiIndexMenu++, TRUE, &mii);
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
mii.wID = idCmdFirst + ID_ADDLOCALDRIVE;
mii.fType = MFT_STRING;
mii.dwTypeData = SZ_ADDLOCALDRIVE;
mii.fState = MFS_ENABLED;
InsertMenuItem(hMenu, uiIndexMenu++, TRUE, &mii);
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
mii.wID = idCmdFirst + ID_DELLOCALDRIVE;
mii.fType = MFT_STRING;
mii.dwTypeData = SZ_DELLOCALDRIVE;
mii.fState = MFS_ENABLED;
InsertMenuItem(hMenu, uiIndexMenu++, TRUE, &mii);
}
else
{
// We might have been called from our CShellView context menu handler
// TODO : Add extra code to deal with this situation here...
//
HMENU hMenuTemp = NULL;
if (m_aPidls)
{
hMenuTemp = ::LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_SHELLVIEW_POPUP));
}
else
{
hMenuTemp = ::LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_SHELLFOLDER_POPUP));
}
if (hMenuTemp == NULL)
{
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));
}
HMENU hShellViewMenu = ::GetSubMenu(hMenuTemp, 0);
if (hShellViewMenu == NULL)
{
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));
}
// iterate thro' the hEditMenu and add them to hMenu
int nMenuItems = ::GetMenuItemCount(hShellViewMenu);
if (nMenuItems > 0)
{
int nItem =0 ;
while (nItem < nMenuItems)
{
MENUITEMINFO mii = { 0 };
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_CHECKMARKS|MIIM_DATA|MIIM_ID|MIIM_STATE|MIIM_TYPE;//all
if (GetMenuItemInfo(hShellViewMenu, nItem, TRUE, &mii))
{
if (mii.fType == MFT_STRING)
{
TCHAR szMenuText[MAX_PATH];
GetMenuString(hShellViewMenu, nItem, szMenuText, MAX_PATH, MF_BYPOSITION);
MENUITEMINFO miiInsert = { 0 };
miiInsert.cbSize = sizeof(MENUITEMINFO);
miiInsert.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
miiInsert.fType = mii.fType;
miiInsert.fState = MFS_ENABLED;
miiInsert.dwTypeData= szMenuText;
miiInsert.wID = mii.wID;
InsertMenuItem(hMenu, uiIndexMenu++, FALSE, &miiInsert);
}
else if (mii.fType == MFT_SEPARATOR)
{
InsertMenuItem(hMenu, uiIndexMenu++, FALSE, &mii);
}
}
nItem++;
}
}
}
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(i-uiIndexMenu));
}
STDMETHODIMP CContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
{
// TODO : Add extra code here
HRESULT hr = S_OK;
switch(LOWORD(lpici->lpVerb))
{
case ID_ADDLOCALDRIVE:
// TODO : Add extra code here
::MessageBox(NULL,"Add Local Drive","Menu",MB_OK);
break;
case ID_DELLOCALDRIVE:
::MessageBox(NULL,"Del Local Drive","Menu",MB_OK);
break;
default:
hr = E_FAIL;
}
return hr;
}
//EOF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -