| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4426 人关注过本帖
标题:VB Sendmessage问题
只看楼主 加入收藏
lkflsj
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-9-22
结帖率:0
收藏
 问题点数:0 回复次数:17 
VB Sendmessage问题
Private Declare Function SendMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Private Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) 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)
Const WM_KEYDOWN = &H100
Const WM_KEYUP = &H101
Const VK_F1 = &H70
Const VK_F2 = &H71
Const VK_F3 = &H72
Const VK_F4 = &H73
Const VK_F5 = &H74
Const VK_A = &H41
Const WM_CLOSE = &H10
Private Sub Command1_Click()
Shell "notepad.exe", 1
End Sub
Private Sub Command2_Click()
Dim hwd As Long
hwd = FindWindow(vbNullString, "无标题 - 记事本")
SendMessage hwd, WM_KEYDOWN, VK_F5, 0&
End Sub
Private Sub Form_Load()
Command1.Caption = "打开记事本"
Command2.Caption = "关闭记事本"
End Sub
该例子模拟按下F5有效
Private Declare Function SendMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Private Declare Function PostMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) 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)
Const WM_KEYDOWN = &H100
Const WM_KEYUP = &H101
Const VK_F1 = &H70
Const VK_F2 = &H71
Const VK_F3 = &H72
Const VK_F4 = &H73
Const VK_F5 = &H74
Const VK_A = &H41
Const WM_CLOSE = &H10
Private Sub Command1_Click()
Shell "notepad.exe", 1
End Sub
Private Sub Command2_Click()
Dim hwd As Long
hwd = FindWindow(vbNullString, "无标题 - 记事本")
SendMessage hwd, WM_KEYDOWN, VK_A, 0&
End Sub
Private Sub Form_Load()
Command1.Caption = "打开记事本"
Command2.Caption = "关闭记事本"
End Sub
该例子模拟按下A无效,求解
搜索更多相关主题的帖子: 问题 
2011-05-28 21:25
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
我翻译一下~
为何第一个例子执行时按下CommanButton2后~记事本会出现时间或按F5键~也有同样效果~
SendMessage hwd, WM_KEYDOWN, VK_F5, 0&

而第二个例子~只能按F5键才有效果~但是按一个却没第一个例子的效果~
SendMessage hwd, WM_KEYDOWN, VK_A, 0&

疑问是这样没错吧?

记得只前编写MSFlexGrid的新增滑鼠滚轮事件时~是写一个抓的IO回传数值的函式勾到系统中~当系统回传的IO数值时也顺便启动先前编写勾上的函式~
而函式依照接收到回传的IO的数值~做个别处理~例如跳出菜单之类的~
猜想也许是API内建写接收到F5键数值讯息时~会在该设定窗口内写入时间~而碰上"A"的回传数值没这段代码?

[ 本帖最后由 wube 于 2011-5-28 23:20 编辑 ]

不要選我當版主
2011-05-28 23:19
lkflsj
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-9-22
收藏
得分:0 
一般目标程序都会含有多个控件,并不是每个控件都会对键盘消息作出反应,只有把键盘消息发送给接受它的控件才会得到期望 的反应。那记事本来说,它的编辑框其实是个edit类,只有这个控件才对键盘事件有反应,如果只是把消息发给记事本的窗体,那是没有用的。

hwnd = FindWindow("Notepad", "无标题 - 记事本") '得到记事本句柄
Thwnd = FindWindowEx(hwnd, 0, "Edit", vbNullString) '得到记事本编辑区的句柄

SendMessage Thwnd , WM_KEYDOWN, VK_A, 0& '按下A键


希望对你有帮助!
这是百度提问里一位高人给的答案,还是谢谢楼上的回答
2011-05-29 07:01
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
以下是引用lkflsj在2011-5-29 07:01:36的发言:

一般目标程序都会含有多个控件,并不是每个控件都会对键盘消息作出反应,只有把键盘消息发送给接受它的控件才会得到期望 的反应。那记事本来说,它的编辑框其实是个edit类,只有这个控件才对键盘事件有反应,如果只是把消息发给记事本的窗体,那是没有用的。

hwnd = FindWindow("Notepad", "无标题 - 记事本") '得到记事本句柄
Thwnd = FindWindowEx(hwnd, 0, "Edit", vbNullString) '得到记事本编辑区的句柄

SendMessage Thwnd , WM_KEYDOWN, VK_A, 0& '按下A键


希望对你有帮助!
这是百度提问里一位高人给的答案,还是谢谢楼上的回答



我是新手~别被网站的称号误导了~只是常来学习~
照你这样一说~FindWindow + SendMessage 不就类似我上面说的控件做出来的那功能吗?
这样又多了解一点了~代码又可以缩短多了~

那顺便也问问~
照这样说~这样写就同样可以得出现在时间的代码控制参数是哪个?(虽然已经进一步得到记事本编辑区的句柄~表示写的位置确定了)
要是没参数(VK_?)来引用~表示程序写死了~这不就是说SendMessage是只能得出时间的API吗?
还是SendMessage又有什么内含的高招?请高人指示~

不要選我當版主
2011-05-29 09:50
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:653
专家分:3402
注 册:2008-5-7
收藏
得分:0 
根据楼主的提示,稍作修改,可向记事本写字符串了,最后自动关闭记事本,代码如下:
Private Declare Function SendMessage& Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any)
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Sub Command1_Click()
  Shell "notepad.exe", 1
