Keyboard is a very important input device for us to use computers. Even today, even when the mouse is popular, many programs still cannot be operated without the keyboard. But sometimes, some repetitive and tedious keyboard operations are always exhausting, so there is a way to replace people's buttons with programs, in this way, a lot of repetitive keyboard operations can be handed over to the program for simulation, saving a lot of effort, and the keyboard pushing wizard is such a software. So how can we use VB to write a program to achieve a function similar to that of the press Key genie? Let's take a look at the keyboard Event Response Mechanism in windows.
When you press a key on the keyboard, the chip in the keyboard will detect this action and send this signal to the computer. What is the difference between which key is pressed? All the buttons on the keyboard are encoded as a scan code. When you press a key, the scan code of this key is passed to the system. Scan codes are related to specific hardware. The scan codes on different keyboards may be different for the same key. The keyboard controller sends the scan code to the computer and then to the keyboard driver. The keyboard driver completes the work and converts the scan code to a keyboard virtual code. What is a virtual code? Because the scan code is related to hardware and is not universal, the concept of virtual code is proposed to unify the encoding of all keys on the keyboard. No matter what keyboard, the virtual code of the same button is always the same, so that the program can recognize it. To put it simply, virtual codes are constants such as vk_a and vk_ B that we often see. For example, if the virtual code of key A is 65, it is written in hexadecimal notation & H41. Note, people often use hexadecimal notation to represent virtual code. After the keyboard driver converts a scan code to a virtual code, the scan code and other information for this keyboard operation are transmitted to the operating system. The operating system then encapsulates the information in a message and inserts the keyboard message into the message queue. Finally, if there is no accident, the keyboard message will be sent to the current activity window. After the application of the activity window receives the message, you will know which key on the keyboard is pressed, and you will be able to decide what response should be made to the user. This process can be expressed as follows:
Press the button ----- the keyboard driver sends the event to the operating system ----- the operating system inserts the keyboard event into the Message Queue ----- the keyboard message is sent to the current activity window
After understanding this process, we can program and implement a link in it to simulate keyboard operations. In VB, there are multiple methods for keyboard simulation. We will introduce several typical methods.
1. Local Simulation
From the above process, we can see that the keyboard event is finally sent to the activity window, and then the target program responds. The most direct simulation method is: directly forge a Keyboard Message and send it to the target program. Haha, this is really simple. Windows provides several such API functions to send messages directly to the target program. Commonly Used functions include sendmessage and postmessage, the difference between them is that the postmessage function does not care whether the message is directly sent to the target program, and after sendmessage sends the message, it will wait for the target program to return something. Note that you must use the postmessage function to simulate a keyboard message. It is incorrect to use sendmessage (because simulating a keyboard message does not require a return value, otherwise the target program will not respond ), remember! The vb declaration of the postmessage function is as follows:
Declare function postmessage lib "USER32" alias "postmessagea" (byval hwnd as long, byval wmsg as long, byval wparam as long, lparam as any) as long
The hwnd parameter is the handle of a control in the target program where you want to send a message. The wmsg parameter is the message type, indicating what kind of message you want to send, the wparam and lparam parameters are appended with the message. The specific content is determined by the message.
Let's take a look at the wmsg parameter, which is the only option to simulate the button. Keyboard messages are commonly used as follows:
Wm_keydown indicates that a common key is pressed
Wm_keyup indicates that a common key is released.
Wm_syskeydown indicates that a system key is pressed, for example, alt.
Wm_syskeyup indicates that a system key is released, such as the Alt key.
If you are sure you want to send the preceding keyboard messages, let's take a look at how to determine the wparam and lparam parameters in the keyboard messages. In a keyboard message, the wparam parameter has a simple meaning. It indicates the key-press virtual code of the keyboard event you want to send. For example, you want to simulate pressing the key on the target program, the value of the wparam parameter is set to vk_a. As for the lparam parameter, it is complicated because it contains multiple pieces of information and can be set to 0, however, if you want your simulation to be more realistic, you are advised to set this parameter. Let's take a closer look at lparam. Lparam is a long parameter, which occupies 4 bytes in the memory and is written as binary 00000000 00000000 00000000 00000000 is a total of 32 bits. We start from right to left, assume that the rightmost person is 0th bits (Note that the number starts from 0 rather than 1), and the leftmost person is 31st bits, the 0-15 bits of this parameter indicate the number of key sends and other extended information. The 16-23 bits indicate the scan code of the key, and the 24-31 bits indicate whether to press or release the key. Generally, we are used to writing in hexadecimal notation. It should be & H00 00 00, and the 0-15 bits are generally & h0001. If you press the key, the 24-31 bits are & H00, if the release key is & hc0, how can we get a 16-23-bit scan code? This requires an API function mapvirtualkey, which can convert a virtual code to a scan code or a scan code to a virtual code, you can also convert the virtual code to the ASCII code of the corresponding character. Its VB declaration is as follows:
Declare function mapvirtualkey lib "USER32" alias "mapvirtualkeya" (byval wcode as long, byval wmaptype as long) as long
The wcode parameter indicates the code to be converted. The wmaptype parameter indicates the conversion from what to why. If it is a virtual code to a scan code, the wmaptype is set to 0. If it is a virtual scan code to a virtual code, then, wmaptype is set to 1. If it is a virtual code to ASCII code, wmaptype is set to 2. with this, we can construct the lparam parameter of the keyboard event. The following is a function for constructing the lparam parameter:
Declare function mapvirtualkey lib "USER32" alias "mapvirtualkeya" (byval wcode as long, byval wmaptype as long) as long
Function makekeylparam (byval virtualkey as long, byval flag as long) as long
The 'parameter virtualkey indicates the key virtual code, and the flag indicates whether to press or release the key, which is expressed by the two constants wm_keydown and wm_keyup.
Dim s as string
24-31 digits of the dim firstbyte as string 'lparam Parameter
If flag = wm_keydown then'
Firstbyte = "00"
Else
Firstbyte = "C0" 'if it is a release key
End if
Dim scancode as long
'Get the key scan code
Scancode = mapvirtualkey (virtualkey, 0)
The 16-23 bits of the dim secondbyte as string 'lparam parameter, that is, the virtual key scan code.
Secondbyte = right ("00" & hex (scancode), 2)
S = firstbyte & secondbyte & "0001" '0001 is the 0-15 bits of the lparam parameter, that is, the number of sent messages and other extended information.
Makekeylparam = Val ("& H" & S)
End Function
This function is called like this. For example, if you press the key, then lparam = makekeylparam (vk_a, wm_keydown) is very simple. It is worth noting that even if you set the value of the lparam parameter when sending a message, the system may reset this parameter according to the current situation when passing the message, the value of lparam in the message received by the target program may be different from the value you sent. Therefore, if you are very lazy, set it to 0 directly without affecting most programs.
Now we can send a Keyboard Message to the target program. First, obtain the handle of the control that the target program receives the message. For example, if the target handle is 12345, We will simulate pressing and releasing the key for the target, as shown in the following figure: (for simplicity, the parameter lparam is not constructed and 0 is directly passed)
Postmessage 12345, wm_keydown, vk_a, 0 & 'press Key
Postmessage 12345, wm_up, vk_a, 0 & 'release key
All right, one button is complete. Now you can try to open notepad and try again. First, use the findwindowex API functions to find the handle of the Notepad program, and then send a Keyboard Message to it, hoping that the notepad will automatically display strange characters. But you are immediately disappointed. Sorry, why didn't you respond at all? You cheat your feelings ~~~~~~~~~~ 55555555555555 is not. Let's look down.
Generally, the target program contains multiple controls. Not every control responds to the keyboard message. Only the control that sends the Keyboard Message to the control that accepts the message will receive the expected response. For notepad, its editing box is actually an edit class. Only this control can respond to keyboard events. It is useless to send messages to the notepad form. Now you can find the handle of the edit box in notepad, for example, 54321. Write the following code:
Postmessage 54321, wm_keydown, vk_f1, 0 & 'Press F1
Postmessage 54321, wm_up, vk_f1, 0 & 'release the F1 key
How about it? Did you open the "help" Information in notepad? This indicates that the target program has received the message you sent ~~~~~~~~
Now you can try again. You want to press the key on notepad. Fortunately, the notepad will automatically enter characters. However, there is no response! What is this?
It turns out that if you want to send characters to the target program, the wm_keydown and wm_up events alone will not work yet. You also need an event: wm_char, which indicates a character, the program needs to accept the input characters according to it. Generally, only buttons A, B, and C have wm_char messages. Other keys (such as direction keys and function keys) do not have this message. wm_char messages generally occur after wm_keydown messages. The lparam parameter of the wm_char message has the same meaning as that of other keyboard messages, and its wparam parameter represents the ASCII code of the corresponding characters (which can be entered in Chinese ), now you can write a complete program that automatically writes characters to the notepad. The following is an example with the specific values of these message constants:
Declare function postmessage lib "USER32" alias "postmessagea" (byval hwnd as long, byval wmsg as long, byval wparam as long, lparam as any) as long
Declare function mapvirtualkey lib "USER32" alias "mapvirtualkeya" (byval wcode as long, byval wmaptype as long) as long
Public const wm_keydown = & h100
Public const wm_keyup = & H101
Public const wm_char = & h102
Public const vk_a = & H41
Function makekeylparam (byval virtualkey as long, byval flag as long) as long
Dim s as string
24-31 digits of the dim firstbyte as string 'lparam Parameter
If flag = wm_keydown then'
Firstbyte = "00"
Else
Firstbyte = "C0" 'if it is a release key
End if
Dim scancode as long
'Get the key scan code
Scancode = mapvirtualkey (virtualkey, 0)
The 16-23 bits of the dim secondbyte as string 'lparam parameter, that is, the virtual key scan code.
Secondbyte = right ("00" & hex (scancode), 2)
S = firstbyte & secondbyte & "0001" '0001 is the 0-15 bits of the lparam parameter, that is, the number of sent messages and other extended information.
Makekeylparam = Val ("& H" & S)
End Function
Private sub form_load ()
Dim hwnd as long
Hwnd = xxxxxx 'xxxxx indicates the handle of the notepad editing box.
Postmessage hwnd, wm_keydown, vk_a, makekeylparam (vk_a, wm_keydown) 'press Key
Postmessage hwnd, wm_char, ASC ("A"), makekeylparam (vk_a, wm_keydown )'
Postmessage hwnd, wm_up, vk_a, makekeylparam (vk_a, wm_up) 'release key
End sub
This is to simulate the button through a local Keyboard Message. This method has a major benefit: it can implement background buttons, that is, it will not affect your foreground operations. For example, you can use this method to create a program to simulate keys in the game to constantly execute some repeated operations. While drinking tea, you can chat with the MMS on QQ, it will not affect your front-end operations at all. No matter whether the target program gets the focus or not, this is the principle of simulating the buttons in the background ~~~~
'According to your feedback, we can see that some games have blocked the keydown message, so you may wish to use wm_lbuttondown, which may be successful. Modify as follows:
'With postmessage, you must first know the target's handle hwd
Option explicit
Private declare function postmessage lib "USER32" alias "postmessagea" (byval hwnd as long, byval wmsg as long, byval wparam as long, byval lparam as long) as long
Private const wm_lbuttondown = & h201
Private const wm_lbuttonup = & H202
Private sub commandementclick ()
Postmessage hwd, wm_lbuttondown, 0, 0' simulate pressing the specified key
Postmessage hwd, wm_lbuttonup, 0, 0
End sub
Using the above method to simulate a button is not effective for all programs. Some programs, you send a lot of messages to it, but it does not respond at all. What's going on? This depends on the specific situation. For some reasons, some programs (especially some games) will prohibit users from using the simulated key program. How can this be achieved? For example, you can check in the program. If you find that you are not an activity window, you will not accept the Keyboard Message. You can also carefully check the received Keyboard Message and you will find that there are always some minor differences between the real button and the simulated button message. From these differences, the target program can determine: this is false! It's forged !! Therefore, if the simulated button for sending a local message with postmessage fails, you can try the global Keyboard Message to see if the target program can be cheated.
You can use the following methods to simulate global keyboard messages:
(1) Use the API function keybd_event. This function can be used to simulate a keyboard event. Its VB declaration is:
Declare sub keybd_event lib "USER32" (byval bvk as byte, byval bscan as byte, byval dwflags as long, byval dwextrainfo as long)
The bvk parameter indicates the virtual code of the key to be simulated, and bscan indicates the scan code of the key (generally 0). dwflags indicates whether to press the key or release the key (press the key to 0, the release key is 2), and dwextrainfo is an extension identifier, which is generally useless. For example, to simulate pressing the tab key, you can do this:
Const keyeventf_keyup = & H2
Const vk_tab = & H9
Keybd_event vk_tab, 0, 0, 0' press the tab key
Keybd_event vk_tab, 0, keyeventf_keyup, 0' release the tab key
Note that sometimes the key speed should not be too fast, otherwise there may be problems, you can use the API function sleep for latency, the Declaration is as follows:
Declare sub sleep lib "Kernel32" (byval dwmilliseconds as long)
The dwmilliseconds parameter indicates the delay time in milliseconds.
How can I simulate pressing the function key? For example, if you want to press Ctrl + C to copy the file, you can:
Keybd_event vk_ctrl, 0, 0, 0' press Ctrl
Keybd_event vk_c, 0, 0, 0' press C
Sleep 500 'latency 500 milliseconds
Keybd_event vk_c, 0, keyeventf_keyup, 0' release C key
Keybd_event vk_ctrl, 0, keyeventf_keyup, 0' release ctrl key
Now, you can try to cheat the target program. This function is effective for most window programs, but some games still ignore the keyboard events it generates. At this time, you need to use the bscan parameter. Generally, bscan transmits 0 messages. However, if the target program is a DirectX game, you need to use this parameter to pass in the scan code correctly and use it to generate correct hardware event messages, to be recognized by the game. In this way, you can write it as follows:
Declare function mapvirtualkey lib "USER32" alias "mapvirtualkeya" (byval wcode as long, byval wmaptype as long) as long
'Declare the API function mapvirtualkey first and convert the character into a Keyboard Scan code.
Keybd_event vk_tab, mapvirtualkey (vk_tab, 0), 0, 0' press the tab key
Keybd_event vk_tab, mapvirtualkey (vk_tab, 0), keyeventf_keyup, 0' release the tab key
The above uses the keybd_event function to simulate Keyboard Events. In addition to this function, the sendinput function can also simulate global Keyboard Events. In addition, you can use global hooks to simulate keyboard messages.