自身打听它的视角是哪些通过它向运动窗口输入字符,系统可应用这种合成的击键事件来发出WM

若您领会其中原因或测量检验到与自身分化的情景,请与小编联络:yedaoq@126.com

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

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

SendInput模拟键盘输入的难点

 

日前接触到这些函数,因而通晓了瞬间,计算一下列在那。

自身打听它的视角是哪些通过它向运动窗口输入字符,这是得步进步主次都有的效果与利益(小编猜Visual
Assist X就用了那么些功能)。

传说MSDN,此函数模拟按钮操作,将部分音信插入键盘或鼠标的输入流中,Windows对它进行管理,生成对应的WM_KEYDOWN或WM_KEYUP事件,这一个事件与常见键盘输入一齐进去应用程序的消息循环,它们不但能够转移为WM_CHA奥迪Q5音信,还是能够转移为别的(诸如加快键)等新闻。

应用它来发送字符音信,并未看起来那么轻松。这有七个须要思量的标题:

1.
输入法的调换。比方需求向活动窗口发送一些土耳其共和国语字符,大家恐怕想象那样来贯彻:获取对应键盘字符的设想键码,发送叁个SendInput。不过一旦运动窗口正在选取二个输入法,那么我们发送出去的消息,会进去输入法的Composition窗口,末了被转移为象形文字或被放任。独有当输入法关闭时,程序运转的遵守才会像大家期待的那么,在移动窗口中显得出希伯来语字符。

2.
对于华语字符,应该怎么发送给活动窗口?由于SendInput模拟的是WM_KEYDOWN和WM_KEYUP事件,遵照一般的笔触,我们是还是不是应该获得中文字符的输入法编码(拼音或五笔码),然后向移动窗口发送编码相关的SendInput?那那不只供给活动窗口开启输入法,乃至还要获知它的编码格局。

由此看来,若一向如想象中那么选用SendInput来输入字符,则必得深入分析运动窗口的输入法景况。何况输入俄语时,需要关门输入法,输入中文时,又供给打开输入法。若真要以如此的思路来贯彻,则一定是麻烦成功的。

 

那正是说,有未有不重视活动窗口输入法情况的主意吧?

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

MSDN对此措施的求证为:INPUT_KEYBOAEvoqueD帮助非键盘的输入格局,比方手写识别或语音识别,通过KEYEVENTF_UNICODE标记,这么些措施与键盘(文本)输入别无二致。若是内定了KEYEVENTF_UNICODE,SendInput发送叁个WM_KEYDOWN或WM_KEYUP音讯给移动窗口的线程音讯队列,新闻的wParam参数为VK_PACKET。GetMessage或PeedMessage一旦获得此消息,就把它传递给TranslateMessage,TranslateMessage依据wScan中内定的Unicode字符产生多个WM_CHA昂Cora音讯。若窗口是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字符会直接发送给应用程序。

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

 

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

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

 

1.
输入法的转变。比方供给向移动窗口发送一些丹麦语字符,大家也许想象那样来贯彻:获取对应键盘字符的杜撰键码,发送三个SendInput。不过一旦运动窗口正在利用贰个输入法,那么我们发送出去的音讯,会跻身输入法的Composition窗口,最后被改变为象形文字或被丢掉。唯有当输入法关闭时,程序运维的成效才会像大家盼望的那样,在活动窗口中展现出法语字符。

 

连带知识:

SendInput模拟键盘输入的难题

 keybd_event
  函数作用:该函数合成一次击键事件。系统可利用这种合成的击键事件来产生WM_KEYUP或WM_KEYDOWN音讯,键盘驱动程序的中止管理程序调用keybd_event函数。在Windows
NT中该函数己被使用SendInput来代替它。

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

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;

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

input[1].type = INPUT_KEYBOARD;
input[1]365体育官网,.ki.wVk = 0;
input[1].ki.wScan = data;
input[1].ki.dwFlags = KEYEVENTF_KEYUP | 0x4;//KEYEVENTF_UNICODE;

