gpt4 book ai didi

c++ - 使用 C++ 在上下文菜单 shell 扩展中级联子菜单

转载 作者:行者123 更新时间:2023-11-28 07:46:24 25 4
gpt4 key购买 nike

您好,我正在尝试在 shell 扩展的上下文菜单中获取级联窗口。我在 .dll 扩展名的上下文菜单中添加了两个子菜单,但想创建一个级联子菜单(我喜欢打开第一个菜单,然后在点击里面的一些菜单后,想打开下一个子菜单)。

如何从这段代码中获取级联子菜单,我哪里出错了?

    // OpenWithCtxMenuExt.cpp : Implementation of COpenWithCtxMenuExt

#include "stdafx.h"
#include "OpenWithExt.h"
#include "OpenWithCtxMenuExt.h"

#pragma comment(lib,"shlwapi")

/////////////////////////////////////////////////////////////////////////////
// COpenWithCtxMenuExt

HRESULT COpenWithCtxMenuExt::Initialize ( LPCITEMIDLIST pidlFolder,
LPDATAOBJECT pDataObj,
HKEY hProgID )
{
FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
HDROP hDrop;

// Look for CF_HDROP data in the data object.
if ( FAILED( pDataObj->GetData ( &fmt, &stg )))
{
// Nope! Return an "invalid argument" error back to Explorer.
return E_INVALIDARG;
}

// Get a pointer to the actual data.
hDrop = (HDROP) GlobalLock ( stg.hGlobal );

// Make sure it worked.
if ( NULL == hDrop )
return E_INVALIDARG;

// Sanity check - make sure there is at least one filename.
UINT uNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 );

if ( 0 == uNumFiles )
{
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return E_INVALIDARG;
}

HRESULT hr = S_OK;

// Get the name of the first file and store it in our member variable m_szFile.
if ( 0 == DragQueryFile ( hDrop, 0, m_szSelectedFile, MAX_PATH ))
hr = E_INVALIDARG;
else
{
// Quote the name if it contains spaces (needed so the cmd line is built properly)
PathQuoteSpaces ( m_szSelectedFile );
}

GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );

return hr;
}

HRESULT COpenWithCtxMenuExt::QueryContextMenu ( HMENU hmenu, UINT uMenuIndex,
UINT uidFirstCmd, UINT uidLastCmd,
UINT uFlags )
{
// If the flags include CMF_DEFAULTONLY then we shouldn't do anything.
if ( uFlags & CMF_DEFAULTONLY )
return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 0 );

// First, create and populate a submenu.
HMENU hSubmenu = CreatePopupMenu();
HMENU hSubmenu1 = CreatePopupMenu();
UINT uID = uidFirstCmd;

InsertMenu ( hSubmenu, 0, MF_BYPOSITION, uID++, _T("&Notepad") );
InsertMenu ( hSubmenu, 1, MF_BYPOSITION, uID++, _T("&Internet Explorer") );
InsertMenu ( hSubmenu, 2, MF_BYPOSITION, uID++, _T("&Mspaint") );
InsertMenu ( hSubmenu, 3, MF_BYPOSITION, uID++, _T("&Pop") );

// provjeriti uID da se ne zbraja
InsertMenu ( hSubmenu1, 0, MF_BYPOSITION, uID++, _T("&Notepad") );
InsertMenu ( hSubmenu1, 1, MF_BYPOSITION, uID++, _T("&Mspaint") );


// Insert the submenu into the ctx menu provided by Explorer.
MENUITEMINFO mii = { sizeof(MENUITEMINFO) };

mii.fMask = MIIM_SUBMENU | /*MIIM_STRING*/ 0x00000040 | MIIM_ID;
mii.wID = uID++;
mii.hSubMenu = hSubmenu;
mii.dwTypeData = _T("C&P Open With");

InsertMenuItem ( hmenu, uMenuIndex, TRUE, &mii );

// Insert the submenu into the ctx menu provided by Explorer.
MENUITEMINFO mii1 = { sizeof(MENUITEMINFO) };

mii1.fMask = MIIM_SUBMENU | /*MIIM_STRING*/ 0x00000040 | MIIM_ID;
mii1.wID = uID++;
mii1.hSubMenu = hSubmenu;
mii1.dwTypeData = _T("C&P pod_folder");

InsertMenuItem ( hmenu, uMenuIndex, TRUE, &mii1 );

return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, uID - uidFirstCmd );
}

