SendInput()函数:
SendInput()函数用于合成键盘事件和鼠标事件,用来模拟鼠标或者键盘操作。
UINT SendInput(
[in] UINT cInputs,
[in] LPINPUT pInputs,
[in] int cbSize
);
cInputs
类型:UINT(32位无符号整数)
函数SendInput()第二个参数pInputs的数组个数,可用ARRAYSIZE( )方式获取
pInputs
类型:LPINPUT
INPUT结构体指针,实例化对象时每个对象代表一个模拟操作动作
cbSize
类型:int
输入结构的大小(以字节为单位),可用sizeof( )方式获取
返回值类型
类型:UINT
该函数返回它成功插入键盘或鼠标输入流的事件数,如果函数返回零,则输入已被另一个线程阻止。若要获取扩展的错误信息,请调用 GetLastError。
INPUT结构体
原型:
typedef struct tagINPUT {
DWORD type;
union {
MOUSEINPUT mi;
KEYBDINPUT ki;
HARDWAREINPUT hi;
} DUMMYUNIONNAME;
} INPUT, *PINPUT, *LPINPUT;
参数:type
类型:DWORD
成员type可以是以下值之一
| 参数 | 意义 |
|---|---|
| INPUT_MOUSE 0 | 该事件是鼠标事件。使用联合的 mi 结构。 |
| INPUT_KEYBOARD 1 | 该事件是键盘事件。使用联合的 ki 结构。 |
| INPUT_HARDWARE 2 | 该事件是硬件事件。使用联合的 hi 结构 |
参数:DUMMYUNIONNAME
类型:union
成员DUMMYUNIONNAME为联合体
成员type中的值分别对应DUMMYUNIONNAME参数
INPUT_MOUSE->mi
INPUT_KEYBOARD->ki
HARDWAREINPUT->hi
mi/ki/hi的类型分别对应的是结构体MOUSEINPUT,KEYBDINPUT,HARDWAREINPUT
看到这可能有点乱,我们用一张导图整理一下

