后台模拟按键Alt+F的困惑

nstmmdl 2010-11-01 02:07:53
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Private Const WM_SYSKEYDOWN = &H104
Private Const WM_SYSKEYUP = &H105

Private Sub test()

Dim hwnd As Long
hwnd = text1.text 'XXXXX表示记事本编辑框的句柄

PostMessage hwnd, WM_SYSKEYDOWN, &H46, &H10000000
PostMessage hwnd, WM_SYSKEYUP, &H46, &H10000000
' lParam解释:大家一般习惯写成16进制的,那么就应该是类似&H00 00 00 00 ,第0-15位一般为&H0001,
' 如果是按下键,那么24-31位为&H00,释放键则为&HC0;设定 29位为1按alt
end sub

以上代码对IE浏览器有效,可以模拟后台按下alt+f文件菜单生效。但对于记事本却毫无反应。
那里又问提?谁能给些提示?谢谢
...全文
671 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
nstmmdl 2010-11-02
  • 打赏
  • 举报
回复
"楼主说的IE菜单生效,是不是只是 文件 菜单变蓝,而没有弹出?"
IE菜单有弹出的。
用:Veron_04 7楼的代码,“取记事本edit窗口的句柄”在无焦点的情况下似乎可弹出菜单。我再试试。

再次谢谢大家热心回复。
dianyancao 2010-11-02
  • 打赏
  • 举报
回复
楼主说的IE菜单生效,是不是只是 文件 菜单变蓝,而没有弹出?
貌似各种菜单在没有焦点的情况下,都会自动关闭。所以可能要先获得焦点,就keybd_event吧
毕竟SendMessage,PostMessage对组合键的支持不太好。
或者试试下面的:

id = 7 '7是退出,1是新建,2是打开,3是保存...
PostMessage hwnd, WM_COMMAND, id, 0&

下面的测试了好久。

Option Explicit
Private Declare Function GetMenu Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function GetMenuItemID Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Private Declare Function GetSubMenu Lib "user32" (ByVal hMenu As Long, ByVal nPos As Long) As Long
Private Const WM_COMMAND = &H111

Private Sub Command1_Click()
Dim hFormHwnd As Long, hMainMenu As Long, hSubMenu As Long, id As Long, i%
hFormHwnd = &H5204CE '这里是记事本窗体的句柄,不是编辑框的句柄
hMainMenu = GetMenu(hFormHwnd)
hSubMenu = GetSubMenu(hMainMenu, 1)
id = GetMenuItemID(hSubMenu, 12) '这里实现了第2个弹出菜单中,第13个子项全选的功能
PostMessage hFormHwnd, WM_COMMAND, id, 0&
End Sub
cbm6666 2010-11-01
  • 打赏
  • 举报
回复
Option Explicit
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Dim HwndVal&, Rtn&
Private Sub Form_Load()
'Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
Command1.Caption = "模拟按键"
Rtn = Shell("NotePad.exe", 1)
HwndVal = FindWindow(vbNullString, "无标题 - 记事本")
If HwndVal = 0 Then MsgBox "记事本没运行": Unload Me: Exit Sub
Print "记事本的句柄是: " & CStr(HwndVal): Print
End Sub

Private Sub Command1_Click()
AppActivate Rtn '激活记事本
SendKeys ("%{f}") '激活菜单
'SendKeys ("{o}") '打开
End Sub
nstmmdl 2010-11-01
  • 打赏
  • 举报
回复
认识有可能错误,因我不是做开发的,对这些才开始学,因兴趣学学练练。但试试IE窗口,无焦点,却可以,这是困惑的地方。主要是想在目标程序在最小化等情况时也能照样操作。网上好像都叫后台模拟。
贝隆 2010-11-01
  • 打赏
  • 举报
回复 1
其实,我认为你的认识是错误的,首先一点,键盘只能向有焦点的对象发送命令,如果你想控制的窗体没有焦点,想控制它是很难实现的。
nstmmdl 2010-11-01
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 veron_04 的回复:]
这个能实现,但是必须要文本框用于焦点才行。