HRESULT COpenWithCtxMenuExt::GetCommandString ( UINT idCmd, UINT uFlags,
UINT* pwReserved, LPSTR pszName,
UINT cchMax )
{
USES_CONVERSION;

// Check idCmd, it must be 0 or 1 since we have two menu items.
if ( idCmd > 3 )
return E_INVALIDARG;

// If Explorer is asking for a help string, copy our string into the
// supplied buffer.
if ( uFlags & GCS_HELPTEXT )
{
LPCTSTR szNotepadText = _T("Open the selected file in Notepad");
LPCTSTR szIEText = _T("Open the selected file in Internet Explorer");
LPCTSTR szPintText = _T("Open the selected file with Mspaint");
LPCTSTR szPopText = _T("Popout");

LPCTSTR szNotepad1Text = _T("Open the selected file in Notepad");
LPCTSTR szPint1Text = _T("Open the selected file with Mspaint");

//LPCTSTR pszText = (0 == idCmd) ? szNotepadText : szIEText;
LPCTSTR pszText;
if(idCmd == 0){
pszText = szNotepadText;
}
if(idCmd == 1){
pszText = szIEText;
}
if(idCmd == 2){
pszText = szPintText;
}
if(idCmd == 3){
pszText = szPopText;
}
if(idCmd == 4){
pszText = szNotepad1Text;
}
if(idCmd == 5){
pszText = szPint1Text;
}

if ( uFlags & GCS_UNICODE )
{
// We need to cast pszName to a Unicode string, and then use the
// Unicode string copy API.
lstrcpynW ( (LPWSTR) pszName, T2CW(pszText), cchMax );
}
else
{
// Use the ANSI string copy API to return the help string.
lstrcpynA ( pszName, T2CA(pszText), cchMax );
}

return S_OK;
}

return E_INVALIDARG;
}

HRESULT COpenWithCtxMenuExt::InvokeCommand ( LPCMINVOKECOMMANDINFO pCmdInfo )
{
// If lpVerb really points to a string, ignore this function call and bail out.
if ( 0 != HIWORD( pCmdInfo->lpVerb ))
return E_INVALIDARG;

// Get the command index.
switch ( LOWORD( pCmdInfo->lpVerb ))
{
case 0:
{
ShellExecute ( pCmdInfo->hwnd, _T("open"), _T("notepad.exe"),
m_szSelectedFile, NULL, SW_SHOW );

return S_OK;
}
break;

case 1:
{
ShellExecute ( pCmdInfo->hwnd, _T("open"), _T("iexplore.exe"),
m_szSelectedFile, NULL, SW_SHOW );

return S_OK;
}
break;

case 2:
{
ShellExecute ( pCmdInfo->hwnd, _T("open"), _T("mspaint.exe"),
m_szSelectedFile, NULL, SW_SHOW );

return S_OK;
}
break;

case 3:
{
ShellExecute ( pCmdInfo->hwnd, _T("open"), _T("mspaint.exe"),
m_szSelectedFile, NULL, SW_SHOW );

return S_OK;
}
break;

case 4:
{
ShellExecute ( pCmdInfo->hwnd, _T("open"), _T("notepad.exe"),
m_szSelectedFile, NULL, SW_SHOW );

return S_OK;
}
break;

case 5:
{
ShellExecute ( pCmdInfo->hwnd, _T("open"), _T("mspaint.exe"),
m_szSelectedFile, NULL, SW_SHOW );

return S_OK;
}
break;

default:
return E_INVALIDARG;
break;
}
}

最佳答案

一段时间后找到了在现有上下文菜单中制作级联上下文菜单的解决方案...这里是代码:

    // OpenWithCtxMenuExt.cpp : Implementation of COpenWithCtxMenuExt

#include "stdafx.h"
#include "OpenWithExt.h"
#include "OpenWithCtxMenuExt.h"

#pragma comment(lib,"shlwapi")

/////////////////////////////////////////////////////////////////////////////
// COpenWithCtxMenuExt

HRESULT COpenWithCtxMenuExt::Initialize ( LPCITEMIDLIST pidlFolder,
LPDATAOBJECT pDataObj,
HKEY hProgID )
{
FORMATETC fmt = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
HDROP hDrop;

// Look for CF_HDROP data in the data object.
if ( FAILED( pDataObj->GetData ( &fmt, &stg )))
{
// Nope! Return an "invalid argument" error back to Explorer.
return E_INVALIDARG;
}

// Get a pointer to the actual data.
hDrop = (HDROP) GlobalLock ( stg.hGlobal );

// Make sure it worked.
if ( NULL == hDrop )
return E_INVALIDARG;

// Sanity check - make sure there is at least one filename.
UINT uNumFiles = DragQueryFile ( hDrop, 0xFFFFFFFF, NULL, 0 );

if ( 0 == uNumFiles )
{
GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );
return E_INVALIDARG;
}

HRESULT hr = S_OK;

// Get the name of the first file and store it in our member variable m_szFile.
if ( 0 == DragQueryFile ( hDrop, 0, m_szSelectedFile, MAX_PATH ))
hr = E_INVALIDARG;
else
{
// Quote the name if it contains spaces (needed so the cmd line is built properly)
PathQuoteSpaces ( m_szSelectedFile );
}

GlobalUnlock ( stg.hGlobal );
ReleaseStgMedium ( &stg );

return hr;
}

