⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contextmenu.cpp

📁 Drive.dll is a dll that creates a drive to system directoryor drive similar to existing drives such
💻 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 + -