Article ID: 179911
Article Last Modified on 7/11/2005
178665 SAMPLE: RegView.exe: Shell Namespace Extension Example
#define IDM_EXPLORE 0
#define IDM_OPEN 1
#define IDM_LAST IDM_OPEN
STDMETHODIMP CContextMenu::QueryContextMenu( HMENU hMenu,
UINT indexMenu,
UINT idCmdFirst,
UINT idCmdLast,
UINT uFlags)
{
if(!(CMF_DEFAULTONLY & uFlags))
{
MENUITEMINFO mii;
if(uFlags & CMF_EXPLORE)
{
//add the Explore command first and make it the default item
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
mii.wID = idCmdFirst + IDM_EXPLORE;
mii.fType = MFT_STRING;
mii.dwTypeData = TEXT("&Explore");
mii.fState = MFS_ENABLED | MFS_DEFAULT;
InsertMenuItem( hMenu,
indexMenu++,
TRUE,
&mii);
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
mii.wID = idCmdFirst + IDM_OPEN;
mii.fType = MFT_STRING;
mii.dwTypeData = TEXT("&Open");
mii.fState = MFS_ENABLED;
InsertMenuItem( hMenu,
indexMenu++,
TRUE,
&mii);
}
else
{
//add the Open command first and make it the default item
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
mii.wID = idCmdFirst + IDM_OPEN;
mii.fType = MFT_STRING;
mii.dwTypeData = TEXT("&Open");
mii.fState = MFS_ENABLED | MFS_DEFAULT;
InsertMenuItem( hMenu,
indexMenu++,
TRUE,
&mii);
ZeroMemory(&mii, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
mii.wID = idCmdFirst + IDM_EXPLORE;
mii.fType = MFT_STRING;
mii.dwTypeData = TEXT("&Explore");
mii.fState = MFS_ENABLED;
InsertMenuItem( hMenu,
indexMenu++,
TRUE,
&mii);
}
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(IDM_LAST + 1));
}
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, USHORT(0));
}
To determine if your shell view is being displayed in Open or Explore mode,
use the IShellBrowser::GetControlWindow method passing FCW_TREE. If this
method returns NULL, then the view is in Open mode. If this method returns
a non-NULL value, then the view is in Explore mode. When the view needs to
display a context menu for an item, it can then obtain the IContextMenu
object using its parent's IShellFolder::GetUIObjectOf and then call the
IContextMenu object's QueryContextMenu method. If the tree is present, the
view should add the CMF_EXPLORE flag in the QueryContextMenu call.
#define MENU_OFFSET 1
#define MENU_MAX 100
HMENU CShellView::GetContextMenuForItems( UINT uItems,
LPITEMIDLIST *aItems)
{
HMENU hMenu;
if(aItems)
{
LPCONTEXTMENU pContextMenu = NULL;
m_pSFParent->GetUIObjectOf( m_hwndParent,
uItems,
(LPCITEMIDLIST*)aItems,
IID_IContextMenu,
NULL,
(LPVOID*)&pContextMenu);
if(pContextMenu)
{
HMENU hMenu = CreatePopupMenu();
/*
See if we are in Explore or Open mode. If the browser's tree is
present, then we are in Explore mode.
*/
BOOL fExplore = FALSE;
HWND hwndTree = NULL;
if(SUCCEEDED(m_pShellBrowser->GetControlWindow(FCW_TREE,
&hwndTree)) && hwndTree)
{
fExplore = TRUE;
}
if(hMenu && SUCCEEDED(pContextMenu->QueryContextMenu( hMenu,
0,
MENU_OFFSET,
MENU_MAX,
CMF_NORMAL | (fExplore ? CMF_EXPLORE : 0))))
{
}
else
{
DestroyMenu(hMenu);
hMenu = NULL;
}
}
}
return hMenu;
}
When the user selects an item in the menu, your IContextMenu::InvokeCommand
will be called. If the command identifier is your Explore or Open command,
then you should use ShellExecuteEx to Open or Explore the folder. To use
ShellexecuteEx to Open or Explore the folder, you need to do the following:
STDMETHODIMP CContextMenu::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
{
if(HIWORD(lpcmi->lpVerb))
{
//the command is being sent via a verb
return NOERROR;
}
if(LOWORD(lpcmi->lpVerb) > IDM_LAST)
return E_INVALIDARG;
switch(LOWORD(lpcmi->lpVerb))
{
case IDM_EXPLORE:
case IDM_OPEN:
{
LPITEMIDLIST pidlFQ;
SHELLEXECUTEINFO sei;
/*
Only one PIDL can be passed to ShellExecuteEx, so default to the
first one in the list.
*/
pidlFQ = CreateFullyQualifiedPidl(m_aPidls[0]);
ZeroMemory(&sei, sizeof(sei));
sei.cbSize = sizeof(sei);
sei.fMask = SEE_MASK_IDLIST | SEE_MASK_CLASSNAME;
sei.lpIDList = pidlFQ;
sei.lpClass = TEXT("folder");
sei.hwnd = lpcmi->hwnd;
sei.nShow = SW_SHOWNORMAL;
if(LOWORD(lpcmi->lpVerb) == IDM_EXPLORE)
sei.lpVerb = TEXT("explore");
else
sei.lpVerb = TEXT("open");
ShellExecuteEx(&sei);
DeletePidl(pidlFQ);
}
break;
}
return NOERROR;
}
These steps allow your namespace extension to properly implement the
Explore and Open commands from a context menu.
178665 SAMPLE: RegView.exe: Shell Namespace Extension Example
Keywords: kbhowto kbextension kbnamespace KB179911