HRESULT COpenWithCtxMenuExt::QueryContextMenu ( HMENU hmenu, UINT uMenuIndex,
UINT uidFirstCmd, UINT uidLastCmd,
UINT uFlags )
{
// If the flags include CMF_DEFAULTONLY then we shouldn't do anything.
if ( uFlags & CMF_DEFAULTONLY )
return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, 0 );

// First, create and populate a submenu.
HMENU hSubmenu = CreatePopupMenu();
HMENU hSub = CreatePopupMenu();
UINT uID = uidFirstCmd;

InsertMenu ( hSubmenu, 0, MF_BYPOSITION, uID++, _T("&Notepad") );
InsertMenu ( hSubmenu, 1, MF_BYPOSITION, uID++, _T("&Internet Explorer") );
InsertMenu ( hSubmenu, 2, MF_BYPOSITION, uID++, _T("&Mspaint") );
InsertMenu ( hSubmenu, 3, MF_BYPOSITION, uID++, _T("&Pop") );

InsertMenu ( hSub, 4, MF_BYPOSITION, uID++, _T("&Case") );
InsertMenu ( hSub, 5, MF_BYPOSITION, uID++, _T("&Case") );

// Insert the submenu into the ctx menu provided by Explorer.
MENUITEMINFO mii = { sizeof(MENUITEMINFO) };

mii.fMask = MIIM_SUBMENU | /*MIIM_STRING*/ 0x00000040 | MIIM_ID;
mii.wID = uID++;
mii.hSubMenu = hSubmenu;
mii.dwTypeData = _T("Open With&x");

InsertMenuItem ( hmenu, uMenuIndex, TRUE, &mii );

mii.hSubMenu = hSub;
mii.dwTypeData = _T("Novi Subm&enu");

InsertMenuItem ( hSubmenu, uMenuIndex, TRUE, &mii );

return MAKE_HRESULT ( SEVERITY_SUCCESS, FACILITY_NULL, uID - uidFirstCmd );
}


HRESULT COpenWithCtxMenuExt::GetCommandString ( UINT idCmd, UINT uFlags,
UINT* pwReserved, LPSTR pszName,
UINT cchMax )
{
USES_CONVERSION;

// Check idCmd, it must be 0 or 1 since we have two menu items.
if ( idCmd > 4 )
return E_INVALIDARG;

// If Explorer is asking for a help string, copy our string into the
// supplied buffer.
if ( uFlags & GCS_HELPTEXT )
{
LPCTSTR szNotepadText = _T("Open the selected file in Notepad");
LPCTSTR szIEText = _T("Open the selected file in Internet Explorer");
LPCTSTR szPintText = _T("Open the selected file with Mspaint");
LPCTSTR szPopText = _T("Popout");
//LPCTSTR pszText = (0 == idCmd) ? szNotepadText : szIEText;
LPCTSTR pszText;
if(idCmd == 0){
pszText = szNotepadText;
}
if(idCmd == 1){
pszText = szIEText;
}
if(idCmd == 2){
pszText = szPintText;
}

if(idCmd == 3){
pszText = szPopText;
}

if(idCmd == 4){
pszText = szPopText;
}



if ( uFlags & GCS_UNICODE )
{
// We need to cast pszName to a Unicode string, and then use the
// Unicode string copy API.
lstrcpynW ( (LPWSTR) pszName, T2CW(pszText), cchMax );
}
else
{
// Use the ANSI string copy API to return the help string.
lstrcpynA ( pszName, T2CA(pszText), cchMax );
}

return S_OK;
}

return E_INVALIDARG;
}

HRESULT COpenWithCtxMenuExt::InvokeCommand ( LPCMINVOKECOMMANDINFO pCmdInfo )
{
// If lpVerb really points to a string, ignore this function call and bail out.
if ( 0 != HIWORD( pCmdInfo->lpVerb ))
return E_INVALIDARG;

// Get the command index.
switch ( LOWORD( pCmdInfo->lpVerb ))
{
case 0:
{
ShellExecute ( pCmdInfo->hwnd, _T("open"), _T("notepad.exe"),
m_szSelectedFile, NULL, SW_SHOW );

return S_OK;
}
break;

case 1:
{
ShellExecute ( pCmdInfo->hwnd, _T("open"), _T("iexplore.exe"),
m_szSelectedFile, NULL, SW_SHOW );

return S_OK;
}
break;

case 2:
{
ShellExecute ( pCmdInfo->hwnd, _T("open"), _T("mspaint.exe"),
m_szSelectedFile, NULL, SW_SHOW );

return S_OK;
}
break;

case 4:
{
MessageBox(0, "New command from sub menu", "Case 4", 0);
return S_OK;
}
break;

case 5:
{
MessageBox(0, "New second command from sub menu", "Case 5", 0);
return S_OK;
}
break;

default:
return E_INVALIDARG;
break;
}
}

关于c++ - 使用 C++ 在上下文菜单 shell 扩展中级联子菜单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14803059/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com