一难题请教~(100分)

  • 主题发起人 主题发起人 yanyandt2
  • 开始时间 开始时间
Y

yanyandt2

Unregistered / Unconfirmed
GUEST, unregistred user!
当鼠标按下某一个程序的菜单时,我想得到该菜单上的文字,<br>请问如何实现?<br>谢谢!<br>我想的使用钩子,不过不知道该如何做。
 
鼠标按下不知道,不过在WM_MENUSELECT消息中倒是可以捕捉到按下的菜单<br>在WH_CALLWNDPROCRET类型的HOOK中捕捉<br>下边是我以前学习写的一段代码,你参考一下<br><br>type<br>&nbsp; TGoData = record<br>&nbsp; &nbsp; TargetWnd : Hwnd;<br>&nbsp; &nbsp; AppHwnd : THandle;<br>&nbsp; &nbsp; ghHook : HHook;<br><br>&nbsp; &nbsp; HM_Selected: THandle;<br>&nbsp; &nbsp; Send: Boolean;<br><br>&nbsp; &nbsp; SLD_WM_SEND: Cardinal;<br><br>&nbsp; &nbsp; SLD_WM_NEW: Cardinal;<br>&nbsp; &nbsp; SLD_WM_OPEN: Cardinal;<br>&nbsp; &nbsp; SLD_WM_SAVE: Cardinal;<br>&nbsp; &nbsp; SLD_WM_QUIT: Cardinal;<br><br>&nbsp; &nbsp; HM_FILE: THandle;<br>&nbsp; &nbsp; HM_NEW: THandle;<br>&nbsp; &nbsp; HM_OPEN: THandle;<br>&nbsp; &nbsp; HM_SAVE: THandle;<br>&nbsp; &nbsp; HM_QUIT: THandle;<br>&nbsp; end;<br>&nbsp; PGoData = ^TGoData;<br>var<br>&nbsp; GoData: PGoData;<br>&nbsp; MemFile : THandle;<br>&nbsp; aStr: String;<br><br>procedure InitialMenu(HD_APP: THandle);<br>var<br>&nbsp; hm,phm: THandle;<br>begin<br>&nbsp; //注册系统消息<br>&nbsp; GoData^.SLD_WM_NEW :=RegisterWindowMessage('SLD_WM_NEW');<br>&nbsp; GoData^.SLD_WM_OPEN :=RegisterWindowMessage('SLD_WM_OPEN');<br>&nbsp; GoData^.SLD_WM_SAVE :=RegisterWindowMessage('SLD_WM_SAVE');<br>&nbsp; GoData^.SLD_WM_QUIT :=RegisterWindowMessage('SLD_WM_QUIT');<br>&nbsp; //添加菜单并获取各菜单标志<br>&nbsp; //文件菜单<br>&nbsp; phm :=CreateMenu;<br>&nbsp; GoData^.HM_FILE :=phm;<br>&nbsp; AppendMenu(phm,MF_STRING,phm+1,'新建 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Ctrl+N');<br>&nbsp; GoData^.HM_NEW :=Lo(phm+1);<br>&nbsp; AppendMenu(phm,MF_STRING,phm+2,'打开 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Ctrl+O');<br>&nbsp; GoData^.HM_OPEN :=Lo(phm+2);<br>&nbsp; AppendMenu(phm,MF_STRING,phm+3,'关闭');<br>&nbsp; GoData^.HM_SAVE :=Lo(phm+3);<br>&nbsp; AppendMenu(phm,MF_SEPARATOR,0,'-');<br>&nbsp; AppendMenu(phm,MF_STRING,phm+4,'退出');<br>&nbsp; GoData^.HM_QUIT :=Lo(phm+4);<br><br>&nbsp; hm :=GetMenu(HD_APP);<br>&nbsp; AppendMenu(hm,MF_POPUP,phm,'文件');<br>end;<br><br>//内存映射<br>procedure IntoShare; stdcall;export;<br>begin<br>&nbsp; MemFile := OpenFileMapping( FILE_MAP_WRITE, False, 'JJYY' );<br>&nbsp; if MemFile = 0 then<br>&nbsp; &nbsp; MemFile:=CreateFileMapping( $FFFFFFFF, nil,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;PAGE_READWRITE, 0, SizeOf( TGoData ), 'JJYY');<br>&nbsp; GoData := MapViewOfFile( MemFile, FILE_MAP_WRITE, 0, 0, 0 );<br>&nbsp; if MemFile = 0 then<br>&nbsp; FillChar( GoData^, SizeOf( TGoData ),0);<br>&nbsp; SetLength(aStr,255);<br>end;<br><br>procedure DllParamSet(hw: Hwnd; hws: THandle);stdcall; export;<br>var<br>&nbsp; phm,hm: Hmenu;<br>begin<br>&nbsp; GoData^.AppHwnd :=hw;<br>&nbsp; GOData^.TargetWnd :=hws;<br>&nbsp; InitialMenu(hws);<br>end;<br><br>function MouseHookHandler(iCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; export;<br>var<br>&nbsp;cpw: CWPRETSTRUCT;<br>&nbsp;i: Cardinal;<br>begin<br>&nbsp; cpw :=PCWPRETSTRUCT(lparam)^;<br>&nbsp; Result := 0;<br>&nbsp; If iCode &lt; 0 Then<br>&nbsp; begin<br>&nbsp; &nbsp; Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam);<br>&nbsp; &nbsp; Exit;<br>&nbsp; end;<br><br>&nbsp; if (cpw.hwnd = GoData^.TargetWnd) or (IsChild(GoData^.TargetWnd,cpw.hwnd)) then<br>&nbsp; begin<br>&nbsp; &nbsp; Result :=1;<br>&nbsp; &nbsp; if cpw.message = WM_MENUSELECT then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; With GoData^ do<br>&nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; Send :=False;<br>&nbsp; &nbsp; &nbsp; &nbsp; if cpw.lParam = 0 then Exit;<br>&nbsp; &nbsp; &nbsp; &nbsp; HM_Selected :=cpw.lParam;<br>// &nbsp; &nbsp; &nbsp; &nbsp;ShowMessage(IntToStr(cpw.lParam));<br>&nbsp; &nbsp; &nbsp; &nbsp; i :=Lo(cpw.wParam);<br>// &nbsp; &nbsp; &nbsp; &nbsp;if i=Lo(cpw.lParam) then Exit;<br>&nbsp; &nbsp; &nbsp; &nbsp; SLD_WM_SEND :=0;<br>&nbsp; &nbsp; &nbsp; &nbsp; if HM_FILE = cpw.lParam then<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if i in [HM_NEW,HM_OPEN,HM_SAVE,HM_QUIT] then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SEND :=true;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SEND :=false;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if HM_NEW=i then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SLD_WM_SEND :=SLD_WM_NEW<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if HM_OPEN=i then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SLD_WM_SEND :=SLD_WM_OPEN<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if HM_SAVE=i then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SLD_WM_SEND :=SLD_WM_SAVE<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else if HM_QUIT=i then<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SLD_WM_SEND :=SLD_WM_QUIT;<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; if cpw.message = WM_SYSCOMMAND then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; PostMessage(GoData^.AppHwnd,GoData^.SLD_WM_SEND,0,0);<br>&nbsp; &nbsp; end;<br>&nbsp; end;<br>// &nbsp;result :=callnexthookex(0,icode,wparam,lparam);<br>end;<br><br>function EnableMouseHook: BOOL; export;<br>begin<br>&nbsp; Result := False;<br>&nbsp; if hNextHookProc &lt;&gt; 0 then Exit;<br>// WH_CALLWNDPROCRET &nbsp;WH_MOUSE &nbsp;WH_KEYBOARD &nbsp;WH_JOURNALRECORD WH_JOURNALPLAYBACK<br><br>&nbsp; hNextHookProc := SetWindowsHookEx(WH_CALLWNDPROCRET,<br>&nbsp; &nbsp; MouseHookHandler,<br>&nbsp; &nbsp; HInstance,<br>&nbsp; &nbsp; 0);<br>&nbsp; Result := hNextHookProc &lt;&gt; 0;<br>end;<br><br>function DisableMouseHook: BOOL; export;<br>begin<br>&nbsp; if hNextHookProc &lt;&gt; 0 then<br>&nbsp; begin<br>&nbsp; &nbsp; UnhookWindowsHookEx(hNextHookProc);<br>&nbsp; &nbsp; hNextHookProc := 0;<br>&nbsp; &nbsp; MessageBeep(0);<br>&nbsp; end;<br>&nbsp; Result := hNextHookProc = 0;<br>end;<br><br>procedure MouseHookExit;<br>begin<br>&nbsp; if hNextHookProc &lt;&gt; 0 then DisableMouseHook;<br>&nbsp; ExitProc := procSaveExit;<br>end;<br>
 
