怎样获取系统右键菜单?

dx79 2001-02-12 03:08:00
急用 谢谢
...全文
534 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
dsc 2001-03-02
  • 打赏
  • 举报
回复
试试这个函数

BOOL CSyncBackupView::DoExplorerMenu(HWND hwnd, LPCTSTR pszPath, POINT point)
{
LPMALLOC pMalloc;
LPSHELLFOLDER psfFolder, psfNextFolder;
LPITEMIDLIST pidlMain, pidlItem, pidlNextItem, *ppidl;
LPCONTEXTMENU pContextMenu;
CMINVOKECOMMANDINFO ici;
ULONG ulCount, ulAttr;
TCHAR tchPath[MAX_PATH];
WCHAR wchPath[MAX_PATH];
UINT nCount, nCmd;
BOOL bResult;
HMENU hMenu;

// Make sure the file name is fully qualified and in Unicode format.
GetFullPathName (pszPath, sizeof (tchPath) / sizeof (TCHAR), tchPath, NULL);

if (IsTextUnicode (tchPath, lstrlen (tchPath), NULL))
lstrcpy ((char *) wchPath, tchPath);
else
MultiByteToWideChar (CP_ACP, 0, pszPath, -1, wchPath, sizeof (wchPath) / sizeof (WCHAR));

// Get pointers to the shell's IMalloc interface and the desktop's IShellFolder interface.
bResult = FALSE;

if (!SUCCEEDED (SHGetMalloc (&pMalloc)))
return bResult;

if (!SUCCEEDED (SHGetDesktopFolder (&psfFolder)))
{
pMalloc->Release();
// lpVtbl->Release (pMalloc);
return bResult;
}

// Convert the path name into a pointer to an item ID list (pidl).
if (SUCCEEDED (psfFolder->ParseDisplayName(hwnd,NULL, wchPath, &ulCount, &pidlMain, &ulAttr)) && (pidlMain != NULL))
{
if (nCount = GetItemCount (pidlMain))
{ // nCount must be > 0
// Initialize psfFolder with a pointer to the IShellFolder
// interface of the folder that contains the item whose context
// menu we're after, and initialize pidlItem with a pointer to
// the item's item ID. If nCount > 1, this requires us to walk
// the list of item IDs stored in pidlMain and bind to each
// subfolder referenced in the list.
pidlItem = pidlMain;

while (--nCount)
{
// Create a 1-item item ID list for the next item in pidlMain.
pidlNextItem = DuplicateItem (pMalloc, pidlItem);
if (pidlNextItem == NULL)
{
pMalloc->Free(pidlMain);
psfFolder->Release();
pMalloc->Release();
return bResult;
}
// Bind to the folder specified in the new item ID list.
if (!SUCCEEDED (psfFolder->BindToObject(pidlNextItem, NULL, IID_IShellFolder, (void**)&psfNextFolder)))
{
pMalloc->Free (pidlNextItem);
pMalloc->Free (pidlMain);
psfFolder->Release ();
pMalloc->Release ();
return bResult;
}
// Release the IShellFolder pointer to the parent folder and set psfFolder equal to the IShellFolder pointer for the current folder.
psfFolder->Release ();
psfFolder = psfNextFolder;
// Release the storage for the 1-item item ID list we created just a moment ago and initialize pidlItem so that it points to the next item in pidlMain.
pMalloc->Free (pidlNextItem);
pidlItem = GetNextItem (pidlItem);
}
// Get a pointer to the item's IContextMenu interface and call IContextMenu::QueryContextMenu to initialize a context menu.
ppidl = &pidlItem;
if (SUCCEEDED (psfFolder->GetUIObjectOf(hwnd, 1, (LPCITEMIDLIST*)ppidl, IID_IContextMenu, NULL, (LPVOID*)&pContextMenu)))
{
hMenu = CreatePopupMenu ();
if (SUCCEEDED (pContextMenu->QueryContextMenu(hMenu, 0, 1, 0x7FFF, CMF_EXPLORE)))
{
ClientToScreen(&point);
// Display the context menu.
nCmd = TrackPopupMenu (hMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_RETURNCMD, point.x, point.y, 0, hwnd, NULL);
// If a command was selected from the menu, execute it.
if (nCmd)
{
ici.cbSize = sizeof (CMINVOKECOMMANDINFO);
ici.fMask = 0;
ici.hwnd = hwnd;
ici.lpVerb = MAKEINTRESOURCE (nCmd - 1);
ici.lpParameters = NULL;
ici.lpDirectory = NULL;
ici.nShow = SW_SHOWNORMAL;
ici.dwHotKey = 0;
ici.hIcon = NULL;

if (SUCCEEDED (pContextMenu->InvokeCommand(&ici)))
bResult = TRUE;
}
}
DestroyMenu (hMenu);
pContextMenu->Release ();
}
}
pMalloc->Free (pidlMain);
}
// Clean up and return.
psfFolder->Release ();
pMalloc->Release ();

return bResult;
}
LeonCamel 2001-02-13
  • 打赏
  • 举报
回复
关注。
jinxi_gao 2001-02-13
  • 打赏
  • 举报
