利用VB如何在另一个程序中增加一个菜单

Meditate 2002-02-23 09:48:50
我现在可以取得另一个程序窗体和菜单的句柄,可是我不知道如何增加一个菜单,请高手们指教!!
...全文
59 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
zyl910 2002-02-25
  • 打赏
  • 举报
回复
我编一个试试。
Meditate 2002-02-25
  • 打赏
  • 举报
回复
zy1910兄,你的程序我试了,主要的问题是如何标示自己建立的菜单,你的程序里是加入了一个全局变量,这个变量有什么说法吗?
Meditate 2002-02-25
  • 打赏
  • 举报
回复
另外你写的程序在自己工程里的窗口加菜单没有问题,可是如果我在另一个程序中动态增加(比如说记事本)就捕获不到事件(hook没有起作用,但是安装上了)
而我自己写的程序安装hook是报告错误5,不只是什么原因。
另外你有其他联系方式吗?比如QQ,Messenger?
我的QQ:17136753
MSN Messenger: YuanXu@km169.net
谢谢指教!
shanhe 2002-02-24
  • 打赏
  • 举报
回复
pop菜单需要使用也叫做
Public Declare Function TrackPopupMenuEx Lib "user32" Alias "TrackPopupMenuEx" (ByVal hMenu As Long, ByVal un As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal hWnd As Long, lpTPMParams As TPMPARAMS) As Long
的函数跟踪,否则不会响应的。但是这只能对自己的程序(同一进程)有效。
如果你是要给另外的程序外挂一个菜单,请采用hook的方式添加并且需要截取窗体winproc函数的调用,判读所有菜单消息是否是自己添加得菜单消息。VB做起来相当的笨拙,一般采用C利用WIN API写DLL来做。
dbcontrols 2002-02-24
  • 打赏
  • 举报
回复
他也不知道。
Meditate 2002-02-24
  • 打赏
  • 举报
回复
谢谢zy1910,我现在已经知道如何增加菜单了,可是我增加完一个菜单AppendMenu后,无法响应他的事件,请仁兄赐教!
另外,wIDNewItem参数的说明和MSDN中的好象有些出入。
zyl910 2002-02-24
  • 打赏
  • 举报
回复
忘记转换空格:


'模块中:
Option Explicit

Public Declare Function GetMenu Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long

Public Declare Function InsertMenu Lib "user32" Alias "InsertMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
Public Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long

Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Const GWL_WNDPROC = -4

Public Const WM_COMMAND = &H111

Public Const MF_BYCOMMAND = &H0&
Public Const MF_BYPOSITION = &H400&
Public Const MF_STRING = &H0&

Public OldWndProc As Long
Public HookhWnd As Long

Public MyCreaMenu As Long

Public Sub Hook(hWnd As Long)
  HookhWnd = hWnd
  OldWndProc = SetWindowLong(HookhWnd, GWL_WNDPROC, AddressOf WindowProc)
  
End Sub

Public Sub UnHook()
  Call SetWindowLong(HookhWnd, GWL_WNDPROC, OldWndProc)
End Sub
Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  Dim GetMsg As Boolean
  
  Select Case uMsg
  Case WM_COMMAND
    If wParam = MyCreaMenu Then '看这里
      MsgBox "动态创建的菜单"
      GetMsg = True
    End If
    
  End Select
  
  If GetMsg = False Then WindowProc = CallWindowProc(OldWndProc, hWnd, uMsg, wParam, lParam)
  
End Function




'窗体中:
Option Explicit

Public MeMenuID As Long
Public FileMenuID As Long
  
Private Sub Form_Load()
  MeMenuID = GetMenu(Me.hWnd)
  FileMenuID = GetSubMenu(MeMenuID, 0)
  MyCreaMenu = &H4001
  Call InsertMenu(FileMenuID, 0, MF_BYPOSITION Or MF_STRING, MyCreaMenu, "API创建的菜单")
  
  Hook Me.hWnd
  
End Sub

Private Sub Form_Unload(Cancel As Integer)
  UnHook
  Call DeleteMenu(FileMenuID, MyCreaMenu, MF_BYCOMMAND)
  
End Sub

Private Sub mnuExit_Click()
  Unload Me
  
End Sub
zyl910 2002-02-24
  • 打赏
  • 举报
回复
'窗体中:
Option Explicit

Public MeMenuID As Long
Public FileMenuID As Long

Private Sub Form_Load()
MeMenuID = GetMenu(Me.hWnd)
FileMenuID = GetSubMenu(MeMenuID, 0)
MyCreaMenu = &H4001
Call InsertMenu(FileMenuID, 0, MF_BYPOSITION Or MF_STRING, MyCreaMenu, "API创建的菜单")

Hook Me.hWnd

End Sub

Private Sub Form_Unload(Cancel As Integer)
UnHook
Call DeleteMenu(FileMenuID, MyCreaMenu, MF_BYCOMMAND)

End Sub

Private Sub mnuExit_Click()
Unload Me

End Sub


'模块中:
Option Explicit

Public Declare Function GetMenu Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long

