如何在资源管理器上下文关联菜单(ContextMenu)中使用子菜单(Submenu)(200分)

  • 主题发起人 主题发起人 CJ
  • 开始时间 开始时间
C

CJ

Unregistered / Unconfirmed
GUEST, unregistred user!
ContextMenu我会的。<br><br><br>关键是这句InsertMenu怎么写?<br>写了以后怎么在以后判断用户安了这个项?//这个应该容易些<br>
 
这个问题不是很难吧?<br><br>QueryContextMenu()<br>{<br><br>根据MSDN的说明,必须从indexMenu位置开始插入菜单,并且菜单的标识符必须在idCmdFirst和idCmdLast之间<br><br>int idCmd = idCmdFirst;<br><br>InsertMenu(hMenu,indexMenu++,MF_STRING | MF_BYPOSITION,idCmd++,"Add To Zip...");<br>InsertMenu(hMenu,indexMenu++,MF_STRING | MF_BYPOSITION,idCmd++,"Add To Zip1...");<br>InsertMenu(hMenu,indexMenu++,MF_STRING | MF_BYPOSITION,idCmd++,"Add To Zip2...");<br><br>return (idCmd - idCmdFirst); //返回值必须等于所增加的菜单数目.<br><br>}<br>--------------------------------------------------------------------------<br><br>InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)<br>{<br>根据MSDN的说明,如果你的DLL被资源管理起调用,那么HIWORD(lpcmi-&gt;lpVerb)等于0,这时候LOWORD(lpcmi-&gt;lpVerb)等于<br>菜单标识符,实际上这个值等于所增加的顺序号,如0,1,2...<br><br>if(!HIWORD(lpcmi-&gt;lpVerb))<br>{<br>&nbsp; int idCmd = LOWORD(lpcmi-&gt;lpVerb);<br>&nbsp; <br>&nbsp; switch(idCmd)<br>&nbsp; {<br>&nbsp; &nbsp; case 0: &nbsp;// "Add To Zip... " 菜单项被调用<br>&nbsp; &nbsp; case 1: &nbsp;// "Add To Zip1... " 菜单项被调用<br>&nbsp; &nbsp; case 2: &nbsp;// "Add To Zip2... " 菜单项被调用<br>&nbsp; }<br>}<br>}<br><br>另:你在CSDN论坛上的类似问题我也答了。
 
是子菜单啊,直接加右键菜单我会的。
 
比如新版本的WINRAR,SEND TO(发送到),WIN2K 的打开方式 等<br><br>就是:<br>菜单1<br>&nbsp; =======子彩蛋1 &nbsp;//要这个<br>&nbsp; =======子彩蛋2<br>彩蛋2
 
呵呵,以前只做过单一菜单,没做过子菜单,看了你的问题,又特定试了一下,实际上也不难:<br>-----------------------------------------------------------------------------------<br><br>STDMETHODIMP TShellExt::QueryContextMenu( HMENU hMenu,UINT indexMenu,<br> &nbsp;UINT idCmdFirst,UINT idCmdLast,<br> &nbsp;UINT uFlags)<br>{<br>&nbsp;<br>&nbsp; //根据MSDN的说明,必须从indexMenu位置开始插入菜单,并且菜单的标识符必须在idCmdFirst和idCmdLast之间<br><br><br>&nbsp; int idCmd=idCmdFirst;<br>&nbsp; AnsiString MenuItemStr="定制菜单2";<br><br>&nbsp; MENUITEMINFO mii;<br>&nbsp; char *MenuStr = "定制菜单1";<br><br>&nbsp; HMENU hNewMenu = CreateMenu();<br><br>&nbsp; AppendMenu(hNewMenu,MF_STRING,idCmd++,"子菜单1");<br>&nbsp; AppendMenu(hNewMenu,MF_STRING,idCmd++,"子菜单2");<br>&nbsp; AppendMenu(hNewMenu,MF_STRING,idCmd++,"子菜单3");<br><br>&nbsp; mii.cbSize = sizeof(MENUITEMINFO);<br>&nbsp; mii.fMask = MIIM_SUBMENU | MIIM_TYPE | MIIM_ID;<br>&nbsp; mii.wID = idCmd++;<br>&nbsp; mii.fType = MFT_STRING;<br>&nbsp; mii.hSubMenu = hNewMenu;<br>&nbsp; mii.dwTypeData = MenuStr;<br>&nbsp; mii.cch = sizeof(MenuStr);<br><br>&nbsp; //定制菜单1 含有子菜单<br>&nbsp; InsertMenuItem(hMenu,indexMenu++,true,&amp;mii);<br><br>&nbsp; //独立的菜单项<br>&nbsp; InsertMenu(hMenu,indexMenu++,MF_STRING | MF_BYPOSITION,idCmd++,MenuItemStr.c_str());<br><br>&nbsp; return HRESULT(idCmd-idCmdFirst); ////返回值必须等于所增加的菜单数目.<br><br>}<br>//---------------------------------------------------------------------------<br>STDMETHODIMP TShellExt::InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)<br>{<br>&nbsp; // 根据MSDN的说明,如果你的DLL被资源管理起调用,那么HIWORD(lpcmi-&gt;lpVerb)等于0,<br>&nbsp; // 这时候LOWORD(lpcmi-&gt;lpVerb)等于菜单标识符,实际上这个值等于所增加的顺序号,<br>&nbsp; // 如0,1,2...<br><br>&nbsp; int idCmd;<br><br>&nbsp; if(!HIWORD(lpcmi-&gt;lpVerb))<br>&nbsp; {<br>&nbsp; &nbsp; idCmd=LOWORD(lpcmi-&gt;lpVerb);<br><br>&nbsp; &nbsp; switch(idCmd)<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; case 0: //”子菜单1“被调用<br>&nbsp; &nbsp; &nbsp; case 1: //“子菜单2”被调用<br>&nbsp; &nbsp; &nbsp; case 2: //”子菜单3“被调用<br><br>// &nbsp; &nbsp; &nbsp;case 3: //“定制菜单1”的标识符,因为含有子菜单,所以该菜单项不可能被激活<br><br>&nbsp; &nbsp; &nbsp; case 4: //”定制菜单2“被调用<br>&nbsp; &nbsp; }<br>&nbsp; }<br>} &nbsp;<br>//---------------------------------------------------------------------------<br>//注意这一步不能少。<br><br>STDMETHODIMP TShellExt::GetCommandString(UINT idCmd,<br> UINT uFlags,<br> UINT FAR *reserved,<br> LPSTR pszName,<br> UINT cchMax)<br>{<br>// &nbsp;MessageBox(NULL,AnsiString("IdCmd="+IntToStr(idCmd)).c_str(),NULL,MB_OK | MB_APPLMODAL | MB_ICONWARNING);<br>&nbsp; if(idCmd==0)<br>&nbsp; {<br>&nbsp; &nbsp; lstrcpy(pszName,"子菜单1");<br>&nbsp; }<br>&nbsp; else if(idCmd==1)<br>&nbsp; {<br>&nbsp; &nbsp; lstrcpy(pszName,"子菜单2");<br>&nbsp; }<br>&nbsp; else if(idCmd==2)<br>&nbsp; {<br>&nbsp; &nbsp; lstrcpy(pszName,"子菜单3");<br>&nbsp; }<br><br>&nbsp; return NOERROR;<br>}<br>//---------------------------------------------------------------------------<br><br>另:你在CSDN论坛上的类似问题我也答了。<br><br>题外话 :<br><br>这个论坛怎么没有象CSDN论坛上的"我参与的问题"这一功能,害得我不停的翻页,一直翻到第8页才找到这个问题。<br><br>我操! 以后我再也不想在这里回复了,有问题到CSDN上问吧.<br>
 
可能是我没有说清楚,我要的是:<br>在别人的子菜单下插入自己的菜单:<br>比如,WINRAR有自己的子菜单:<br>WINRAR=》<br>&nbsp; &nbsp; &nbsp; &nbsp; ADD TO WINRAR<br>&nbsp; &nbsp; &nbsp; &nbsp; MAKE SELF-EXTEND FILE<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;......<br>我要在下面插入一条 OPEN IN WINRAR使之成为:<br>WINRAR=》<br>&nbsp; &nbsp; &nbsp; &nbsp; ADD TO WINRAR<br>&nbsp; &nbsp; &nbsp; &nbsp; MAKE SELF-EXTEND FILE<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;......<br>&nbsp; &nbsp; &nbsp; &nbsp; OPEN IN WINRAR //我自己加的<br><br>也就是说,父彩旦不是我做的,而是别人做的。<br><br>谢谢。<br><br>BTW:如果有邮件通知,直接点下面的连接不就到这个问题了?
 
呵呵,你的要求真是古怪,还好,我既然自称“四大名捕之追杀令”,什么怪招都敢接,看好了!!!<br><br>--------------------------------------<br><br>1、必须先确定一点,你想要你的菜单成为别人的菜单的子菜单,那首先就必须保证那个菜单必须存在。<br>&nbsp; &nbsp;但是如何保证那个菜单必须先存在呢?OK!只要那个菜单所在的COM在你的COM加载之前加载就可以<br>&nbsp; &nbsp;了,但又如何使那个COM在你的COM加载之前加载呢,看注册表:<br>&nbsp; &nbsp;<br>&nbsp; &nbsp; &nbsp; HKEY_CLASSES_ROOT/*/Shellex/ContextMenuHandlers /<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AAAA2002<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ........<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RisingRav<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WinZip<br>&nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp;排在最后的那一项是最先被加载的,所以只要让你的标识排在最前面(这里我采用AAAA2002),这样<br>&nbsp; &nbsp;你的COM就会在所有的COM加载之后加载,这样就能找到那个WinZip或者WinRAR菜单了。<br>&nbsp; &nbsp; &nbsp; <br>2、找到菜单,再添加子菜单就容易多了,看下面的代码: &nbsp; &nbsp; &nbsp; <br><br>&nbsp; int MenuItemCount;<br><br>&nbsp; MENUITEMINFO mii;<br>&nbsp; char Buf[64];<br>&nbsp; HMENU hSubMenu;<br><br>&nbsp; mii.cbSize = sizeof(MENUITEMINFO);<br>&nbsp; mii.fMask &nbsp;= MIIM_SUBMENU | MIIM_TYPE;<br>&nbsp; mii.fType &nbsp;= MFT_STRING;<br><br>&nbsp; MenuItemCount = GetMenuItemCount(hMenu);<br>&nbsp; <br>&nbsp; for(int i=0; i &lt; Count; i++)<br>&nbsp; {<br>&nbsp; &nbsp; ZeroMemory(Buf,sizeof(Buf));<br><br>&nbsp; &nbsp; mii.dwTypeData = Buf;<br>&nbsp; &nbsp; mii.cch = sizeof(Buf);<br><br>&nbsp; &nbsp; //首先确定WinRAR菜单是否已经有子菜单<br>&nbsp; &nbsp; GetMenuItemInfo(hMenu,i,true,&amp;mii);<br><br>&nbsp; &nbsp; if(AnsiString(Buf).LowerCase() == "winzip") // or "winrar"<br>&nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; if(mii.hSubMenu == NULL)<br>&nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; hSubMenu = CreateMenu();//还没有子菜单,必须自己建立菜单<br>&nbsp; &nbsp; &nbsp; }<br>&nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; {<br>&nbsp; &nbsp; &nbsp; &nbsp; hSubMenu = mii.hSubMenu;<br>&nbsp; &nbsp; &nbsp; }<br><br>&nbsp; &nbsp; &nbsp; //加入三个菜单项(也可以使用InsertMenuItem函数插入自己的菜单项,这里为了简化才使用函数AppendMenu)<br>&nbsp; &nbsp; &nbsp; AppendMenu(hSubMenu,MF_STRING,idCmd++,"子菜单1");<br>&nbsp; &nbsp; &nbsp; AppendMenu(hSubMenu,MF_STRING,idCmd++,"子菜单2");<br>&nbsp; &nbsp; &nbsp; AppendMenu(hSubMenu,MF_STRING,idCmd++,"子菜单3");<br><br>&nbsp; &nbsp; &nbsp; //重新设置菜单项<br>&nbsp; &nbsp; &nbsp; mii.hSubMenu = hSubMenu;<br><br>&nbsp; &nbsp; &nbsp; SetMenuItemInfo(hMenu,i,true,&amp;mii);<br><br>&nbsp; &nbsp; &nbsp; break;<br>&nbsp; &nbsp; }<br><br>&nbsp; }<br>&nbsp; &nbsp;<br>&nbsp; return (idCmd - idCmdFirst); <br>&nbsp; <br>&nbsp; 其它不再详述。<br><br><br>
 
不错不错,要的就是这个,有点感觉了,我试试先。
 
没空市,先结了
 

Similar threads

后退
顶部