谢谢,我实验了一下,这个问题想请教一下:<br>function HookProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;<br>var<br>HookStruct: CWPRETSTRUCT;//<br>caption2:array [0..255] of char;<br>begin<br>Result:=1;<br>HookStruct:=PCWPRETSTRUCT(lparam)^;<br>if iCode &lt; 0 then<br>begin<br>Result := CallNextHookEx(hHook,iCode,wParam,lParam);<br>exit;<br>end;<br><br>if HookStruct.message = WM_MENUSELECT then<br>begin<br>getMenuString(HookStruct.lParam,lo(HookStruct.wParam),<br>&nbsp; &nbsp; caption2,255,hi(HookStruct.wParam));<br>form1.label1.Caption:=caption2;<br>end;<br>&nbsp; &nbsp; &nbsp; &nbsp;<br>end;<br><br>现在我一SetwindowsHookEx(WH_CALLWNDPROCRET,HookProc,HInstance,0);<br>程序就非法操作,请问该如何解决?
 
你上边的代码不全,所以我也不知道<br>你要是愿意的话留个Email,我把写好的DLL源代码发给你,你看看<br>对了我看你上边的代码有Form1.这样的代码,不知你是不是在应用程序中用的SetwindowsHookEx<br>你要想获得其他程序的消息,必须在DLL中实现
 