Public Declare Function InsertMenu Lib "user32" Alias "InsertMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
Public Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long

Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Public Const GWL_WNDPROC = -4

Public Const WM_COMMAND = &H111

Public Const MF_BYCOMMAND = &H0&
Public Const MF_BYPOSITION = &H400&
Public Const MF_STRING = &H0&

Public OldWndProc As Long
Public HookhWnd As Long

Public MyCreaMenu As Long

Public Sub Hook(hWnd As Long)
HookhWnd = hWnd
OldWndProc = SetWindowLong(HookhWnd, GWL_WNDPROC, AddressOf WindowProc)

End Sub

Public Sub UnHook()
Call SetWindowLong(HookhWnd, GWL_WNDPROC, OldWndProc)
End Sub
Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim GetMsg As Boolean

Select Case uMsg
Case WM_COMMAND
If wParam = MyCreaMenu Then '看这里
MsgBox "动态创建的菜单"
GetMsg = True
End If

End Select

If GetMsg = False Then WindowProc = CallWindowProc(OldWndProc, hWnd, uMsg, wParam, lParam)

End Function

zyl910 2002-02-24
  • 打赏
  • 举报
回复
To dbcontrols(泰山__抛砖引玉):你胡说什么呀!我是刚刚才看见这个贴子又排到前面来了!

要响应“Wm_Command”消息。

正在写例子……
NowCan 2002-02-24
  • 打赏
  • 举报
回复
响应事件必须用钩子这类的技术进入到目标进程内。我曾经写过一个,在我主页上,不过是用的BCB,不是VB。
http://nowcan.yeah.net
zyl910 2002-02-23
  • 打赏
  • 举报
回复
菜单API:
====================================================================
AppendMenu

VB声明
Declare Function AppendMenu Lib "user32" Alias "AppendMenuA" (ByVal hMenu As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
说明
在指定的菜单里添加一个菜单项
返回值
Long,非零表示成功,零表示失败。会设置GetLastError
参数表
参数 类型及说明
hMenu Long,菜单句柄
wFlags Long,参考ModifyMenu函数中的菜单常数标志定义表,其中列出了允许使用的所有常数
wIDNewItem Long,指定菜单条目的新命令ID。如果在wFlags参数中指定了MF_POPUP字段,那么这应该是指向一个弹出式菜单的句柄
lpNewItem String(相应的vb声明见注解),如果在wFlags参数中指定了MF_STRING标志,这就代表在菜单中设置的字串。如设置了MF_BITMAP标志,这就代表一个Long型变量,其中包含了一个位图句柄。如设置了MF_OWNERDRAW,这个值就会包括在DRAWITEMSTRUCT和MEASUREITEMSTRUCT结构中,在条目需要重画的时候由windows发送出去
====================================================================
InsertMenu

VB声明
Declare Function InsertMenu Lib "user32" Alias "InsertMenuA" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long, ByVal wIDNewItem As Long, ByVal lpNewItem As Any) As Long
说明
在菜单的指定位置处插入一个菜单条目,并根据需要将其他条目向下移动
返回值
Long,非零表示成功,零表示失败。会设置GetLastError
参数表
参数 类型及说明
hMenu Long,菜单的句柄
nPosition Long,定义了新条目插入点的一个现有菜单条目的标志符。如果在wFlags中指定了MF_BYCOMMAND标志,这个参数就代表欲改变的菜单条目的命令ID。如设置的是MF_BYPOSITION标志,这个参数就代表菜单条目在菜单中的位置,第一个条目的位置为零
wFlags Long,一系列常数标志的组合。参考ModifyMenu
wIDNewItem Long,指定菜单条目的新菜单ID。如果在wFlags中指定了MF_POPUP标志,就应该指定弹出式菜单的一个句柄
lpNewItem 如果在wFlags参数中设置了MF_STRING标志,就代表要设置到菜单中的字串(String)。如设置的是MF_BITMAP标志,就代表一个Long型变量,其中包含了一个位图句柄
====================================================================
CreatePopupMenu

VB声明
Declare Function CreatePopupMenu Lib "user32" Alias "CreatePopupMenu" () As Long
说明
创建一个空的弹出式菜单。可用AppendMenu或InsertMenu函数在窗口中添加条目,或者为一个现成的菜单添加弹出式菜单,并在新建的菜单中添加条目
返回值
Long,如成功,返回一个菜单句柄;零意味着错误
====================================================================
DestroyMenu

VB声明
Declare Function DestroyMenu Lib "user32" Alias "DestroyMenu" (ByVal hMenu As Long) As Long
说明
删除指定的菜单。如菜单属于另一个菜单的一部分,或直接分配给一个窗口,那么菜单会在窗口清除后被自动删除
返回值
Long,非零表示成功,零表示失败。会设置GetLastError
参数表
参数 类型及说明
hMenu Long,欲删除菜单的句柄
iwzw 2002-02-23
  • 打赏
  • 举报
回复
关注

742

社区成员

发帖
与我相关
我的任务
社区描述
VB 版八卦、闲侃,联络感情地盘,禁广告帖、作业帖
社区管理员
  • 非技术类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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