直接调用SendKeys函数就可以在此时此刻光标的岗位自动输入钦赐的字符串,上面的例证演示了怎么着自动展开记事本程序并输入一段话:
void CSendInputDlg::OnTest()
{
ShellExecute(NULL, NULL, “notepad.exe”, NULL, NULL, SW_SHOWNORMAL);

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


SendInput模拟键盘和鼠标事件

那便是说,有没有不依赖活动窗口输入法情形的法子吧?

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

Sleep(500); //为了确认保证记事本程序展开完结,稍等片刻

先是是,头文件必须富含以下七个:
#include <winable.h>
#include <atlconv.h>

在VC中选择SendInput函数完毕汉语的自发性输入(ZZ)

1.
依照MSDN,KEYBDINPUT.time是多个时间戳,假若为零,系统将动用它和谐的年华戳。因而小编疑惑四个一块发送的平地风波,是还是不是因为其时间戳一样,而被忽视掉了。于是本人在上述代码中显式设置了该属性,再统一发送,结果依旧是不曾发出任何消息。

由此看来,若直接如想象中那么采取SendInput来输入字符,则必须深入分析运动窗口的输入法处境。况兼输入爱尔兰语时,须求关门输入法,输入普通话时,又须要展开输入法。若真要以那样的思路来兑现,则必然是为难成功的。

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

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

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

其余供给向活动窗口输入字符(包蕴英语)的功力均应运用这种艺术来落到实处。事实上,键盘新闻转变为字符新闻的长河是很复杂的,那只怕与键盘布局、区域、换档状态等比较多因素有关,那也是Windows要运用TranslateMessage来转变新闻的原委。因而,不该计算透过击键事件来谋算向活动窗口输入特定的字符。

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

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

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

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

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

自家不领会那是或不是意味着:对于键盘输入,不允许将音讯合併发送。

运用它来发送字符音讯,并不曾看起来那么粗略。那有五个须求考虑的难题:

关于第二点内容,作者很有问号。因为事先有人在英特网帖的代码是统一发送的,想必有人那样做过同一时候成功了。我不知道是还是不是与系统或其余因素有关。小编也曾试图尝试消除此主题素材,但从不成功:

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

后面一个是SendInput函数要运用,前面一个是字符串转变的时候要用到。

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

2.
对此华语字符,应该怎么发送给活动窗口?由于SendInput模拟的是WM_KEYDOWN和WM_KEYUP事件,依据一般的思路,大家是或不是应当获得中文字符的输入法编码(拼音或五笔码),然后向活动窗口发送编码相关的SendInput?那那不光须求活动窗口开启输入法,以至还要获知它的编码格局。

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

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

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

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

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

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

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

MSDN对此措施的求证为:INPUT_KEYBOA中华VD匡助非键盘的输入情势,比如手写识别或语音识别,通过KEYEVENTF_UNICODE标志,那么些主意与键盘(文本)输入别无二致。假使钦赐了KEYEVENTF_UNICODE,SendInput发送三个WM_KEYDOWN或WM_KEYUP音信给移动窗口的线程消息队列,音信的wParam参数为VK_PACKET。GetMessage或PeedMessage一旦获得此音讯,就把它传递给TranslateMessage,TranslateMessage依据wScan中钦定的Unicode字符发生一个WM_CHAAMG ONE新闻。若窗口是ANSI窗口,则Unicode字符会自动调换为对应的ANSI字符。

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

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

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

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;

2.
一旦大家想达到实际做一反扑键所发出的功力:顺序产生一个WM_KEYDOWN和一个WM_KEYUP事件。则必得分别以不钦赐KEYEVENTF_KEYUP和指定KEYEVENTF_KEYUP的法子执行三回SendInput操作。SendInput允许在一遍调用中发送多少个模拟信息:

shift = vk >> 8 & 0x1;

多年来接触到那么些函数,由此领会了一下,总括一下列在那。

 

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

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

本身打听它的视角是何等通过它向移动窗口输入字符,那是累累程序都有个别效果与利益(笔者猜Visual
Assist X就用了那几个效应)。

2.
自家分别品尝了二种情形:合併发送的两条新闻都未曾点名KEYEVENTF_KEYUP(期望获取四个一样的字符输入);合并发送的两条音讯具备分歧的设想键码且都不钦赐KEYEVENTF_KEYUP(期望获得多个分裂的字符输入)。结果还是还是失利,未有生出别的信息。

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

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

据他们说MSDN,此函数模拟开关操作,将部分新闻插入键盘或鼠标的输入流中,Windows对它举行管理,生成对应的WM_KEYDOWN或WM_KEYUP事件,这么些事件与普通键盘输入一同跻身应用程序的消息循环,它们不但能够转换为WM_CHA大切诺基音信,还足以转换为其余(诸如加速键)等音讯。

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

但其实,那将招致不产生其余新闻。那七个音信必需分开采送,如下所示:

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

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

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

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

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

实质上是一些,使用SendInput模拟键盘输入时,其参数是KEYBDINPUT结构,通过将其dwFlags成员设置KEYEVENTF_UNICODE就足以了。使用此格局,只需将KEYBDINPUT.wScan设置为字符的Unicode编码就能够。对于葡萄牙共和国(República Portuguesa)语字符,没有需求关闭活动窗口的输入法;对于华语字符,也不供给活动窗口打开输入法和将字符转变为输入法编码。

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

相关文章