回复
kankan
dx79 2001-02-13
  • 打赏
  • 举报
回复
难道还是没人懂我的意思吗?
我不是想要做文件名关联,也不是想要在系统右键菜单里加入菜单项
我是想要获取整个右键菜单并显示出来。我对COM不熟悉,根据MSDN上的说明,要获取
IContextMenu就必须先实现IShellExtInit,我不知道该怎么做

下面是我写的一段code,最后一句错误返回了。..

IShellFolder *rootpsf, *psf;
IContextMenu *pcm;
IShellExtInit *pse;
ITEMIDLIST *pidl;
HMENU hMenu;
WORD wsz[MAX_PATH];

rootpsf = NULL;
psf = NULL;
pcm = NULL;
pse = NULL;
pidl = NULL;
hMenu = NULL;
memset(wsz, 0, MAX_PATH);

hres = SHGetDesktopFolder(&rootpsf);
if (!SUCCEEDED(hres))
goto err_handler;

if (!MultiByteToWideChar(CP_ACP, 0, "D:\\Temp\\song.htm", -1, wsz, MAX_PATH))
goto err_handler;

hres = rootpsf->ParseDisplayName(hWndMain, NULL, (LPOLESTR)wsz, NULL, &pidl, NULL);
if (!SUCCEEDED(hres))
goto err_handler;

hres = rootpsf->BindToObject(pidl, NULL, IID_IContextMenu, (LPVOID *)&pcm);
if (!SUCCEEDED(hres))
goto err_handler;

最后一行总是错误,why?
Smile_Tiger 2001-02-13
  • 打赏
  • 举报
回复
CSDN程序员光盘里有现成的源代码

文章题目为:

Associate File Extension with Shell OPEN command and Application
将文件扩展名同命令行和应用程序关联
Kaile 2001-02-12
  • 打赏
  • 举报
回复
改写注册表,键值如下:
HKEY_CLASSES_ROOT\DIRECTORY\SHELL\MENUNAME
HKEY_CLASSES_ROOT\DIRECTORY\SHELL\MENUNAME\COMMAND 设置其值
HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\DIRECTORY\SHELL
HKEY_LOCAL_MACHINE\SOFTWARE\CLASSES\DIRECTORY\SHELL\COMMAND 设置其值
随风bj 2001-02-12
  • 打赏
  • 举报
回复
具体是在:
HKEY_CLASSES_ROOT\Folder\Shell
举个例:
如果要加入由键运行得程序为TEST.EXE
那么先加入一个主键TEST
然后在其下加入一主键command ,将其默认的键值设为test.exe的路径就可以了
完成后如下:
HKEY_CLASSES_ROOT\Folder\Shell\Test\command\"默认 = test.exe"
随风bj 2001-02-12
  • 打赏
  • 举报
回复
哎呀,在注册表里加入就可以了
dx79 2001-02-12
  • 打赏
  • 举报
回复
楼上二位没有理解我的意思。可能我没有说清楚,我是想要获得每个文件自己的context menu
就是资源管理器里右键单击若干对象后弹出的菜单。
Smile_Tiger 2001-02-12
  • 打赏
  • 举报
回复
节选-----------------

58) 如何给系统菜单添加一个菜单项

给系统菜单添加一个菜单项需要进行下述三个步骤:
首先,使用Resource Symbols对话(在View菜单中选择Resource Symbols...
可以显示该对话)定义菜单项ID,该ID应大于0x0F而小于0xF000;
其次,调用CWnd::GetSystemMenu获取系统菜单的指针并调用
CWnd:: Appendmenu将菜单项添加到菜单中。下例给系统菜单添加两个新的
int CMainFrame:: OnCreate (LPCREATESTRUCT lpCreateStruct)
{


//Make sure system menu item is in the right range.
ASSERT (IDM_MYSYSITEM &0xFFF0)==IDM_MYSYSITEM)
ASSERT (IDM-MYSYSITEM<0xF000)

//Get pointer to system menu.
CMenu* pSysmenu=GetSystemmenu (FALSE)
ASSERT_VALID (pSysMenu)
//Add a separator and our menu item to system menu.
CString StrMenuItem (_T ("New menu item"))
pSysMenu->Appendmenu (MF_SEPARATOR)
pSysMenu->AppendMenu (MF_STRING, IDM_MYSYSITEM, strMenuitem)


}
现在,选择系统菜单项时用户应进行检测。使用ClassWizard处理
WM_SYSCOMMAND消息并检测用户菜单的nID参数:
void CMainFrame:: OnSysCommand (UINT nID,LPARAM lParam)
{
//Determine if our system menu item was selected.
if ( (nID & 0xFFF0)==IDM_MYSYSITEM)
{
//TODO-process system menu item
}

else
CMDIFrameWnd:: OnSysCommand (nID, lParam)
}
最后,一个设计良好的UI应用程序应当在系统菜单项加亮时在状态条显示
一个帮助信息,这可以通过增加一个包含系统菜单基ID的串表的入口来实现。
随风bj 2001-02-12
  • 打赏
  • 举报
回复
用GetSystemMenu试试

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