高手请进:如何获得外部程序的菜单项内容?(UP有分)

PrettyMurphy 2004-10-24 11:55:31
我在做一个项目,需要跟据外部程序所选择的菜单项动作,来在本程序内执行相应的响应.

我做了个全局的HOOK,可以截获菜单的点击的左右键事件,可以知道点击的是菜单,但是却始终区分不出点击了菜单哪一项.

后来想靠取得的内容来区分,但是别的对象比如BUTTON,LISTVIEW等都可以取到内容,只有菜单的取不到.

我想请问,为什么菜单的内容取不到?有没有什么办法可以取得到?或者说,可以区分出点击了哪一项菜单?

具体HOOK内容实现如下:

function Hookproc(iCode: Integer; wparam, lparam: LongInt): lresult; stdcall;
var PEvt: ^EVENTMSG;
FocusWnd: HWND;
aName: array [0..255] of char;

rPos: TPoint;
ahWnd:THandle;
begin
if iCode<0 then begin
result:= CallNextHookEx(haHook,iCode,wparam,lparam);
exit;
end;

if (iCode = HC_ACTION) then
begin
GetCursorPos(rPos);
ahWnd:=WindowFromPoint(rPos);
GetClassName(ahWnd,aName, 256);

if trim(aName)='#32768' then //是否是菜单?
form1.Label2.Caption :='选中的是菜单'
else
form1.Label2.Caption :=aName;

GetWindowText(ahWnd,aName,255); //获取该类名称.
form1.Label3.Caption :=aName;

FocusWnd:=GetActiveWindow;
if FocusWnd= IE_HWND then begin //IE_HWND为指定窗体句柄.
pEvt := Pointer(DWord(lParam)); //取鼠标结构.
if (pEvt.message = WM_LBUTTONDOWN) or (pEvt.message = WM_RBUTTONDOWN) then
begin
if pEvt.message = WM_LBUTTONDOWN then
form1.Label1.Caption :='左键按下'
else
form1.Label1.Caption := '右键按下';
end;
end;
end;
result:= CallNextHookEx(haHook,iCode,wparam,lparam);
end;


请教高手指点.谢谢!
...全文
173 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
biku 2004-10-25
  • 打赏
  • 举报
回复
我也想知道,帮顶一下!!!!
laoer 2004-10-25
  • 打赏
  • 举报
回复
关注一下!
PrettyMurphy 2004-10-25
  • 打赏
  • 举报
回复
截获不到...

可能是我水平不行.
biku 2004-10-25
  • 打赏
  • 举报
回复
请问,用HOOK的话,需要那个HOOK才能,HOOK到点击菜单时的消息。
PrettyMurphy 2004-10-25
  • 打赏
  • 举报
回复
to: Sorder(剑客)

ID值怎么取呢?是wparam的值么?

可是我所取到的wparam值都是0呢.

在同一位大大讨论时,大大是这样说的:
你钩到的消息是MainForm的,消息是一层一层地派发下去的,TMenu也有自己的消息处理程序WndProc,只要将消息扔给他就可以了。

TMenu有WindowsHandle属性,可以用通过Win32 API,来查找到WndProc地址,然后CALL就可以了。

消息处理机制是多层的,在MainForm的WndProc中,并不处理菜单,而只是把消息发给菜单。菜单还有自己的WndProc。MenuItem如果什么也不做,自然会返回,如果处理了这个消息,那么Call WndProc()时,会有handled标志来标识的。

有一点点理解了,有高手发表高见没?或是实现?
Tensionli 2004-10-25
  • 打赏
  • 举报
回复
up
progray 2004-10-25
  • 打赏
  • 举报
回复
mark
brallow 2004-10-25
  • 打赏
  • 举报
回复
收藏,。。。
i54 2004-10-25
  • 打赏
  • 举报
回复
UP学习
Sorder 2004-10-25
  • 打赏
  • 举报
回复
你先试一下每一个菜单项点击后传过来的ID值,然后写程序根据每一个ID值来完成动作
PrettyMurphy 2004-10-25
  • 打赏
  • 举报
回复
to : mestars(米豆)(☆☆)

可能我们理解上有差别,我的想法是获得外部的菜单事件响应呢.

mestars 2004-10-25
  • 打赏
  • 举报
回复
简单一句话就是:让你的程序支持调用参数。例如:让你的程序支持在windows的【运行】里可以这样运行 AppName.exe 参数。
mestars 2004-10-25
  • 打赏
  • 举报
回复
我的意思是就像执行Dos命令似的调用你的程序,比如 Format C:,C:就是个参数。现在就是把参数换成你的菜单的标题,然后你在你的程序里对参数进行分析看是那个菜单调用的。分析的代码样例上面已经列了
DemonLoveLizzy 2004-10-24
  • 打赏
  • 举报
回复
可以截取WM_INITMENU(菜单激活时),WM_MENUSELECT(菜单选择时),或者WM_SYSCOMMAND(wParam就是菜单的ID号)
peacezhang 2004-10-24
  • 打赏
  • 举报
回复
up
mestars 2004-10-24
  • 打赏
  • 举报
回复
比较笨但是有效的方法
你可以给你的程序加上参数处理,在程序启动时判断
if ParamCount>1 then
begin
if ParamStr(1)='menu1' then
ShowMessage('菜单1')
esle if ParamStr(1)='menu2' then
ShowMessage('菜单2')
else
ShowMessage('直接运行的');
end;
/////////////////////////////////////////////////////////////////////////////
Delphi调用该程序:
ShellExcute(handle, 'open', '程序名','menu1',nil,SW_NORMAL)
VB调用:
ShellExecute Me.hwnd, "open", 程序名,"menu1", vbNullString, 1
PrettyMurphy 2004-10-24
  • 打赏
  • 举报
回复
??? 能不能讲详细点?
masterjames 2004-10-24
  • 打赏
  • 举报
回复
菜单哪一项,可以将值放到自定义消息中,做消息发对来
DemonLoveLizzy 2004-10-24
  • 打赏
  • 举报
回复
截WM_MENUSELECT试试,按理来讲是可行的
PrettyMurphy 2004-10-24
  • 打赏
  • 举报
回复
怎么判断?
加载更多回复(4)

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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