那么些事件与普通键盘输入一起进去应用程序的新闻循环澳门正规网上娱乐,该函数合成二反扑键事件

 http://baike.baidu.com/view/1080077.htm

 

 keybd_event
  函数功用:该函数合成一遍击键事件。系统可使用这种合成的击键事件来发生WM_KEYUP或WM_KEYDOWN音信,键盘驱动程序的间歇管理程序调用keybd_event函数。在Windows
NT中该函数己被使用SendInput来代表它。

 

————————————————– 

http://www.cnblogs.com/yedaoq/archive/2010/12/30/1922305.html

http://www.cnblogs.com/yedaoq/archive/2010/12/30/1922305.html

SendInput模拟键盘输入的主题材料

 

SendInput模拟键盘输入的标题

SendInput模拟键盘输入的主题素材

 

新近触及到这一个函数,由此领悟了一晃,计算一下列在那。

自个儿询问它的出发点是怎么着通过它向活动窗口输入字符,那是非常的多顺序都有的职能(我猜Visual
Assist X就用了这些效果)。

基于MSDN,此函数模拟按钮操作,将一些新闻插入键盘或鼠标的输入流中,Windows对它实行拍卖,生成对应的WM_KEYDOWN或WM_KEYUP事件,那几个事件与平日键盘输入一齐跻身应用程序的新闻循环,它们不只能够转变为WM_CHA揽胜极光音讯,仍是能够变换为别的(诸如加快键)等新闻。

使用它来发送字符新闻,并从未看起来那么粗略。那有多个供给怀念的主题素材:

1.
输入法的改造。举例要求向移动窗口发送一些罗马尼亚语字符,我们兴许想象那样来完成:获取对应键盘字符的杜撰键码,发送一个SendInput。但是假设运动窗口正在利用贰个输入法,那么我们发送出去的新闻,会进来输入法的Composition窗口,最后被撤换为象形文字或被吐弃。唯有当输入法关闭时,程序运维的功力才会像大家期望的那样,在活动窗口中彰显出塞尔维亚(Република Србија)语字符。

2.
对此华语字符,应该怎么发送给活动窗口?由于SendInput模拟的是WM_KEYDOWN和WM_KEYUP事件,遵照一般的思路,我们是还是不是相应赢得普通话字符的输入法编码(拼音或五笔码),然后向活动窗口发送编码相关的SendInput?那那不光供给活动窗口张开输入法,以致还要获知它的编码格局。

如上所述,若一直如想象中那样选择SendInput来输入字符,则必得深入分析活动窗口的输入法情形。并且输入朝鲜语时,供给关闭输入法,输入中文时,又须要展开输入法。若真要以那样的笔触来达成,则早晚是麻烦成功的。

 

那么,有未有不依靠活动窗口输入法景况的秘技呢?

其实是一对,使用SendInput模拟键盘输入时,其参数是KEYBDINPUT结构,通过将其dwFlags成员设置KEYEVENTF_UNICODE就能够了。使用此措施,只需将KEYBDINPUT.wScan设置为字符的Unicode编码就能够。对于斯洛伐克语字符,无需关闭活动窗口的输入法;对于华语字符,也不须求活动窗口展开输入法和将字符变换为输入法编码。

MSDN对此办法的辨证为:INPUT_KEYBOAEscortD扶助非键盘的输入方式,举个例子手写识别或语音识别,通过KEYEVENTF_UNICODE标识,那一个艺术与键盘(文本)输入别无二致。倘若钦赐了KEYEVENTF_UNICODE,SendInput发送一个WM_KEYDOWN或WM_KEYUP音讯给移动窗口的线程消息队列,新闻的wParam参数为VK_PACKET。GetMessage或PeedMessage一旦获得此新闻,就把它传递给TranslateMessage,TranslateMessage根据wScan中钦命的Unicode字符发生贰个WM_CHAXC90信息。若窗口是ANSI窗口,则Unicode字符会自动调换为对应的ANSI字符。

 

其余部需要要向活动窗口输入字符(包涵保加利亚语)的成效均应选取这种方法来完结。事实上,键盘音讯调换为字符音讯的进程是很复杂的,那也许与键盘布局、区域、换档状态等众多要素有关,那也是Windows要选拔TranslateMessage来转换音讯的案由。由此,不应有总括透过击键事件来企图向移动窗口输入特定的字符。

 

经测试,SendInput还大概有四个值得注意的地方:

1.
没有为KEYBDINPUT.dwFlags指定KEYEVENTF_KEYUP标识时,SendInput将生成WM_KEYDOWN音信,不然生成WM_KEYUP消息,由于独有WM_KEYDOWN会转变为字符新闻,由此,若以输入字符为指标,则不应钦定KEYEVENTF_KEYUP标识。

