1

I am trying to simulate a physical keypress (namely, F12) in python, without raising LowLevelKeyHookInjected (0x10) Flag in Windows. The purpose of this is to trigger an action in a program that filters out emulated keyboard presses. This program is an assistive technology that provides alternate access methods for OS control.

I have tried many options, including SendKeys, pyauotogui, pynput, ctype, etc...

If I physically press F12, I can trigger the appropriate action, however, simulating F12 press and release via python using the methods above does not work. Here is an example of what I have tried:

import pynput.keyboard import Key, Controller
import time
Keyboard = Controller()
keyboard.press(Key.f12)
time.sleep(.05)
keyboard.release(Key.f12)

So, it simply simulates the f12 key press, waits for .05 secs, then releases the key.

I am running Python 3.6.6 on Windows

Thank you for all your help in advance!

Peter Yoo
  • 11
  • 1
  • 4

1 Answers1

4

This is what I used when I had this same problem a few days ago. It's a bit messy but it gets the job done. :)

import ctypes
from ctypes import wintypes
import time
user32 = ctypes.WinDLL('user32', use_last_error=True)
INPUT_KEYBOARD = 1
KEYEVENTF_EXTENDEDKEY = 0x0001
KEYEVENTF_KEYUP       = 0x0002
KEYEVENTF_UNICODE     = 0x0004
MAPVK_VK_TO_VSC = 0
# msdn.microsoft.com/en-us/library/dd375731
wintypes.ULONG_PTR = wintypes.WPARAM
class MOUSEINPUT(ctypes.Structure):
    _fields_ = (("dx",          wintypes.LONG),
                ("dy",          wintypes.LONG),
                ("mouseData",   wintypes.DWORD),
                ("dwFlags",     wintypes.DWORD),
                ("time",        wintypes.DWORD),
                ("dwExtraInfo", wintypes.ULONG_PTR))
class KEYBDINPUT(ctypes.Structure):
    _fields_ = (("wVk",         wintypes.WORD),
                ("wScan",       wintypes.WORD),
                ("dwFlags",     wintypes.DWORD),
                ("time",        wintypes.DWORD),
                ("dwExtraInfo", wintypes.ULONG_PTR))
    def __init__(self, *args, **kwds):
        super(KEYBDINPUT, self).__init__(*args, **kwds)
        if not self.dwFlags & KEYEVENTF_UNICODE:
            self.wScan = user32.MapVirtualKeyExW(self.wVk,
                                                 MAPVK_VK_TO_VSC, 0)
class HARDWAREINPUT(ctypes.Structure):
    _fields_ = (("uMsg",    wintypes.DWORD),
                ("wParamL", wintypes.WORD),
                ("wParamH", wintypes.WORD))
class INPUT(ctypes.Structure):
    class _INPUT(ctypes.Union):
        _fields_ = (("ki", KEYBDINPUT),
                    ("mi", MOUSEINPUT),
                    ("hi", HARDWAREINPUT))
    _anonymous_ = ("_input",)
    _fields_ = (("type",   wintypes.DWORD),
                ("_input", _INPUT))
LPINPUT = ctypes.POINTER(INPUT)
def PressKey(hexKeyCode):
    x = INPUT(type=INPUT_KEYBOARD,
              ki=KEYBDINPUT(wVk=hexKeyCode))
    user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
def ReleaseKey(hexKeyCode):
    x = INPUT(type=INPUT_KEYBOARD,
              ki=KEYBDINPUT(wVk=hexKeyCode,
                            dwFlags=KEYEVENTF_KEYUP))
    user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x))
def F12():
    PressKey(0x7B)
    time.sleep(0.5)
    ReleaseKey(0x7B)
    # you can change 0x30 to any key you want. For more info look at :
    # msdn.microsoft.com/en-us/library/dd375731


F12()

Just use F12() to simulate the F12 key.

If you want to simulate other keys as well you can change where is says 0x7B in F12 function to something else (look in msdn.microsoft.com/en-us/library/dd375731 to find what keys have what value). To simulate letters as well this may help convert quickly:

def toKeyCode(c):
    keyCode = keyCodeMap[c[0]]
    return int(keyCode, base=16)

keyCodeMap = {
    'shift'             : "0x10",
    '0'                 : "0x30",
    '1'                 : "0x31",
    '2'                 : "0x32",
    '3'                 : "0x33",
    '4'                 : "0x34",
    '5'                 : "0x35",
    '6'                 : "0x36",
    '7'                 : "0x37",
    '8'                 : "0x38",
    '9'                 : "0x39",
    'a'                 : "0x41",
    'b'                 : "0x42",
    'c'                 : "0x43",
    'd'                 : "0x44",
    'e'                 : "0x45",
    'f'                 : "0x46",
    'g'                 : "0x47",
    'h'                 : "0x48",
    'i'                 : "0x49",
    'j'                 : "0x4A",
    'k'                 : "0x4B",
    'l'                 : "0x4C",
    'm'                 : "0x4D",
    'n'                 : "0x4E",
    'o'                 : "0x4F",
    'p'                 : "0x50",
    'q'                 : "0x51",
    'r'                 : "0x52",
    's'                 : "0x53",
    't'                 : "0x54",
    'u'                 : "0x55",
    'v'                 : "0x56",
    'w'                 : "0x57",
    'x'                 : "0x58",
    'y'                 : "0x59",
    'z'                 : "0x5A",
}

(also this is my first post so if I messed something up I'm sorry :D)

Community
  • 1
  • 1
C. Lang
  • 463
  • 4
  • 12
  • Hi, thanks for this code. Could you explain how to use the INPUTMOUSE class please ? Thanks. I just want to click with you code. Thanks a lot – Dupuis David Jan 06 '22 at 14:57