(两年无解之题?)怎样获取TEdit的默认右键菜单(ContextMenu)的句柄 (200分)

  • 主题发起人 kaithink
  • 开始时间
K

kaithink

Unregistered / Unconfirmed
GUEST, unregistred user!
如题<br><br>关键字:组件设计,GetMenu,WM_CONTEXTMENU,右键菜单,上下文菜单,弹出菜单,快捷菜单,菜单句柄<br><br>注意事项:<br><br>&nbsp; &nbsp; 环境:建立一个DELPHI工程,在FORM1上放置一个EDIT1,不需其它设置。<br>&nbsp; &nbsp; 要求:在程序运行时,当右击EDIT1之后,显示右键菜单之前(当然是该菜单创建之后了),给出即将显示的右键菜单的句柄,进一步的目的是修改它控制它。<br>&nbsp; &nbsp; 另:此处所提右键菜单,均指系统默认的,并非自己放置的TPOPMENU组件。<br>
 
一下午居然无人应声<br><br>可叹这个问题的变态
 
下面是一个汉化菜单的例子。其中有得到菜单句柄的语句。<br>*************************************************<br>DELPHI:菜单的汉化<br><br>----现在我们经常看到一些软件汉化包,例'晴窗伴侣'是PHOTOSHOP<br>的汉化包,其实我们只要对WINDOWS的编程熟悉,也可以自己编写某<br>些软件的汉化包。这样不管软件大小,只要你喜欢就可以给做一个汉<br>化包。下面的程序是一些主要的步骤。其实你还可以用别的方法来实<br>现,亲自试试吧。<br><br>----在运行程序之前首先生成一个中英文菜单对照表文件,产生时可<br>以参照该程序自己编制一个获得系统的原菜单内容的程序,然后在之<br>后输入菜单的汉字内容。其格式如下:<br>  <br>SAVE AS 保存到.... <br>. . <br>.. <br>EXIT 退出系统 <br>// 程序开始 <br>unit wrdxt; <br><br>interface <br><br>uses <br>Windows, Messages, SysUtils, Classes, <br>Graphics, Controls, Forms, Dialogs, <br>StdCtrls; <br><br>type <br>TForm1 = class(TForm) <br>Button1: TButton; <br>ListBox1: TListBox; <br>ListBox2: TListBox; <br>procedure Button1Click(Sender: TObject); <br>procedure FormActivate(Sender: TObject); <br>private <br>{ Private declarations } <br>public <br>{ Public declarations } <br>end; <br>var <br>Form1: TForm1; <br>childmenu,mainmenu,c2menu:hmenu; <br>wndhandle:hwnd; <br>mystr:pchar; <br>mainnum,childNUM,c2num:integer; <br>MYCHAR:STRING; <br>mm3,mm6:string[19]; <br>mm4,mm5:string; <br>implementation <br><br>{$R *.DFM} <br>//我用表单的CLICK事件激活,其实用ACTIVE事件会更好<br>procedure TForm1.Button1Click(Sender: TObject); <br>var <br>start1,start2,start3,start4,start5:integer; <br><br>begin <br>//通过标题获得窗口句柄 <br>wndhandle:=findwindow(nil,mystr); <br>//通过标题获得菜单句柄 <br>mainmenu:=getmenu(wndhandle); <br>//取得顶行菜单数 <br>mainnum:=getmenuitemcount(mainmenu); <br>//汉化菜单 <br>for start1:=0 to mainnum do <br>begin <br>mm5:=``; <br>//取得菜单项的标题 <br>getmenustring(mainmenu,start1,PCHAR <br>(myChAR),20,MF_BYPOSITION); <br>mm6:=string(pchar(mychar)); <br>for start3:=0 to listbox1.items.count-1 do <br>begin <br>mm4:=listbox1.Items[start3]; <br>mm3:= mm4; <br>if (string(mm6)=trim(mm3)) then <br>begin <br>for start4:=21 to length(mm4) do <br>begin <br>mm5:=mm5+mm4[start4]; <br>end; <br>end; <br>end; <br>if mm5&lt;&gt;`` then <br>modifymenu(mainmenu,start1,MF_BYPOSITION, <br>getmenuitemid(mainmenu,start1),pchar(mm5)); <br>childmenu:=getsubmenu(MAINMENU,start1); <br>childnum:=getmenuitemcount(childmenu); <br>//汉化下拉菜单 <br>for start2:=0 to childnum do <br>begin <br>mm5:=``; <br>getmenustring(childmenu,start2,PCHAR <br>(mychar),20,MF_BYPOSITION); <br>mm6:=string(pchar(mychar)); <br>for start3:=0 to listbox1.items.count-1 do <br>begin <br>mm4:=listbox1.Items[start3]; <br>mm3:= mm4; <br>if (string(mm6)=trim(mm3)) then <br>begin <br>for start4:=21 to length(mm4) do <br>begin <br>mm5:=mm5+mm4[start4]; <br>end; <br>end; <br>end; <br>if mm5&lt;&gt;`` then <br><br>modifymenu(childmenu,start2,MF_BYPOSITION, <br>getmenuitemid(childmenu,start2),pchar(mm5)); <br>c2menu:=getsubmenu(childMENU,start2); <br>c2num:=getmenuitemcount(c2menu); <br>for start5:=0 to c2num do <br>begin <br>mm5:=``; <br>getmenustring(c2menu,start5,PCHAR <br>(mychar),20,MF_BYPOSITION); <br>mm6:=string(pchar(mychar)); <br>for start3:=0 to listbox1.items.count-1 do <br>begin <br><br>mm4:=listbox1.Items[start3]; <br>mm3:= mm4; <br>if (string(mm6)=trim(mm3)) then <br>begin <br>for start4:=21 to length(mm4) do <br>begin <br>mm5:=mm5+mm4[start4]; <br>end; <br>end; <br>end; <br>if mm5&lt;&gt;`` then <br>modifymenu(c2menu,start5,MF_BYPOSITION, <br>getmenuitemid(c2menu,start5),pchar(mm5)); <br>END; <br><br>END; <br>end; <br><br>end; <br><br>procedure TForm1.FormActivate(Sender: TObject);<br>begin <br>//要汉化的系统的窗口标题 <br>//mystr:=`adobe photoshop`; <br>mystr:=`frontpage explorer`; <br>mychar:=` `; <br>//装入已编辑好的中英文菜单对照文件 <br>listbox1.items.loadfromfile(`myfile2.txt`);<br>end; <br><br>end. <br><br>
 