2.
一旦大家想达到实际做贰遍击键所产生的功力:顺序发生三个WM_KEYDOWN和一个WM_KEYUP事件。则必须各自以不钦定KEYEVENTF_KEYUP和指定KEYEVENTF_KEYUP的法子试行一回SendInput操作。SendInput允许在一回调用中发送多少个模拟音讯:

  INPUT input[2]; 
  memset(input, 0, 2 * sizeof(INPUT));

  input[0].type = INPUT_KEYBOARD; 
  input[0].ki.wVk = data;

  input[1].type = INPUT_KEYBOARD; 
  input[1].ki.wVk = data; 
  input[1].ki.dwFlags = KEYEVENTF_KEYUP;

  SendInput(2, input, sizeof(INPUT));

但实在,那将变成不爆发别的新闻。那三个消息必需分开采送,如下所示:

  INPUT input[2]; 
  memset(input, 0, 2 * sizeof(INPUT));

  input[0].type = INPUT_KEYBOARD; 
  input[0].ki.wVk = data; 
  SendInput(1, input, sizeof(INPUT));

 

  input[1].type = INPUT_KEYBOARD; 
  input[1].ki.wVk = data; 
  input[1].ki.dwFlags = KEYEVENTF_KEYUP;

  SendInput(1, input + 1, sizeof(INPUT));

 

关于第二点内容,笔者很有疑点。因为事先有人在英特网帖的代码是统一发送的,想必有人那样做过同有的时候候成功了。笔者不精晓是不是与系统或任何因素有关。小编也曾试图尝试解决此主题材料,但并未顺理成章:

1.
依据MSDN,KEYBDINPUT.time是一个时间戳,假若为零,系统将应用它和睦的日子戳。由此作者不敢相信 无法相信七个联合发送的事件,是或不是因为其时间戳一样,而被忽视掉了。于是作者在上述代码中显式设置了该属性,再统一发送,结果照旧是不曾发出别的新闻。

2.
本人分别品尝了两种情状:合併发送的两条音讯都不曾点名KEYEVENTF_KEYUP(期望获取多个一样的字符输入);合併发送的两条新闻具备差别的杜撰键码且都不钦命KEYEVENTF_KEYUP(期望获得多个例外的字符输入)。结果依旧战败,未有发出其余音讯。

本身不知底那是不是代表:对于键盘输入,不一致意将新闻合併发送。

若您掌握其中缘由或测验到与自个儿区别的情形,请与自身联络:yedaoq@126.com

 

相关文化:

1.
输入法也足以管理SendInput发送的Unicode音讯,具体方法不详。见MSDN中ImmGetProperty方法的参照:当dwIndex参数为IGP_PROPERTY时,IME_PROP_ACCEPT_WIDE_VKEY是三个恐怕的再次回到值,它表示IME会管理SendInput函数以VK_PACKET注入的Unicode字符,若重返值无该标志,则Unicode字符会直接发送给应用程序。

多年来接触到那一个函数,由此了然了一下,总结一下列在那。

本身打听它的重点点是哪些通过它向运动窗口输入字符,那是数不尽顺序都有的效果与利益(小编猜Visual
Assist X就用了这么些效应)。

依附MSDN,此函数模拟开关操作,将一部分新闻插入键盘或鼠标的输入流中,Windows对它进行拍卖,生成对应的WM_KEYDOWN或WM_KEYUP事件,那一个事件与常见键盘输入一齐进去应用程序的音讯循环,它们不仅可以够转移为WM_CHA牧马人音信,还是可以转移为其余(诸如加快键)等音讯。

采取它来发送字符新闻,并未看起来那么粗略。那有三个必要缅想的难点:

1.
输入法的转移。举例必要向活动窗口发送一些斯洛伐克语字符,我们或然想象那样来兑现:获取对应键盘字符的虚构键码,发送一个SendInput。可是一旦运动窗口正在采用贰个输入法,那么大家发送出去的音讯,会进来输入法的Composition窗口,最后被撤换为象形文字或被舍弃。唯有当输入法关闭时,程序运维的效应才会像我们愿意的那样,在运动窗口中体现出日文字符。

2.
对此华语字符,应该怎么发送给活动窗口?由于SendInput模拟的是WM_KEYDOWN和WM_KEYUP事件,遵照一般的笔触,大家是否相应赢得中文字符的输入法编码(拼音或五笔码),然后向运动窗口发送编码相关的SendInput?这那不独有需求活动窗口张开输入法,以至还要获知它的编码格局。