End Sub
Private Sub Command2_Click()
  Dim hwd As Long, Thwnd As Long, i As Integer, j As Integer, l As Long, a As String
  a = "ABCDEFGHI自动向记事本写文字,看看写汉字行不,真好玩!"
  hwd = FindWindow("Notepad", "无标题 - 记事本") '得到记事本句柄
  Thwnd = FindWindowEx(hwd, 0, "Edit", vbNullString) '得到记事本编辑区的句柄
  For i = 1 To Len(a)
    l = Asc(Mid(a, i, 1))
    SendMessage Thwnd, &H286, l, 0& '写单个字符
    For j = 1 To 20000
      '延时一段时间
      DoEvents
    Next
  Next
  SendMessage hwd, &H10, 0, 0& '向Notepad发关闭窗口消息
End Sub
Private Sub Form_Load()
  Command1.Caption = "打开记事本"
  Command2.Caption = "关闭记事本"
End Sub
'在vb6中运行通过
2011-05-29 10:24
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
还是似懂非懂~感觉功用好相似又有点不相似~

这一段不完整的程序也是写撷取作业系统传回的IO讯号后处理的动作~若是改用 FindWindow + FindWindowEx + SendMessage 去处理~
1.表示虽然都一样能有钩子的功能~但是SendMessage只能做讯息处理的动作~而不能让程序产生介面~所以是不同需求才用不同的API吗?
        对API看了又看~用了又用~还是模模糊糊的很不熟的感觉~好像很多地方功能重叠但又有些微不同~懂的话可以节省很多代码长度和复杂度~

2.半懂又会到处碰壁~那钩子和API的又有什么关联性?感觉好像也都做相同的事的东西?

3.SendMessage Thwnd, &H286, l, 0& '写单个字符(之前写VK_F5可以直接带出时间字符串~怎这次要用循环来带出?)
        所以说这两个参数"ByVal wMsg As Long, ByVal wParam As Long"是有关联性?可他们的型态都是Long~不是函式来的?好怪~

不好意思这原本是别人的帖子~突然引发我的疑问~变成我在发问了~(若有高手介意分数~我可以通通给~只要能解决我心中的疑问)~
话说似懂非懂也不知道要问什么~刚好有机会才突然灵光一闪来着~

程序代码:
Public Function GetLong(hwnd As Variant, DataIn As Variant) As Long
    SetWindowLong hwnd, GWL_WNDPROC, AddressOf FlexScroll
End Function

Public Function FlexScroll(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'支持滚轮的滚动
     Select Case wMsg
     Case WM_MOUSEWHEEL
         Select Case wParam
         Case -7864320   '向下滚
             SendKeys "{PGDN}"
         Case 7864320    '向上滚
             SendKeys "{PGUP}"
         End Select
         DataText.Text = wParam
     End Select
     FlexScroll = CallWindowProc(Oldwinproc, hwnd, wMsg, wParam, lParam)
End Function


[ 本帖最后由 wube 于 2011-5-29 11:14 编辑 ]

不要選我當版主
2011-05-29 11:12
lkflsj
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-9-22
收藏
得分:0 
不知道论坛有没有知道怎么获取目标程序的控件类名,前面提到的记事本
Thwnd = FindWindowEx(hwd, 0, "Edit", vbNullString) '得到记事本编辑区的句柄
"edit"是属于类名,这个是记事本的,但比如我打开某个网络游戏的话,界面就有很多控件,每个控件都有个类名,VB中怎么查找出这些控件的类名是什么?
2011-05-29 11:17
wube
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:23
帖 子:1820
专家分:3681
注 册:2011-3-24
收藏
得分:0 
回复 7楼 lkflsj
这问题我知道~先前无意间查到过~VB6的只有Form这控件可以用对于每个去查询Form内的控件~但是放在控件中的控件可能就不行了~
因为只有Form这控件有加这功能~要找控件中的控件句柄~要.NET以上才有这功能~网址我找找~之前贴过~

不要選我當版主
2011-05-29 11:29
lkflsj
Rank: 1
等 级:新手上路
帖 子:5
专家分:0
注 册:2010-9-22
收藏
得分:0 
3.SendMessage Thwnd, &H286, l, 0& '写单个字符(之前写VK_F5可以直接带出时间字符串~怎这次要用循环来带出?)

SendMessage Thwnd, &H100, &H74, 0& 直接输出时间字符串,这里向notepad发送按下F5的按键,并不是发送时间字符串到记事本
2011-05-29 11:29
lowxiong
Rank: 12Rank: 12Rank: 12
等 级:贵宾
威 望:27
帖 子:653
专家分:3402
注 册:2008-5-7
收藏
得分:0 
回复 6楼 wube
vb使用api相对提高了运行效率,他可以直接同系统核心函数库打交道,你在学c时,经常会用到mfc的各类,其实就是包装了的api函数。对api函数要活学活用,不需要教条,我在例子中使用了&H286,其实他给sendmessage的信息就是发送字符消息(不是按键消息),常量名为WM_IME_CHAR,我只是为了减少代码量省略了常量定义。当然,vb有很丰富的函数可供使用,尽量少用api,避免程序的不稳定性,除非特殊需要,比如,你前面提到过的半透明窗体或控件,就可以用api完成。你提到的sendkeys也可以发送按键消息,但只能对当前活动的窗体发,不能对指定的窗体发。
2011-05-29 11:32
快速回复:VB Sendmessage问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.014599 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved