DNF模拟按键问题,试过很多方法,想消息队列win2012添加消息队列,keybd_event,都试过,不行,winio驱动级模拟签名问题

Python Selenium —— 文件上传、下载,其实很简单 - 简书
Python Selenium —— 文件上传、下载,其实很简单
很多selenium学习者被浏览器弹出的文件上传、下载框折磨的痛不欲生,今天博主就带你们轻松搞定上传和下载问题。
文件上传是所有UI自动化测试都要面对的一个头疼问题,要处理这个问题,我们需要:
首先,要区分出上传按钮的种类,大体上可以分为两种,一种是input框,另外一种就比较复杂,通过js、flash等实现,标签非input
接下来,我们分别对这两种进行分析:
1.input标签
众所周知,&input&标签是可以直接send_keys的,这里也不例外,来看代码示例:
# -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://sahitest.com/demo/php/fileUpload.htm')
upload = driver.find_element_by_id('file')
upload.send_keys('d:\\baidu.py')
# send_keys
print upload.get_attribute('value')
# check value
driver.quit()
很明显,对于input上传,直接send_keys是最简单的解决方案。
2.非input型上传
接下来难度要升级了,对于那些不是input框实现的上传怎么办,这种上传千奇百怪,有用a标签的,有用div的,有用button的,有用object的,我们没有办法通过直接在网页上处理掉这些上传,唯一的办法就是打开OS弹框,去处理弹框。
问题又来了,OS弹框涉及的层面已经不是selenium能解决的了,怎么办?很简单,用OS层面的操作去处理呗,到这里我们基本找到了问题的处理方法。
大体上有以下几种解决方案:
autoIT,借助外力,我们去调用其生成的au3或exe文件。
Python pywin32库,识别对话框句柄,进而操作
SendKeys库
keybd_event,跟3类似,不过是模拟按键,ctrl+a,ctrl+c, ctrl+v...
目前我只知道以上四种办法,有其他方法的请留言告诉我,让我学习一下。
我们依次看一下:
对于OS弹框,上传、下载等,均可以用 autoit 进行处理,简单上传很简单,博主这里还要交给你怎么通过传参对要传的文件进行参数化:
想要参数化传入的参数,可以通过autoit的命令行参数:
D:\& myProg.exe param1 "This is a string parameter" 99
在脚本中,可用以下变量获取命令行参数:
$CmdLine[0] ; = 3
$CmdLine[1] ; = param1
$CmdLine[2] ; = "This is a string parameter"
$CmdLine[3] ; = 99
$CmdLineR = 'param1 "This is a string parameter" 99'
$CmdLine[0] 获取的是命令行参数的总数,在上例中$CmdLine[0]=3
$CmdLine[1]~$CmdLine[63] 获取的是命令行参数第1到第63位,这个方式最多只能获取63个参数,不过正常情况下是足够用的
$CmdLineRaw 获取的是未拆分的所有参数,是一个长字符串,这种情况下不局限与63个参数
下面我们小小实践一下:
通过autoit的获取对象并编辑脚本:
ControlFocus("文件上传", "", "Edit1")
WinWait("[CLASS:#32770]", "", 10)
ControlSetText("文件上传" ,"", "Edit1", $CmdLine[1])
Sleep(2000)
ControlClick("文件上传", "","Button1");
通过Aut2Exe工具将脚本转成exe文件(upfile.exe)
我们先通过命令行试试,打开网页上传弹框,然后在cmd中执行该脚本:
D:\& upfile.exe "D:\1.html"
接下来就是用Python用os模块来调用该文件了:
# -*- coding: utf-8 -*-
from selenium import webdriver
import time
driver = webdriver.Firefox()
driver.get('http://www.sahitest.com/demo/php/fileUpload.htm')
driver.find_element_by_id('file').click()
time.sleep(1)
os.system('D:\\upfile.exe "D:\\1.html"')
# 这里可以对传参进行参数化,我们可以通过py脚本来控制所要上传的文件了
time.sleep(3)
driver.quit()
执行,成功!
接下来这里有个小问题要提醒你,关于OS弹框的title,不同浏览器是不一样的,一般firefox是“文件上传”、chrome叫“打开”、而IE则叫“选择要加载的文件”,对于这个问题,你可以写三个不同脚本,在处理弹框的方法中根据浏览器类型的不同而进行选择,或者每次去获取所有类型弹框,再或者通过参数传入该弹框的名称。具体怎么去应用就要考考你了。
2.win32gui
废话不多说,上代码先:
# -*- coding: utf-8 -*-
from selenium import webdriver
import win32gui
import win32con
import time
dr = webdriver.Firefox()
dr.get('http://sahitest.com/demo/php/fileUpload.htm')
upload = dr.find_element_by_id('file')
upload.click()
time.sleep(1)
# win32gui
dialog = win32gui.FindWindow('#32770', u'文件上传')
ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None)
ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None)
# 上面三句依次寻找对象,直到找到输入框Edit对象的句柄
button = win32gui.FindWindowEx(dialog, 0, 'Button', None)
# 确定按钮Button
win32gui.SendMessage(Edit, win32con.WM_SETTEXT, None, 'd:\\baidu.py')
# 往输入框输入绝对地址
win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)
# 按button
print upload.get_attribute('value')
在这里你需要一个非常重要的小工具:Spy++,百度一下有很多,当然你也可以用autoIT自带的工具,不过没有这个好用,建议去下一个吧。
而且,你得安装pywin32的库,你可以到找到对应你Python版本的库,注意32位还是64位一定要和你安装的Python版本对应。
安装完成之后在【开始菜单Python的文件夹】里看到PyWin32的文档【Python for Windows Documentation】,你能从中找到对应的方法API。
简单介绍几个用到的:
win32gui.FindWindow(lpClassName=None, lpWindowName=None):
自顶层窗口开始寻找匹配条件的窗口,并返回这个窗口的句柄。
lpClassName:类名,在Spy++里能够看到
lpWindowName:窗口名,标题栏上能看到的名字
代码示例里我们用来寻找上传窗口,你可以只用其中的一个,用classname定位容易被其他东西干扰,用windowname定位不稳定,不同的上传对话框可能window_name不同,怎么定位取决于你的情况。
win32gui.FindWindowEx(hwndParent=0, hwndChildAfter=0, lpszClass=None, lpszWindow=None)
搜索类名和窗体名匹配的窗体,并返回这个窗体的句柄。找不到就返回0。
hwndParent:若不为0,则搜索句柄为hwndParent窗体的子窗体。
hwndChildAfter:若不为0,则按照z-index的顺序从hwndChildAfter向后开始搜索子窗体,否则从第一个子窗体开始搜索。
lpClassName:字符型,是窗体的类名,这个可以在Spy++里找到。
lpWindowName:字符型,是窗口名,也就是标题栏上你能看见的那个标题。
代码示例里我们用来层层寻找输入框和寻找确定按钮
win32gui.SendMessage(hWnd, Msg, wParam, lParam)
hWnd:整型,接收消息的窗体句柄
Msg:整型,要发送的消息,这些消息都是windows预先定义好的,可以参见
wParam:整型,消息的wParam参数
lParam:整型,消息的lParam参数
代码示例里我们用来向输入框输入文件地址以及点击确定按钮
至于win32ui模块以及其他的方法,这里不进行更多描述,想要了解的自行百度或看pywin32文档。
3.SendKeys
首先要安装SendKeys库,可以用pip安装
pip install SendKeys
代码示例:
# -*- coding: utf-8 -*-
from selenium import webdriver
import win32gui
import win32con
import time
dr = webdriver.Firefox()
dr.get('http://sahitest.com/demo/php/fileUpload.htm')
upload = dr.find_element_by_id('file')
upload.click()
time.sleep(1)
# SendKeys
SendKeys.SendKeys('D:\\baidu.py')
# 发送文件地址
SendKeys.SendKeys("{ENTER}") # 发送回车键
print upload.get_attribute('value')
通过SendKeys库可以直接向焦点里输入信息,不过要注意在打开窗口是略微加一点等待时间,否则容易第一个字母send不进去(或者你可以在地址之前加一个无用字符),不过我觉得这种方法很不稳定,不推荐。
4.keybd_event
win32api提供了一个keybd_event()方法模拟按键,不过此方法比较麻烦,也不稳定,所以很不推荐,下面给出部分代码示例,如果想要研究,自己百度去学习吧。
# 先找一个input框,输入想要上传的文件的地址,剪切到剪贴板
video.send_keys('C:\\Users\\Administrator\\Pictures\\04b20919fc78baf41fc993fd8ee2c5c9.jpg')
video.send_keys(Keys.CONTROL, 'a')
# selenium的send_keys(ctrl+a)
video.send_keys(Keys.CONTROL, 'x')
# (ctrl+x)
driver.find_element_by_id('uploadImage').click()
# 点击上传按钮,打开上传框
# 粘贴(ctrl + v)
win32api.keybd_event(17, 0, 0, 0)
# 按下按键 ctrl
win32api.keybd_event(86, 0, 0, 0)
# 按下按键 v
win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0)
# 升起按键 v
win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0)
# 升起按键 ctrl
time.sleep(1)
# 回车(enter)
win32api.keybd_event(13, 0, 0, 0)
# 按下按键 enter
win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0)
# 升起按键 enter
是不是很麻烦,当然,你甚至可以用按键把整个路径输入进去,不过,我想没人愿意这么做的。而且在此过程中你不能随意移动鼠标,不能使用剪贴板,太不稳定了,所以非常不建议你用这种办法。。
3.多文件上传
接下来还有一种情况值得我们考虑,那就是多文件上传。如何上传多个文件,当然我们还是往输入框里输入文件路径,所以唯一要搞清楚的就是多文件上传时,文件路径是怎么写的。
我来告诉你吧,多文件上传就是在文件路径框里用引号括起单个路径,然后用逗号隔开多个路径,就是这么简单,例如:
"D:\\a.txt" "D:\\b.txt"
但需要注意的是:只有多个文件在同一路径下,才能这样用,否则是会失败的(下面的写法是不可以的):
"C:\\a.txt" "D:\\b.txt"
接下里找一个例子试试:
示例网址:
# -*- coding: utf-8 -*-
from selenium import webdriver
import win32gui
import win32con
import time
dr = webdriver.Firefox()
dr.get('http://www.sucaijiayuan.com/api/demo.php?url=/demo/')
dr.switch_to.frame('iframe')
# 一定要注意frame
dr.find_element_by_class_name('filePicker').click()
time.sleep(1)
dialog = win32gui.FindWindow('#32770', None)
ComboBoxEx32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None)
ComboBox = win32gui.FindWindowEx(ComboBoxEx32, 0, 'ComboBox', None)
Edit = win32gui.FindWindowEx(ComboBox, 0, 'Edit', None)
button = win32gui.FindWindowEx(dialog, 0, 'Button', None)
# 跟上面示例的代码是一样的,只是这里传入的参数不同,如果愿意可以写一个上传函数把上传功能封装起来
win32gui.SendMessage(Edit, win32con.WM_SETTEXT, 0, '"d:\\baidu.py" "d:\\upload.py" "d:\\1.html"')
win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)
print dr.find_element_by_id('status_info').text
选中3张文件,共1.17KB。
可见,多文件上传并没有那么复杂,也很简单,唯一的区别就是输入的参数不同而已。autoIT也可以实现,有兴趣可以自己试试。
而且我们可以发现一点,就是上面的这个窗口的代码跟之前示例中的基本是一样,说明我们可以把上传的部分抽出来,写一个函数,这样每次要上传,直接去调用函数,传入参数即可。
看,上传其实很好处理,你有什么好的办法也可以给博主留言,共同交流。
接下来我们看看文件下载,很多人不会处理弹出的文件下载框。其实跟上传类似,可以用autoit和win32api解决,方法类似,我们不在举例了,可以根据上面所讲的上传来改写。这里博主想讲讲一种更漂亮的处理办法,那就是指定下载路径,不弹出弹框,直接下载到指定路径。
主要针对Firefox和Chrome浏览器,其他浏览器未曾去寻找这方面的资料。
Firefox 文件下载
对于Firefox,需要我们设置其Profile:
browser.download.dir:指定下载路径
browser.download.folderList:设置成 2 表示使用自定义下载路径;设置成 0 表示下载到桌面;设置成 1 表示下载到默认路径
browser.download.manager.showWhenStarting:在开始下载时是否显示下载管理器
browser.helperApps.neverAsk.saveToDisk:对所给出文件类型不再弹出框进行询问
下面来个示例:
# -*- coding: utf-8 -*-
from selenium import webdriver
from time import sleep
profile = webdriver.FirefoxProfile()
profile.set_preference('browser.download.dir', 'd:\\')
profile.set_preference('browser.download.folderList', 2)
profile.set_preference('browser.download.manager.showWhenStarting', False)
profile.set_preference('browser.helperApps.neverAsk.saveToDisk', 'application/zip')
driver = webdriver.Firefox(firefox_profile=profile)
driver.get('http://sahitest.com/demo/saveAs.htm')
driver.find_element_by_xpath('//a[text()="testsaveas.zip"]').click()
driver.quit()
Firefox需要针对每种文件类型进行设置,这里需要我们查询对应文件的MIME类型,可以用以下链接进行查询:
Chrome 文件下载
Chrome浏览器类似,设置其options:
download.default_directory:设置下载路径
profile.default_content_settings.popups:设置为 0 禁止弹出窗口
它的设置就简单多了,看个示例:
# -*- coding: utf-8 -*-
from selenium import webdriver
from time import sleep
options = webdriver.ChromeOptions()
prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': 'd:\\'}
options.add_experimental_option('prefs', prefs)
driver = webdriver.Chrome(executable_path='D:\\chromedriver.exe', chrome_options=options)
driver.get('http://sahitest.com/demo/saveAs.htm')
driver.find_element_by_xpath('//a[text()="testsaveas.zip"]').click()
driver.quit()
看,文件下载也很简单吧。如果你还有任何想法,欢迎给博主留言。
更多关于python selenium的文章,请关注我的CSDN专栏:
更多技术博客见http://blog.csdn.net/huilan_same
文件上传是做UI自动化测试时候的一个大问题,尝试了一下网上各种上传文件的方式,以下试验按照使用频率来排名。(多个方法多个思路,你要不想学“茴”字的四种写法,看第一个就够了) 环境准备: 一个可以带有上传文件按钮的网页(把以下代码拷贝到一个新建文本文档中,可以取名为fileu...
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金相信有很多朋友...
《裕语言》速成开发手册3.0 官方用户交流:iApp开发交流(1) iApp开发交流(2) iApp开发交流(3) iApp开发交流(4) iApp开发交流(5) iApp游戏开发交流...
发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注
09:45字数 61697阅读 3316评论 2喜欢 85 用到的组件 1、通过CocoaPods安装 项目名称 项目信息 AFNetworking 网络请求组件 FM...
《ilua》速成开发手册3.0 官方用户交流:iApp开发交流(1) iApp开发交流(2) iApp开发交流(3) iApp开发交流(4) iApp开发交流(5) iApp游戏开发交...
如果你是小草,单位就是你的地。如果你是小鸟,单位就是你的天。如果你是一条鱼,单位就是你的海。如果你是一只狼,单位就是你跃马驰骋的战场。家庭离不了你,但你离不了单位。 没有单位,你,什么也不是! 单位是你和社会之间和他人之间进行交换的桥梁。单位是你显示自己存在的舞台。单位是你...
人啊,吃着杂碎面,唱着牧羊曲,听着冷风歌,想着白日梦,睡在支影床,活在后半夜! 说不出的有闲话,看不到的过昨天,笑不出的冷面鬼,听不到的枕边风,不过就是一个半面人! 有意思的世界产出了空洞的人!
以前对仪式感这东西没有太在意。最近看了一篇仪式感的文章,再对应看看身边发生的事,觉得那句没有仪式感的爱情不会太长久,也是有一定道理的。
不肯花心思給你仪式感的人,他是真的很爱你吗?
月初,好友过生日。在她过生日之前我还开玩笑的说,今年你男票要怎么給你...
孩子上甲骨文课,创作了些甲骨文画,清纯的图画,童真的世界。孩子眼中,公司商业,男耕女织都是一种生活,分工和协作创造家庭的祥和世界。孩子的世界,只有童真,没有江湖。 成人的世界,修身齐家为治国平天下,这还是仁者的视角。凡夫常谓:人在江湖,身不由己。江湖的习气多了,就忘了行路的...Windows提供了一个模拟键盘API函数Keybd_event(),使用该函数可以相应的屏蔽键盘的动作。Keybd_event()函数能触发一个按键事件,也就是说会产生一个WM_KEYDOWN或WM_KEYUP消息。
该函数原型如下:
  VOID keybd_event(
  BYTE bVk, // virtual-key code
  BYTE bScan, // hardware scan code
  DWORD dwFlags, // flags specifying various function options
  DWORD dwExtraInfo // additional data associated with keystroke
  从原型可以看出,Keybd_event()共有四个参数:
第一个为按键的虚拟键值,如回车键为vk_return, tab键为vk_tab(其他具体的参见附录:常用模拟键的键值对照表);
第二个参数为扫描码,一般不用设置,用0代替就行;
第三个参数为选项标志,如果为keydown则置0即可,如果为keyup则设成"KEYEVENTF_KEYUP";
第四个参数一般也是置0即可。
例子1:模拟按下'A'键
   keybd_event(65,0,0,0);
   keybd_event(65,0,KEYEVENTF_KEYUP,0);
例子2:模拟按下'ALT+F4'键
   keybd_event(18,0,0,0);
   keybd_event(115,0,0,0);
   keybd_event(115,0,KEYEVENTF_KEYUP,0);
   keybd_event(18,0,KEYEVENTF_KEYUP,0);
附:常用模拟键的键值对照表(也可参考)
键盘键与虚拟键码对照表
      字母和数字键 数字小键盘的键功能键
      键   键码 
 键   键码    键   键码   
键    键码
      A   65  
0   96     F1   112   Backspace    8
      B   66  
1   97     F2   113   Tab       9
      C   67   
2   98  
  F3   114  
Clear      12
      D   68   3   99     F4   115  Enter      13
      E   69   
4   100    F5   116  Shift      16
      F   70   
5   101    F6   117  Control     17
      G   71   
6   102    F7   118   Alt       18
      H   72    7   103    F8   119  Caps Lock    20
      I   73    8   104    F9   120  Esc       27
      J   74    9   105    F10  121  Spacebar    32
      K   75    *   106 
  F11  122  Page Up     33
      L   76    +   107  
 F12  123  Page Down    34
      M   77    Enter 108    --   --   End       35
      N   78    -   109    --   --    Home      36
      O   79    .   110    --   --     Left Arrow   37
      P   80    /   111    --   --     Up Arrow    38
      Q   81    --   --     --   --     Right Arrow   39
      R   82    --   --    --   --      Down Arrow    40
      S   83    --   --     --   --     Insert      45
      T   84    --   --     --   --     Delete      46
      U   85    --   --     --   --     Help       47
      V   86    --   --    --   --     Num Lock     144
      W   87          
      X   88      
      Y   89      
      Z   90      
      0   48      
      1   49      
      2   50       
      3   51       
      4   52       
      5   53       
      6   54       
      7   55       
      8   56       
      9   57  
模拟键盘平时不是很常用, 但是当调用某些快捷键执行某项功能时, 它真的是那么的方便呀.
看看下面的实现, 你就会大呼: 为什么不早点告诉我?
原来没有blog呀,
都靠这些挣分呢.
1) 显示桌面:
很多软件有显示桌面的功能, 并且大家的方法都是遍历窗口,
然后让它们最小化, 其实 win系统给咱们了一个非常方便的WIN键(就是键盘上在CTRL键和ALT键之间的那个带win标志的按键), 利用它, 可以轻松的完成显示桌面的功能.
keybd_event(VK_LWIN, 0, 0 ,0);
keybd_event('M', 0, 0 ,0);
keybd_event('M', 0, KEYEVENTF_KEYUP ,0);
keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0);
其他的操作也类似, 比如直接显示开始的运行,就把上面的'M'换成'R'即可。
keybd_event(VK_LWIN, 0, 0 ,0);
keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0);
直接显示“开始”对话框了。
2) 实现快速的全选
很多的时候,比如listctrl实现全选,你可以用listctrl循环设置每一项的状态为选中,多罗索的事情呀。用快捷键试一试CTRL+A,其他的快捷键一样的用法,呵呵,你知道怎么办了吧?
keybd_event(VK_CONTROL, (BYTE)0, 0 ,0);
keybd_event('A',(BYTE)0, 0 ,0); //此处可以用
'A', (BYTE)65, 用'a'不起作用.
keybd_event('A', (BYTE)0, KEYEVENTF_KEYUP,0);
keybd_event(VK_CONTROL, (BYTE)0, KEYEVENTF_KEYUP,0);
3) 执行某些特殊的键,比如数字键,大小写,下面是数字键的例子
bool bState=
//true为按下NumLock,false反之
BYTE keyState[256];
GetKeyboardState((LPBYTE)&keyState);
if( (bState && !(keyState[VK_NUMLOCK] & 1)) ||
(!bState && (keyState[VK_NUMLOCK] & 1)) )
// Simulate a key press
keybd_event( VK_NUMLOCK,
KEYEVENTF_EXTENDEDKEY | 0,
// Simulate a key release
keybd_event( VK_NUMLOCK,
KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
4) 你想CTRL+ALT+DELETE三键一起按下,
keybd_event(VK_CONTROL, 0, 0 ,0);
keybd_event(VK_MENU,0, 0 ,0);
keybd_event(VK_DELETE,0, 0 ,0);
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP ,0);
keybd_event(VK_MENU,0, KEYEVENTF_KEYUP ,0);
keybd_event(VK_DELETE,0, KEYEVENTF_KEYUP ,0);
呵呵,这样不会成功呀,因为这几个键直接是操作系统来截获执行的,而模拟键盘只能发向应用程序,所以这种方法不行的(想显示锁定对话框,用
LockWorkStation();)
5) Window2000/NT/XP已经不提倡用这个函数了,上面的方法只是为了让大家开阔一下思路,怎么替代呢,呵呵,看下面,所以上面的所有代码都可以用这个来完成
//2000下用这个代替 ,包含 "winable.h"
INPUT input[4];
memset(input, 0, sizeof(input));
input[0].type = input[1].type = input[2].type = input[3].type = INPUT_KEYBOARD;
input[0].ki.wVk
= input[3].ki.wVk = VK_LWIN;
input[1].ki.wVk
= input[2].ki.wVk = 'R';
//接下来释放它,这一点很重要。
input[2].ki.dwFlags = input[3].ki.dwFlags = KEYEVENTF_KEYUP;
input[0].ki.time = input[1].ki.time = input[2].ki.time = input[3].ki.time = GetTickCount();
SendInput(4, input, sizeof(INPUT));
感觉比那个有点罗索,呵呵。
====================
附WIN键的部分快捷键:
WIN键+D=快速的切到桌面,再次点击返回
WIN键+E=快速打开资源管理器
WIN键+R=“运行”。
WIN键+M=全部视窗最小化。
WIN键+Shift+M=取消全部视窗最小化。
WIN键+F1=Help。
WIN键+F=“寻找”。
WIN键+Ctrl+F=显示“查找电脑”。
WIN键+Tab=切换工作列的程式。
WIN键+Break=显示系统内容。
******************************************************************************************
关于SendMessage keybd_event
PostMessage
******************************************************************************************
首先你会发现keybd_event函数中是没有窗口句柄作为参数的,好奇的你一定会觉得很奇怪,那是因为,keybd_event是全局模拟按键的,只对前台窗口(即当前的活动窗口)才可以,但是如果模拟的按键正好也是某个窗口的全局热键消息,那该窗口也能接收到的
而SendMessage 、PostMessage是对指定句柄窗口都其作用的,对于做一些一外挂是非常有用的。例如可以做成这样的效果:即用SendMessage/PostMessage在某一个窗口模拟动作,而同时自己可以在其他窗口做其他事情,互不影响的!
但是有一点要注意,很多人在模拟键盘消息的时候,都会忘记模拟WM_KEYUP的消息。。。
还有一点就是,PostMessage中的窗口句柄参数,可以设置为HWND_BROADCAST,即广播,但不要理所当然地认为是对所有的窗口都起作用!!!它只对系统的顶层窗口起作用,子窗口是收不到这个消息的!!!
还要注意的是SendMessage是没有HWND_BROADCAST参数的,那是因为,SendMessage总是等发送的消息在对应的窗口消息队列中处理完毕后才返回的(这是一种负责的行为), 细想一下就知道为什么SendMessage没有HWND_BROADCAST参数了!!
  1. 当需要模拟键盘输入命令时,比如Ctrl + V,选择keybd_event;
  2. 当需要模拟键盘输入一串字符时,选择PostKeybdMessage;
  3. 当需要模拟键盘输入单个字符时,选择keybd_event。
