Recently I was playing death vs fire shadow with my classmates. In memory of childhood, suddenly thought to play with the keyboard is not carefree, so the initiation of the idea of writing a virtual handle.
My idea is to implement the handle on the mobile device (IOS, Android), listen on the computer, use the socket to establish a persistent connection, send the operation code to the listening software on the computer through the mobile device, and handle the event through the opcode.
The service side of the socket, built on a server, allows mobile devices and computers to connect separately, establish channels, and use Python on the server to build socketclient and to use sockets on mobile devices. Not here to tell. The focus of this paper is to implement key events on the computer, including the processing of key combinations.
If we have a virtual handle with 4+6 keys. Each is up or down. 1-6 function keys, the operation code sent is 0~9. When all keys are released. The operation code sent is-1.
In order to implement the key operation, it is necessary to use USER32.DLL's keybd_event (byte bvk, byte bscan, int dwFlags, int dwextrainfo) function, the first parameter is the key code, the second and fourth fill 0 can be, The third represents whether the button is pressed or released, 0 means press, 2 means release.
Because C # cannot invoke those macros directly, the key code is entered into a number to implement. The corresponding table for the key code is as follows:
Virtual key corresponding value corresponding key Vk_lbutton 1 left mouse button Vk_rbutton 2 right mouse button Vk_cancel 3 Cancelvk_mbutton 4 middle mouse button Vk_xbutton1 5 vk_xbutton2 6 Vk_back 8 Backspacevk_tab 9 tabvk_clear Clearvk_return entervk_shift Shiftvk_control-Ctrlvk_menu AltVK_PAUSE Vk_capital Caps Lockvk_kana-Vk_hangul Vk_junja-vk_final Vk_hanja Vk_kanji Vk_nonconvert vk_accept vk_modechange spacevk_prior vk_space upvk_next page downvk_end Endvk_home Homevk_left PNs left arrowvk_up-up arrowvk_right-Arrowvk_down WN arrowvk_select selectvk_print printvk_execute executevk_snapshot-Snapshotvk_insert Letevk_help 0, 1 2 3 4, 5, 6, 7, 8, 9, A, B,, D, E, F, G, H, I, J 7 5 K-L-M-N-O-P-ba-Q-R-K-S-A-T-U-V-W-X-Y-Zvk_lwin-Vk_rwin-Vk_apps-Vk_sleep 95 VK_NUMPAD0 96 Keypad 0vk_nUMPAD1 97 numpad 1vk_numpad2 98 numpad 2vk_numpad3 99 numpad 3vk_numpad4 100 Numpad 4vk_numpad5 101 numpad 5vk_numpad6 102 Keypad 6vk_numpad 7 103 Numpad 7vk_numpad8 104 Numpad 8vk_numpad9 105 numpad 9vk_multiply 106 numpad *vk_add 107 keypad +vk_separator 108 keypad ENTERVK_SUBTR ACT 109 Numpad-vk_decimal 110 Numpad. Vk_divide 111 keypad/vk_f1 F1VK_F2 113 f2vk_f3, F3vk_f4, F4vk_f5, F5vk_f6 117 F6vk_f7 118 F7vk_f8 119 F8VK_F9 1 20 F9VK_F10 121 F10VK_F11 122 F11VK_F12 123 F12VK_F13 124 VK_F14 125 VK_F15 126 VK_F16 127 VK_F17 128 VK_F18 129 VK_F19 13 0 VK_F20 131 VK_F21 132 VK_F22 133 VK_F23 134 VK_F24 135 VK_NUMLOCK 144 Num LockVK_SCROLL 145 ScrollVK_LSHIFT 160 VK_RSHIF T 161 Vk_lcontrol 162 Vk_rcontrol 163 Vk_lmenu 164 Vk_rmenu 165 Vk_browser_back 166 Vk_browser_forward 167 VK_BROWSER_REFR 168 Vk_browser_stop 169 Vk_browser_search ESH vk_browser_favorites 171 vk_browser_home 172 VK_VOLUME_MUTE 173 VolumeMu Tevk_volume_down 174 volumedownvk_volume_up 175 volumeupvk_media_next_track 176 vk_media_prev_track 177 VK_MEDIA_STOP 178 Vk_media_play_pause 179 vk_launch_mail, Vk_launch_media_select 181 VK_LAUNCH_APP1 182 VK_LAUNCH_APP2 183 VK_OE M_1 186; : Vk_oem_plus 187 = +vk_oem_comma 188 Vk_oem_minus 189-_vk_oem_period 191/? Vk_oem_3 192 ' ~vk_oem_4 219 [{Vk_oem_5 220 \ | VK_OEM_6 221 ] }VK_OEM_7 222 ‘ "VK_OEM_8 223 VK_OEM_102 226 VK_PACKET 231 VK_PROCESSKEY 229 VK_ATTN 246 VK_CRSEL 247 VK_EX SEL 248 vk_ereof 249 Vk_play + vk_zoom 251 vk_noname 252 vk_pa1 253 vk_oem_clear 254
In order to implement the key combination, for each key to be processed, you should call the function to implement the key press, and note that the key has been pressed can not be repeatedly pressed, when all keys loose start, to clear all the keys of the press, in order to achieve this purpose. Use the dynamic array ArrayList to record keys that have been pressed.
To use ArrayList, refer to:
Using System.Collections;
ArrayList The basic method is to contains infer whether the element is inside the array. Clear deletes all elements. add element.
We infer whether ArrayList includes the element when each key is pressed, and does not include the call function to hold the key down. and add the key code to the array. Otherwise, no action.
When the key is all released. You should traverse the ArrayList array, let all the pressed keys be released, and then empty the ArrayList.
With this logic, we are able to achieve whatever the keystroke event is.
Here is a detailed explanation of how each module is implemented:
"Press and release of Keys"
Due to the introduction of DLLs. So add a reference:
Using System.Runtime.InteropServices;
then reference a DLL to handle the keyboard:
[DllImport ("USER32. DLL ")]public static extern void keybd_event (byte bvk, byte bscan, int dwFlags, int dwextrainfo);</span>
This function is the key handling function described above. Direct call can simulate keyboard operation, in order to implement the above business logic, when the key press the first to infer whether it has been pressed. Then process, encapsulate a function handle key:
In which Al is a dynamic array. Definitions such as the following:
Static ArrayList Al = new ArrayList (0);
static void Presskey (Byte keycode) { if (!al. Contains (keycode)) { al. ADD (keycode); keybd_event (keycode, 0, 0, 0);} }
This enables the press of the key, and avoids repeated presses.
When the key is all released. To release all keys that have been pressed, and empty the AL:
foreach (Byte key in AL) { keybd_event (key, 0, 2, 0);} Al. Clear ();
"Socket Implementation"
First quote:
Using system.net;using System.Net.Sockets;
Then use a function to implement the socket's listener
static void Runsocket () {//Set ServerIP address IPAddress IP = ipaddress.parse ("<ip address >"); Socket clientsocket = new socket (addressfamily.internetwork, SocketType.Stream, protocoltype.tcp); try {clientsocket.connect (new IPEndPoint (IP, <port >));//configure ServerIP with Port Console.WriteLine ("Connection server succeeded"); } catch {Console.WriteLine ("Failed to connect to server, press ENTER to exit!")"); Return }//Receive data via Clientsocket while (true) {int receivelength = Clientsocket.rec Eive (result); String str = Encoding.ASCII.GetString (result, 0, receivelength); Console.WriteLine ("<" + str + ">"); int option =-1; try {option = Int. Parse (str); } catch {}//Console.WriteLine ("option =" + option); state = option; } }
A function is defined to parse a socket,socket received opcode in a child thread. After the parse succeeds, it is assigned the state. State is the opcode to be processed by the main thread. Represents the press of the button.
Open the code for the socket thread, which is written in the main function:
Thread t = new thread (runsocket); T.start ();
The next part is to deal with the different keys, and the following is the complete source code, which is a C # console program:
For security. I've removed both my IP and port, assuming that you want to use this source code, you need to be aware of the following:
The ①socket server can send characters 0~9,-1 depending on the action of the handle.
② computer-side programs remain open, debug and execution status can be.
Using system;using system.collections.generic;using system.linq;using system.text;using System.Threading.Tasks; Using system.net;using system.net.sockets;using system.threading;using system.runtime.interopservices;using System.collections;namespace socketclient{class Program {static int state = 0; Static ArrayList Al = new ArrayList (0); private static byte[] result = new byte[1024]; [DllImport ("USER32. DLL ")] public static extern void keybd_event (byte bvk, byte bscan, int dwFlags, int dwextrainfo); static void Presskey (byte keycode) {if (!al. Contains (KeyCode)) {al. ADD (KeyCode); keybd_event (keycode, 0, 0, 0); }} static void Main (string[] args) {thread t = new Thread (runsocket); T.start (); Al. Clear (); state =-1; while (true) {if (state! =-1) {SWItch (state) {case 0://W = Presskey (87); Break Case 1://S = Presskey (83); Break Case 2://A = Presskey (65); Break Case 3://D = Presskey (68); Break Case 4://J = Presskey (74); Break Case 5://K = Presskey (75); Break Case 6://L = Presskey (76); Break Case 7://U = Presskey (85); Break Case 8://I =Presskey (73); Break Case 9://O = Presskey (79); Break }} else {foreach (byte key in AL) { keybd_event (Key, 0, 2, 0); } al. Clear (); }}}} static void Runsocket () {//Set ServerIP address IPAddress IP = ipaddr Ess. Parse ("42.96.168.162"); Socket clientsocket = new socket (addressfamily.internetwork, SocketType.Stream, protocoltype.tcp); try {clientsocket.connect (new IPEndPoint (IP, 12345));//configure ServerIP with Port CONSOLE.WR Iteline ("Connection server succeeded"); } catch {Console.WriteLine ("Failed to connect to server, press ENTER to exit!") "); Return }//Receive data via Clientsocket while (true) {int receivelength = Clientsocket.re Ceive (result); String str = Encoding.ASCII.GetString (result, 0, receivelength); Console.WriteLine ("<" + str + ">"); int option =-1; try {option = Int. Parse (str); } catch {}//Console.WriteLine ("option =" + option); state = option; } } }}
A lot of data has been checked to achieve such a few functions. It is not easy, I hope that the need to help you.
Use C#+socket to implement virtual handles that are controlled with a mobile device