楼上:<br><br>呵呵,有这么容易吗? 看清题先!
 
搜遍互联网都没找到解决方案
 
_AFX_THREAD_STATE* pThreadState = ::AfxGetThreadState();//_afxThreadState.GetData(); // start from popup<br>pMenu = CMenu::FromHandle(pThreadState-&gt;m_hTrackingMenu);<br><br>&nbsp;得到当前线成的STATE ,通过他的到当前线成的弹出菜单<br><br>CSDN有人提示<br><br>大富翁总有没落之感...
 
/////我上面写的是:获取其他应用程序的菜单句柄。///////<br><br>你到底是想实现什么功能,你提的关键字范围太广。<br>是在WINDOWS的上下文菜单,还是DELPHI的IDE菜单。<br>如果是WINDOWS的上下文菜单,那很简单在DELPHI的例子中有详细的源程序。<br>如果想获取DELPHI的 IDE菜单,那在《DELPHI深度历险》中有,或查OPEN TOOLS API<br>相关资料。<br><br>你最好把你要做的功能详细说一下。之所以没有人来,可能跟你提的方式有关。<br>大富翁里高手如云,关键是有些高手愿不愿意说!
 
回楼上:<br><br>已经修改主贴,尽我所能讲清需求了。<br><br>如果还有不明白的,请参看以下贴子:<br>http://expert.csdn.net/Expert/topic/2275/2275483.xml?temp=6.861514E-02<br>http://expert.csdn.net/Expert/topic/1970/1970757.xml?temp=.1517145<br>http://expert.csdn.net/Expert/topic/1453/1453055.xml?temp=.1210749<br>http://search.csdn.net/expert/topic/53/5301/2002/8/21/959541.htm<br><br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=234507<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=1614265<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=254067<br>http://www.delphibbs.com/delphibbs/dispq.asp?lid=810306<br>
 