由此看来,若平昔如想象中这样接纳SendInput来输入字符,则必得深入分析活动窗口的输入法境况。并且输入德语时,需求关闭输入法,输入粤语时,又要求张开输入法。若真要以那样的思绪来贯彻,则势必是难以成功的。

那么,有未有不正视活动窗口输入法境况的不二等秘书技吧?

实质上是有些,使用SendInput模拟键盘输入时,其参数是KEYBDINPUT结构,通过将其dwFlags成员设置KEYEVENTF_UNICODE即可了。使用此格局,只需将KEYBDINPUT.wScan设置为字符的Unicode编码就可以。对于意大利语字符,不须要关闭活动窗口的输入法;对于华语字符,也不供给活动窗口张开输入法和将字符转变为输入法编码。

MSDN对此措施的验证为:INPUT_KEYBOA帕杰罗D支持非键盘的输入形式,举个例子手写识别或语音识别,通过KEYEVENTF_UNICODE标记,那几个办法与键盘(文本)输入别无二致。假诺钦命了KEYEVENTF_UNICODE,SendInput发送二个WM_KEYDOWN或WM_KEYUP音讯给移动窗口的线程音讯队列,音讯的wParam参数为VK_PACKET。GetMessage或PeedMessage一旦得到此音信,就把它传递给TranslateMessage,TranslateMessage依据wScan中钦赐的Unicode字符产生三个WM_CHALAND新闻。若窗口是ANSI窗口,则Unicode字符会自动调换为相应的ANSI字符。

另外索要向移动窗口输入字符(包蕴保加利亚共和国(The Republic of Bulgaria)语)的作用均应运用这种艺术来落实。事实上,键盘新闻调换为字符音信的长河是很复杂的,那恐怕与键盘布局、区域、换档状态等居多要素有关,那也是Windows要选择TranslateMessage来调换音信的开始和结果。因而,不该总计通过击键事件来企图向运动窗口输入特定的字符。

经测量检验,SendInput还会有四个值得注意的地方:

1.
没有为KEYBDINPUT.dwFlags指定KEYEVENTF_KEYUP标识时,SendInput将生成WM_KEYDOWN音信,否则生成WM_KEYUP音信,由于独有WM_KEYDOWN会转换为字符新闻,因而,若以输入字符为目的,则不应内定KEYEVENTF_KEYUP标识。

2.
比方大家想到达实际做贰反扑键所发出的意义:顺序发生二个WM_KEYDOWN和一个WM_KEYUP事件。则必得各自以不钦点KEYEVENTF_KEYUP和指定KEYEVENTF_KEYUP的章程举办一次SendInput操作。SendInput允许在一回调用中发送两个模拟消息:

INPUT input[2];
memset(input, 0, 2 * sizeof(INPUT));

input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = data;

input[1].type = INPUT_KEYBOARD;
input[1].ki.wVk = data;
input[1].ki.dwFlags = KEYEVENTF_KEYUP;

SendInput(2, input, sizeof(INPUT));

但其实,那将招致不发出任何音信。那五个新闻必需分别发送,如下所示:

INPUT input[2];
memset(input, 0, 2 * sizeof(INPUT));

input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = data;
SendInput(1, input, sizeof(INPUT));

input[1].type = INPUT_KEYBOARD;
input[1].ki.wVk = data;
input[1].ki.dwFlags = KEYEVENTF_KEYUP;

SendInput(1, input + 1, sizeof(INPUT));

有关第二点内容,笔者很有疑难。因为事先有人在英特网帖的代码是统一发送的,想必有人这么做过相同的时间成功了。笔者不知情是还是不是与系统或其余因素有关。笔者也曾筹划尝试消除此主题材料,但未能如愿:

1.
依照MSDN,KEYBDINPUT.time是三个岁月戳,假使为零,系统将动用它自个儿的小运戳。因而小编困惑多个共同发送的风浪,是或不是因为其时间戳一样,而被忽视掉了。于是自个儿在上述代码中显式设置了该属性,再统一发送,结果依然是未有发生其它新闻。

2.
自个儿分别品尝了二种景况:合併发送的两条音信都未曾点名KEYEVENTF_KEYUP(期望获取五个一律的字符输入);合并发送的两条音讯具备不一样的设想键码且都不点名KEYEVENTF_KEYUP(期望获取三个不等的字符输入)。结果还是战败,没有发生别的音信。

本身不知道那是还是不是意味:对于键盘输入,不容许将音讯合併发送。

若你精晓个中原因或测验到与作者差异的气象,请与本身沟通:yedaoq@126.com

相关知识:

