Keybd_event is replaced by SendInput

Source: Internet
Author: User

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

Keybd_event
Function function: This function is used to synthesize a key event. The system can use this synthetic key event to generate the WM_KEYUP or WM_KEYDOWN message. The interrupt handler of the keyboard driver calls the keybd_event function. In Windows NT, this function has been replaced by SendInput.

--------------------------------------------------

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

SendInput simulating keyboard input

I recently came into use with this function, so I learned about it and summarized it here.

I understand how it starts with inputting characters into the activity window. This is a feature that many programs have (I guess Visual Assist X uses this feature ).

According to MSDN, this function simulates button operations and inserts some messages into the input stream of the keyboard or mouse. Windows processes the messages and generates corresponding WM_KEYDOWN or WM_KEYUP events, these events enter the application's message loop together with the normal keyboard input. They can not only be converted to WM_CHAR messages, but also to other messages (such as the acceleration key.

Using it to send character messages is not as simple as it looks. There are two issues to consider:

1. Input Method conversion. For example, if you want to send some English characters to the activity window, we may imagine this: Get the virtual key code of the corresponding keyboard characters and send a SendInput code. However, if an input method is used in the activity window, the messages we send will enter the Composition window of the input method, which will eventually be converted to hieroglyphics or discarded. Only when the input method is disabled will the program run show English characters in the activity window as expected.

2. How should I send Chinese characters to the activity window? SendInput simulates WM_KEYDOWN and WM_KEYUP events. According to the general idea, do we need to get the input method encoding of Chinese characters (pinyin or five digits ), then, send the SendInput related to the encoding to the activity window? This requires that the input method be enabled in the activity window, and even the encoding method.

As mentioned above, if SendInput is used as expected to input characters, the input state of the active window must be analyzed. When entering English, you must disable the input method. When entering Chinese, you must enable the input method. If we really want to achieve it with this idea, it will be difficult to succeed.

Is there any way to do this without relying on the input state of the activity window?

Actually, when using SendInput to simulate keyboard input, its parameter is the KEYBDINPUT structure. You can set KEYEVENTF_UNICODE by setting its dwFlags member. To use this method, you only need to set KEYBDINPUT. wScan to the Unicode encoding of characters. For English characters, you do not need to close the input method of the active window. For Chinese characters, you do not need to open the input method of the active window or convert the characters to the input method encoding.

MSDN describes this method as follows: INPUT_KEYBOARD supports non-keyboard input methods, such as handwriting recognition or speech recognition, which are identified by KEYEVENTF_UNICODE. If KEYEVENTF_UNICODE is specified, SendInput sends a WM_KEYDOWN or WM_KEYUP message to the thread message queue of the active window. The wParam parameter of the message is VK_PACKET. Once the GetMessage or PeedMessage obtains the message, it is passed to the TranslateMessage. The TranslateMessage generates a WM_CHAR message based on the Unicode Character specified in wScan. If the window is an ANSI window, the Unicode characters are automatically converted to the corresponding ANSI characters.

This method is applicable to any function that requires entering characters (including English) in the activity window. In fact, the process of converting a keyboard message to a character message is very complicated, which may be related to many factors such as the keyboard layout, area, and shift status, this is why Windows uses TranslateMessage to convert messages. Therefore, you should not try to input a specific character in the activity window through a key-down event.

According to tests, SendInput has two points worth noting:

1. no KEYBDINPUT. when dwFlags specifies the KEYEVENTF_KEYUP identifier, SendInput will generate the WM_KEYDOWN message. Otherwise, WM_KEYUP messages will be generated. Because only WM_KEYDOWN will be converted to character messages, if the target is an input character, KEYEVENTF_KEYUP ID should not be specified.

2. If we want to achieve the effect of making a press Key: generate a WM_KEYDOWN event and a WM_KEYUP event in sequence. The SendInput operation must be performed once without KEYEVENTF_KEYUP or KEYEVENTF_KEYUP. SendInput allows multiple simulated messages to be sent in one call:

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 ));

But in fact, this will lead to no messages. The two messages must be sent separately, as shown below:

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 ));

I have doubts about the second point. Because the code posted by someone on the internet is sent and merged, it must have been done and succeeded. I don't know if it is related to the system or other factors. I tried to solve this problem, but failed:

1. According to MSDN, KEYBDINPUT. time is a timestamp. If it is zero, the system uses its own timestamp. Therefore, I suspect that the events sent together are ignored because their timestamps are the same. So I explicitly set this attribute in the above code and then send it in combination. The result still does not produce any messages.

2. I tried two cases: neither of the two messages sent by merging has specified KEYEVENTF_KEYUP (two identical character inputs are expected ); the two messages sent and merged have different virtual key codes and do not specify KEYEVENTF_KEYUP (two different character inputs are expected ). The result still fails and no messages are generated.

I don't know if this means: for keyboard input, messages cannot be sent in combination.

If you understand the reason or test it to be different from me, please contact me: yedaoq@126.com

Related Knowledge:

1. The input method can also process Unicode messages sent by SendInput. The specific method is unknown. See the ImmGetProperty method reference in MSDN: When the dwIndex parameter is IGP_PROPERTY, IME_PROP_ACCEPT_WIDE_VKEY is a possible return value, which indicates that IME will process the Unicode characters injected by the SendInput function using VK_PACKET, if the returned value does not have this identifier, the Unicode character is directly sent to the application.

Bytes --------------------------------------------------------------------------------------

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

Use the SendInput function in VC to implement automatic Chinese Input (ZZ)

12:46:44 | category: C ++
| Font size
Subscription

First, the header file must contain the following two:
# Include <winable. h>
# Include <atlconv. h>

The former is used by the SendInput function, and the latter is used for String Conversion.

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 ));
}

// For ease of use, the following function encapsulates the first two functions.
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 characters
{
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 Character
{
SendUnicode (data [I]);
}
}
}

You can directly call the SendKeys function to automatically enter the specified string at the current cursor position. The following example shows how to automatically open the Notepad program and enter a paragraph:
Void CSendInputDlg: OnTest ()
{
ShellExecute (NULL, NULL, "notepad.exe", NULL, NULL, SW_SHOWNORMAL );

Sleep (500); // wait for a moment to ensure that the Notepad program has been opened.

CWnd * pWnd = FindWindow (NULL, "untitled-Notepad ");
If (pWnd)
{
PWnd-> SetForegroundWindow ();
SendKeys ("I'm sway, I love China! \ NI love China! \ NEmail: xmujava@163.com \ t \ n2010-05-21 \ B ");
}
}

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

SendInput simulates keyboard and mouse events

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 [2]. mi. dx = 100;
K binput [3]. mi. dy = 100;
Kbinput [3]. mi. mouseData = 0;
Kbinput [3]. mi. dwFlags = MOUSEEVENTF_RIGHTDOWN;

Kbinput [4]. type = INPUT_MOUSE;
Kbinput [2]. 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 ));

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.