昨天找了一下全文检索,两年前就有人问这个问题,但是没人给出能接受的<br>答案,强烈关注中,如有人能解,我再加200分送上!
 
楼上正解,感谢支持<br>如果真能解出,我也再加200分!<br><br>这个问题已在CSDN发出,为解此题,我甘愿在大富翁破产!
 
我明白你的问题,我也问类似的问题,TRichEdit的<br>如果有人知道告诉我<br>
 
拦截API函数CreateMenu,CreatePopupMenu,可以直接获得当前弹出菜单的句并啊
 
恩,前段时间在研究如何画真正xp风格菜单时得出一些经验,<br>不知是否正确,还忘包涵,我的想法是这样的:<br>根据MS所说,菜单的类名是:MENU_CLASS = '#32768';<br>然后设置一个消息钩子,FHook:= SetWindowsHookEx(WH_CALLWNDPROC, TFNHookProc(@FThunk), 0, MainThreadID);<br>//hook CallBack Procedure<br>function TMenuSubClass.MenuCallBack(code: Integer; wparam: WPARAM;<br>&nbsp; lparam: LPARAM): LRESULT;<br>var<br>&nbsp; cwps: TCWPStruct;<br>&nbsp; lRet: Longint;<br>&nbsp; szClass: array[0..8] of char;<br>&nbsp; MenuHwnd:Hwnd;<br>begin<br>if (Code = HC_ACTION) then<br>begin<br>&nbsp; CopyMemory(@cwps, Pointer(lParam), SizeOf(CWPSTRUCT));<br>&nbsp; case cwps.message of<br>&nbsp; &nbsp; WM_INITMENUPOPUP:<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; //判断是否系统菜单<br>&nbsp; &nbsp; if (getSystemmenu(cwps.hwnd,false)=cwps.wParam) or (hiword(cwps.lParam)&lt;&gt;0) then<br>&nbsp; &nbsp; &nbsp; bSysMenu:=true<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; bSysMenu:=false;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; WM_CREATE:<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; GetClassName(cwps.hwnd, szClass, Length(szClass)-1);<br>&nbsp; &nbsp; &nbsp; &nbsp;// windows 的菜单类是 #32768<br>&nbsp; &nbsp; &nbsp; if (lstrcmpi(szClass, MENU_CLASS) = 0) then <br>&nbsp; &nbsp; &nbsp; //显示菜单句柄,至于是Tedit的,我没有具体试过,反正能构住当前程序所有菜单<br>&nbsp; &nbsp; &nbsp; showmessage(intostr(cwps.hwnd));<br>&nbsp; &nbsp;end;
 
这个和系统文件右键一样都很难:http://www.bwkj.net/bios/webstudy1/xitongyoujian1.htm<br>
 
从技术角度来说,确实是一个比较值得研究的话题。<br>在如下也有相关讨论 http://dbforums.com/t409307.html<br>主要是说截获 &nbsp;WM_INITMENUPOPUP 和 WM_CONTEXTMENU 消息,但是似乎也是一个失败的产物。<br><br>个人实现思路大概这个应该和在文件夹中弹出菜单类似。很有可能会使用到GetUIObjectOf、IContextMenu之类的。但是很遗憾,俺没有试验成功。。。
 
等待成功案例
 
这个菜单是缺省得菜单,应该是调用 DefHandler之后产生的这个菜单 只是不知道之后是否还有什么对应的消息<br>我想可以把所有接受的消息全部记录下来进行分析 至于菜单的性质我想应该不是GetUIObjectOf、IContextMenu 这类的,这类的好处在于灵活可扩展,但是Edit好像没有这个必要我想<br>弹出菜单一般调用TrackPopupMenu(?)来进行的,HOOKAPI?
 
我的天啊,没人回答
 
难、难、难。。。。。。。。。。。。。。。。
 
to:kaithink<br>没有试过我的代码???<br>我指的拦截到程序的菜单,也包括Tedit的右键菜单的,我已经成功把它变成自画类型的菜单
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
624
import
I
I
回复
0
查看
556
import
I
顶部