SendMessage(Button.Handle,WM_LBUTTONDOWN,0,0);  鼠标左键按下 SendMessage(Button.Handle,WM_LBUTTONUP,0,0);   鼠标左键抬起SendMessage(Edit.Handle,WM_SETTEXT,255,Integer(PChar('abc'))); 传递文本SendMessage(Edit.Handle,WM_Char,Wparam('Q'),2);  传递字符SendMessage(Button.Handle,BM_SETSTYLE,BS_RADIOBUTTON,1);  改变Button风格SendMessage(ComboBox.Handle,CB_SETDROPPEDWIDTH,300,0);  改变CBDownWidthWM_CUT、WM_COPY和WM_PASTE  剪切,复制,粘帖 实现任意组合键keybd_event(VK_Control, MapVirtualKey(VK_Control, 0), 0, 0);keybd_event(ord('V'),
MapVirtualKey(ord('V'), 0), 0, 0);keybd_event(ord('V'),
MapVirtualKey(ord('V'), 0),
KEYEVENTF_KEYUP, 0); keybd_event(VK_Control, MapVirtualKey(VK_Control, 0),
KEYEVENTF_KEYUP, 0);
模拟鼠标按下事件
::PostMessage(hwd0,WM_MOUSEMOVE, MK_LBUTTON, MAKELONG(x,y));
::PostMessage(hwd0,WM_LBUTTONDOWN,MK_LBUTTON,MAKELPARAM(x,y));
::PostMessage(hwd0,WM_LBUTTONUP,MK_LBUTTON,MAKELPARAM(x,y));
模拟键盘按下事件
keybd_event(VK_TAB,0,0,0);
keybd_event(VK_TAB,0,KEYEVENTF_KEYUP,0);
keybd_event常量符号 含义
利用键盘事件keybd_event(Win32 API)模拟键盘按键
(pywin32)解决keybd_event在游戏中失效
模拟键盘API函数Keybd_event用法
利用Keybd_event()函数模拟键盘输入
没有更多推荐了,

我要回帖

更多关于 dnf怎么添加好友 的文章

 

随机推荐