1.
输入法也足以管理SendInput发送的Unicode新闻,具体方法不详。见MSDN中ImmGetProperty方法的参照:当dwIndex参数为IGP_PROPERTY时,IME_PROP_ACCEPT_WIDE_VKEY是贰个大概的重回值,它象征IME会处理SendInput函数以VK_PACKET注入的Unicode字符,若重返值无该标记,则Unicode字符会直接发送给应用程序。 


http://xylvhp.blog.163.com/blog/static/31123614201101104644542/

在VC中采取SendInput函数实现粤语的机关输入(ZZ)

2011-01-11 12:46:44| 分类: C++
|字号
订阅

第一是,头文件必得含有以下两个:
#include <winable.h>
#include <atlconv.h>

后边二个是SendInput函数要选择,前者是字符串调换的时候要用到。

void SendAscii(wchar_t data, BOOL shift)
{
INPUT input[2];
memset(input, 0, 2 * sizeof(INPUT));

if (shift)
{
input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = VK_SHIFT;
SendInput(1, input, sizeof(INPUT));
}

input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = data;

input[1].type = INPUT_KEYBOARD;
input[1].ki.wVk = data;
input[1].ki.dwFlags = KEYEVENTF_KEYUP;

SendInput(2, input, sizeof(INPUT));

if (shift)
{
input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = VK_SHIFT;
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, input, sizeof(INPUT));
}
}

void SendUnicode(wchar_t data)
{
INPUT input[2];
memset(input, 0, 2 * sizeof(INPUT));

input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = 0;
input[0].ki.wScan = data;
input[0].ki.dwFlags = 0x4;//KEYEVENTF_UNICODE;

input[1].type = INPUT_KEYBOARD;
input[1].ki.wVk = 0;
input[1].ki.wScan = data;
input[1].ki.dwFlags = KEYEVENTF_KEYUP | 0x4;//KEYEVENTF_UNICODE;

SendInput(2, input, sizeof(INPUT));
}

//为方便使用,下面这些函数包装了前多少个函数。
void SendKeys(CString msg)
{
short vk;
BOOL shift;

USES_CONVERSION;
wchar_t* data = T2W(msg.GetBuffer(0));
int len = wcslen(data);

for(int i=0;i<len;i++)
{
if (data[i]>=0 && data[i]<256) //ascii字符
{
vk = VkKeyScanW(data[i]);

if (vk == -1)
{
SendUnicode(data[i]);
}
else
{
if (vk < 0)
{
vk = ~vk + 0x1;
}

shift = vk >> 8 & 0x1;

if (GetKeyState(VK_CAPITAL) & 0x1)
{
if (data[i]>=’a’ && data[i]<=’z’ || data[i]>=’A’ &&
data[i]<=’Z’)
{
shift = !shift;
}
}

SendAscii(vk & 0xFF, shift);
}
}
else //unicode字符
{
SendUnicode(data[i]);
}
}
}

直接调用SendKeys函数就足以在眼下光标的地方自动输入钦定的字符串,上面包车型客车例证演示了哪些自动打开记事本程序并输入一段话:
void CSendInputDlg::OnTest()
{
ShellExecute(NULL, NULL, “notepad.exe”, NULL, NULL, SW_SHOWNORMAL);

Sleep(500); //为了确定保障记事本程序打开实现,稍等片刻

CWnd *pWnd = FindWindow(NULL, “无标题 – 记事本”);
if (pWnd)
{
pWnd->SetForegroundWindow();
SendKeys(“笔者是sway,作者爱中华!\nI love China!\nEmail:
xmujava@163.com\t\n2010-05-21 \b\b”);
}
}

//////////////////////////////////////////////////////////////////////////////////////////////////////

SendInput模拟键盘和鼠标事件

INPUT kbinput[5];
ZeroMemory( &kbinput, sizeof(INPUT)*5 );

kbinput[0].type = INPUT_KEYBOARD;
kbinput[0].ki.wVk = ‘Z’;

kbinput[1].type = INPUT_KEYBOARD;
kbinput[1].ki.wVk = ‘W’;

kbinput[2].type = INPUT_KEYBOARD;
kbinput[2].ki.wVk = ‘J’;
//kbinput[2].ki.dwFlags = KEYEVENTF_KEYUP;

kbinput[3].type=INPUT_MOUSE;
kbinput[3].mi.dx=100;
kbinput[3].mi.dy=100;
kbinput[3].mi.mouseData=0;
kbinput[3].mi.dwFlags=MOUSEEVENTF_RIGHTDOWN;

kbinput[4].type=INPUT_MOUSE;
kbinput[4].mi.dx=100;
kbinput[4].mi.dy=100;
kbinput[4].mi.mouseData=0;
kbinput[4].mi.dwFlags=MOUSEEVENTF_RIGHTUP;

UINT uRet = SendInput( 5, kbinput, sizeof(INPUT) );