我刚才是写到form里的。<br>正在实验dll中的。<br>我的email: realyanyan@sohu.com<br>非常感谢!!
 
我在dll中实现不会出现错误了。<br>可是我无法得到其他程序菜单的文字,请问是怎么回事?
 
既然不出错了,那我就不发了<br>我没有试过取得菜单的文字,不过我想只要取得菜单的句柄那么就应该可以得到他的文字<br>你是一下用API函数GetMenuItemInfo,我刚刚看了一下觉得应该是可以的。<br><br>GetMenuItemInfo <br><br>VB声明 <br>Declare Function GetMenuItemInfo Lib "user32" Alias "GetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As Long, ByVal b As Boolean, lpMenuItemInfo As MENUITEMINFO) As Long <br>说明 <br>用一个MENUITEMINFO结构取得(接收)与一个菜单条目有关的特定信息 <br>返回值 <br>Long,TRUE(非零)表示成功,否则返回零。会设置GetLastError <br>参数表 <br>参数 类型及说明 <br>hMenu Long,菜单的句柄 <br>un Long,菜单条目的菜单ID或位置 <br>b Boolean,如un指定的是条目位置,就为TRUE;如指定的是一个菜单ID,则为FALSE <br>lpMenuItemInfo MENUITEMINFO,这个结构用于装载请求的信息 <br><br><br>MENUITEMINFO <br><br>类型定义 <br>Type MENUITEMINFO<br>cbSize As Long<br>fMask As Long<br>fType As Long<br>fState As Long<br>wID As Long<br>hSubMenu As Long<br>hbmpChecked As Long<br>hbmpUnchecked As Long<br>dwItemData As Long<br>dwTypeData As Long<br>cch As Long<br>End Type <br>说明 <br>这个结构包含了菜单条目的信息,不支持win nt 3.51(原文:This structure contains information about a menu entry. Not supported on NT 3.51)<br>&nbsp;<br>字段表 <br>字段 类型及说明 <br>cbSize Long,结构大小,通常为44bytes(Size of this structure, currently at 44 bytes.) <br>fMask Long,Specifies the information to set or get. Any combination of the following <br>MIIM_CHECKMARKS Sets or gets the hbmpChecked and hbmpUnchecked fields <br>MIIM_DATA Sets or gets the dwItemData field <br>MIIM_ID ets or gets the wID field <br>MIIM_STATE Sets or gets the fState field <br>MIIM_SUBMENU Sets or gets the hSubMenu field <br>MIIM_TYPE Sets or gets the fType and dwTypeData fields <br>fType Long,Menu item type, any combination of the following with the exception that MFT_BITMAP, MFT_SEPARATOR, and MFT_STRING cannot be combined with one another:MFT_BITMAP: Displays the menu item using a bitmap. dwTypeData contains the bitmap handle.MFT_MENUBARBREAK: The menu item is placed on a new line for top level menus, a new column for popup menus. Places a line between the columns.MFT_MENUBREAK: Same as MFT_MENUBREAK without the vertical line.MFT_OWNERDRAW: The menu item is an owner-draw menu.MFT_RADIOCHECK: Uses a radio button (option button) bullet to indicate the checked state instead of a check mark. Applies if no custom bitmap is specified.MFT_RIGHTJUSTIFY: Right-justifies a top level menu item.MFT_SEPARATOR: The entry is a separator line in a pop-up menu.MFT_STRING: The entry contains a string. dwTypeData contains the address of the string, and the cch field contains the length of the string. <br>fState Long,Current menu entry state or action to take. May be any combination of the following:MFS_CHECKED: Entry is checked.MFS_DEFAULT: The entry is a default item (appears in bold).MFS_DISABLED: Entry is disabled.MFS_ENABLED: Entry is enabled.MFS_GRAYED: Entry is grayed and disabled.MFS_HILITE: Entry is highlighted.MFS_UNCHECKED: Entry is unchecked.MFS_UNHILITE: Entry is unhighlighted. <br>wID Long,Menu entry identifier. The high 16 bits are not used. <br>hSubMenu Long,Handle to a pop-up menu if one is associated with the menu entry <br>hbmpChecked Long,Handle to a bitmap to display for a menu entry when checked. Zero to use the default <br>hbmpUnchecked Long,Handle to a bitmap to display for a menu entry when unchecked. Zero to use the default <br>dwItemData Long,User-defined value associated with this entry. <br>dwTypeData Long,Depends on the menu type <br>cch Long,Length of the menu string when MFT_STRING is specified. Zero for other menu types. <br><br>
 
我想我是得到文字的方法不对。<br>我不想用内存影射,想在得到菜单文字时给我的程序sendmessage过来,<br>可是用sendmessage如何发送字符串(菜单文字)?
 
我想你可以把得到的菜单句柄发送过来然后再分析该句柄来获得菜单标题
 
我把菜单句柄发过来也得不到,不知道为什么。。。<br>tianjh007如果有时间帮我写一个好吗?谢谢了<br>
 
好的,我抽时间看看,要是做出来的话再给你回话
 
谢谢了!<br>别人没有其他好办法吗??
 
接受答案了.
 
后退
顶部