下面我们看看
MOUSEINPUT KEYBDINPUT HARDWAREINPUT 这三个结构体
原型
typedef struct tagMOUSEINPUT {
LONG dx;
LONG dy;
DWORD mouseData;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT, *LPMOUSEINPUT;
参数:dx,dy
类型:LONG
dx,dy默认为鼠标移动相对数值(与上次位置变化相比),若想用其绝对数值需要在dwFlags成员里面使用MOUSEEVENTF_ABSOLUTE标识符
参数:mouseDate
类型:DWORD
1.如果 dwFlags 包含MOUSEEVENTF_WHEEL,则 mouseData 表明指定滚轮移动量。正值表示滚轮向前旋转;负值表示滚轮向后旋转。
2.如果 dwFlags 包含MOUSEEVENTF_XDOWN或MOUSEEVENTF_XUP,则 mouseData 指定按下或释放了哪些 X 按钮。此值可以是以下的任意组合
| 残数 | 意义 |
|---|---|
| XBUTTON1 0x0001 | 设置是按下还是松开第一个 X 按钮。 |
| XBUTTON2 0x0002 | 设置是按下还是松开第二个 X 按钮。 |
如果dwFlags里面没有 MOUSEEVENTF_XDOWN ,MOUSEEVENTF_XUP , mouseData
这三个标识符,则我们把mouseData置为0;
参数:dwFlags
类型:DWORD
此值可以是以下的任意组合
| MOUSEEVENTF_MOVE 0x0001 | 鼠标事件 |
| MOUSEEVENTF_LEFTDOWN 0x0002 | 鼠标左键按下 |
| MOUSEEVENTF_LEFTUP 0x0004 | 鼠标左键释放 |
| MOUSEEVENTF_RIGHTDOWN 0x0008 | 鼠标右键按下 |
| MOUSEEVENTF_RIGHTUP 0x0010 | 鼠标右键释放 |
| MOUSEEVENTF_MIDDLEDOWN 0x0020 | 鼠标中部按下 |
| MOUSEEVENTF_MIDDLEUP 0x0040 | 鼠标中部释放 |
| MOUSEEVENTF_XDOWN 0x0080 | 鼠标侧键按下 |
| MOUSEEVENTF_XUP 0x0100 | 鼠标侧键释放 |
| MOUSEEVENTF_WHEEL 0x0800 | .鼠标滚轮移动,移动数值在mouseData指定 |
| MOUSEEVENTF_ABSOLUTE 0x8000 | 若使用此值,则说明成员dxdy为绝对坐标,坐标 (0,0) 映射到显示表面的左上角;坐标 (65535,65535) 映射到右下角。在多显示器系统中,坐标映射到主显示器。 |
参数:time
类型:DWORD
事件的时间戳(以毫秒为单位)。如果此参数为 0,系统将提供自己的时间戳。
参数:dwExtraInfo
类型:DWORD
与鼠标事件关联的附加值。应用程序调用 GetMessageExtraInfo 来获取此额外信息。
原型
typedef struct tagKEYBDINPUT {
WORD wVk;
WORD wScan;
DWORD dwFlags;
DWORD time;
ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT, *LPKEYBDINPUT;
参数:wVk
类型:word
虚拟键盘代码.
参数:dwFlags
类型:DWORD
此值可以是以下的数值
| KEYEVENTF_KEYUP 0x0002 | 如果指定,则正在释放按键。如果未指定,则正在按下该键。 |
示范代码
//**********************************************************************
//
// Sends Win + D to toggle to the desktop
//按下win+D键示例
//**********************************************************************
void ShowDesktop()
{
OutputString(L"Sending 'Win-D'\r\n");
INPUT inputs[4] = {};
ZeroMemory(inputs, sizeof(inputs));
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VK_LWIN;
inputs[1].type = INPUT_KEYBOARD;
inputs[1].ki.wVk = VK_D;
inputs[2].type = INPUT_KEYBOARD;
inputs[2].ki.wVk = VK_D;
inputs[2].ki.dwFlags = KEYEVENTF_KEYUP;
inputs[3].type = INPUT_KEYBOARD;
inputs[3].ki.wVk = VK_LWIN;
inputs[3].ki.dwFlags = KEYEVENTF_KEYUP;
UINT uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
if (uSent != ARRAYSIZE(inputs))
{
OutputString(L"SendInput failed: 0x%x\n", HRESULT_FROM_WIN32(GetLastError()));
}
}
封装的两个函数
#define Press 1
#define Realse 0
/*成员dx,dy为移动为xy距离,absolute为移动是否相对值,成功返回1*/
/*Virtually为虚拟键码,Status为状态按下Press或者Realse*/
BOOL MouseEvent(int dx, int dy, bool absolute);
BOOL KeyBoardEvent(unsigned int VirtualKey, bool Status);
BOOL MouseEvent(int dx, int dy, bool absolute)
{
INPUT inputs[1] = {};
ZeroMemory(inputs, sizeof(inputs));
inputs[0].type = INPUT_MOUSE;
inputs[0].mi.dx = dx;
inputs[0].mi.dy = dy;
inputs[0].mi.mouseData = 0;
if (absolute == 1)
{
inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
}
else if (absolute == 0)
{
inputs[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
}
UINT uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
if (uSent != ARRAYSIZE(inputs))
{
cout << "SendInput failed: 0x%x\n" << HRESULT_FROM_WIN32(GetLastError());
return 0;
}
else
{
cout << "Success" << endl;
return 1;
}
}
BOOL KeyBoardEvent(unsigned int VirtualKey, bool Status)
{
INPUT inputs[1] = {};
ZeroMemory(inputs, sizeof(inputs));
inputs[0].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = VirtualKey;
if (Status == Press)
{
}
else if (Status == Realse)
{
inputs[0].ki.dwFlags = KEYEVENTF_KEYUP;
}
UINT uSent = SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));
if (uSent != ARRAYSIZE(inputs))
{
cout << "SendInput failed: 0x%x\n" << HRESULT_FROM_WIN32(GetLastError());
return 0;
}
else
{
cout << "Success" << endl;
return 1;
}
}
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手
假设我在Store的模型中有这个非常简单的方法:defgeocode_addressloc=Store.geocode(address)self.lat=loc.latself.lng=loc.lngend如果我想编写一些不受地理编码服务影响的测试脚本,这些脚本可能已关闭、有限制或取决于我的互联网连接,我该如何模拟地理编码服务?如果我可以将地理编码对象传递到该方法中,那将很容易,但我不知道在这种情况下该怎么做。谢谢!特里斯坦 最佳答案 使用内置模拟和stub的rspecs,你可以做这样的事情:setupdo@subject=MyCl
在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定
我有一个gem,它有一个根据Rails.env的不同行为的方法:defself.envifdefined?(Rails)Rails.envelsif...现在我想编写一个规范来测试这个代码路径。目前我是这样做的:Kernel.const_set(:Rails,nil)Rails.should_receive(:env).and_return('production')...没关系,只是感觉很丑。另一种方法是在spec_helper中声明:moduleRails;end而且效果也很好。但也许有更好的方法?理想情况下,这应该有效:rails=double('Rails')rails.sho
我有一个rspec模拟对象,一个值赋给了属性。我正在努力在我的rspec测试中满足这种期望。只是想知道语法是什么?代码:defcreate@new_campaign=AdCampaign.new(params[:new_campaign])@new_campaign.creationDate="#{Time.now.year}/#{Time.now.mon}/#{Time.now.day}"if@new_campaign.saveflash[:status]="Success"elseflash[:status]="Failed"endend测试it"shouldabletocreat
我正在尝试测试命令行工具的输出。如何使用rspec来“伪造”命令行调用?执行以下操作不起作用:it"shouldcallthecommandlineandreturn'text'"do@p=Pig.new@p.should_receive(:run).with('my_command_line_tool_call').and_return('resulttext')end如何创建stub? 最佳答案 使用newmessageexpectationsyntax:规范/虚拟规范.rbrequire"dummy"describeDummy
文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景 最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。 在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记
我有一个或多或少这样的场景classAdefinitialize(&block)b=B.new(&block)endend我正在对A类进行单元测试,我想知道B#new是否正在接收传递给A#new的block。我使用Mocha作为模拟框架。这可能吗? 最佳答案 我用Mocha和RSpec都试过了,虽然我可以通过测试,但行为不正确。从我的实验中,我得出结论,验证block是否已通过是不可能的。问题:为什么要传递一个block作为参数?block将用于什么目的?什么时候调用?也许这确实是您应该用类似的东西测试的行为:classBlockP