VB code

Option Explicit
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam ……
[/Quote]

这个在获得焦点的条件下可以,已经又进一步了,谢谢!
nstmmdl 2010-11-01
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 veron_04 的回复:]
可否考虑试用驱动级的方法?试用WinIO.Dll来操作。这样直接试用键盘输出端口。
[/Quote]
这个已试过,可以模拟很多不能模拟的,记事本也可以,但不能后台,我现在也是这样做的。易受别的程序影响。
贝隆 2010-11-01
  • 打赏
  • 举报
回复
这个能实现,但是必须要文本框用于焦点才行。

Option Explicit
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Const WM_SYSKEYUP = &H105
Private Const WM_SYSKEYDOWN = &H104
Private Sub test()
Dim lngHwnd As Long
lngHwnd = FindWindow(vbNullString, "1.txt - 记事本")
PostMessage lngHwnd, WM_SYSKEYDOWN, &H46, &H3E0001 Or &H20000000 ' 模拟按下 Alt+F
Sleep 100
PostMessage lngHwnd, WM_SYSKEYUP, &H46, &HC03E0001 Or &H20000000 ' 模拟抬起 Alt+F
End Sub
Private Sub Form_Load()
Timer1.Enabled = True
Timer1.Interval = 1000
End Sub
Private Sub Timer1_Timer()
Call test
End Sub

贝隆 2010-11-01
  • 打赏
  • 举报
回复
可否考虑试用驱动级的方法?试用WinIO.Dll来操作。这样直接试用键盘输出端口。
nstmmdl 2010-11-01
  • 打赏
  • 举报
回复
谢谢这么快速回复!

希望用后台的方式,因为这样会受到别的消息干扰,查询了很多资料,都没解决。
网上能有的都是通过postmessage来模拟,但postmessage对系统里的很多窗口
似乎不行,可能是我的方法错误。经分析,可能是那种afx:xxxx类做出的窗口菜单
就不支持。notepad.exe的edit都可以正常模拟输入,就是对菜单操作不灵。。。
hlb_it 2010-11-01
  • 打赏
  • 举报
回复
呵呵 在
贝隆 2010-11-01
  • 打赏
  • 举报
回复

Option Explicit
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Const VK_MENU = &H12 'alt key
Private Const KEYEVENTF_KEYUP = &H2
Private Sub test()
Dim hwnd As Long
hwnd = Text1.hwnd
Text1.SetFocus
keybd_event VK_MENU, 0, 0, 0
keybd_event &H46, 0, 0, 0
Sleep 500
keybd_event &H46, 0, KEYEVENTF_KEYUP, 0
keybd_event VK_MENU, 0, KEYEVENTF_KEYUP, 0
End Sub

Private Sub Command1_Click()
Call test
End Sub

nstmmdl 2010-11-01
  • 打赏
  • 举报
回复
谢谢斑竹回复,但我测试"记事本"还是不行,取IE句柄测试可以,我的系统是win2003+vb6.0
贝隆 2010-11-01
  • 打赏
  • 举报
回复

Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long,ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long


Private Const WM_KEYUP = &H101
Private Const WM_KEYDOWN = &H100
Private Const WM_SYSKEYDOWN = &H104
Private Const WM_SYSKEYUP = &H105
Private Const VK_MENU = &H12 'alt key
Private Sub test()

Dim hwnd As Long
hwnd = text1.text 'XXXXX表示记事本编辑框的句柄
PostMessage hwnd, WM_SYSKEYDOWN, VK_MENU,&H0
PostMessage hwnd, WM_SYSKEYDOWN, &H46,&H0
Sleep 50
PostMessage hwnd, WM_SYSKEYUP, &H46, &H0
PostMessage hwnd, WM_SYSKEYUP, VK_MENU,&H0
' lParam解释:大家一般习惯写成16进制的,那么就应该是类似&H00 00 00 00 ,第0-15位一般为&H0001,
' 如果是按下键,那么24-31位为&H00,释放键则为&HC0;设定 29位为1按alt
end sub

1,486

社区成员

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

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