# Loading the libraries we need
import ctypes  # library to wrap C compatible data types, calling functions in DLLs or shared libraries in Python
import time

SendInput = ctypes.windll.user32.SendInput
# windll is used to loading dynamic link libraries for Windows
# DLL stands for Dynamic Link Library  file.
# Unline exe files, they run in the address space of some other program, i.e. they need to be invoked
# Helpful for Reusability of code. Can be used by multiple applications at the same time
# user32.dll is one such dll used in windows by multiple applications
# SendInput is a function inside user32.dll that synthesizes keystrokes, mouse motions, and button clicks. 

# Each key on any keyboard has a unique Direct Input Keyboard(DIK) code. They are not character symbols. They refer to the position of the key on the keyboard.
# Refer: https://community.bistudio.com/wiki/DIK_KeyCodes
W = 0x11  # Direct Input Keyboard code for W
A = 0x1E  # Direct Input Keyboard code for A
S = 0x1F  # Direct Input Keyboard code for S
D = 0x20  # Direct Input Keyboard code for D

# c_ulong is unsigned long data type in C
# Pointer function is used to create a pointer
p = ctypes.POINTER(ctypes.c_ulong)


class KeyBoardInput(ctypes.Structure):
    # This contains information about a simulated keyboard event.
    # Refer: https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-keybdinput
    _fields_ = [("wVk", ctypes.c_ushort),
                ("wScan", ctypes.c_ushort),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", p)]

# wVk is a virtual-key code. 
# The code must be a value in the range 1 to 254

# wScan is a hardware scan code for the key.

# dwFlags specifies various aspects of a keystroke like if a key is being pressed or released

# time gives the time stamp for the event, in milliseconds

# dwExtraInfo is an additional value associated with the keystroke. 
# An application calls GetMessageExtraInfo to obtain this extra information.


class HardwareInput(ctypes.Structure):
    # This contains information about a simulated message generated by an input device other than a keyboard or mouse.
    # Refer: https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-hardwareinput
    _fields_ = [("uMsg", ctypes.c_ulong),
                ("wParamL", ctypes.c_short),
                ("wParamH", ctypes.c_ushort)]

# uMsg is the message generated by the input hardware.

# wParamL is the low-order word of the lParam parameter for uMsg.

# wParamH is the high-order word of the lParam parameter for uMsg.

class MouseInput(ctypes.Structure):
    # This contains information about a simulated mouse event.
    # Refer: https: // docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput
    _fields_ = [("dx", ctypes.c_long),
                ("dy", ctypes.c_long),
                ("mouseData", ctypes.c_ulong),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", p)]


# dx is the mouse's absolute position along the x-axis or its amount of motion since the last mouse event was generated, 
# depending on the setting of MOUSEEVENTF_ABSOLUTE

# dy is the mouse's absolute position along the y-axis or its amount of motion since the last mouse event was generated,
#  depending on the setting of MOUSEEVENTF_ABSOLUTE

# mouseData specifies the amount of wheel movement. 
# A positive value indicates that the wheel was rotated forward, away from the user
# A negative value indicates that the wheel was rotated backward, toward the user

# dwFlags is controls various aspects of mouse motion and button clicking like left button down, left button up,right button down,etc

# time gives the time stamp for the event, in milliseconds

# dwExtraInfo is an additional value associated with the mouse event. 
#   An application calls GetMessageExtraInfo to obtain this extra information.

class Input_I(ctypes.Union):
    # Creating an union for the KeyBoard Input,Mouse Input and Hardware Input
    _fields_ = [("keyboard_i", KeyBoardInput),
                ("mouse_i", MouseInput),
                ("hardware_i", HardwareInput)]

class Input(ctypes.Structure):
    _fields_ = [("type", ctypes.c_ulong),
                ("ii", Input_I)]


# SendInput Function synthesizes keystrokes, mouse motions, and button clicks.
# The number of structures in the pInputs array.
# An array of INPUT structures. Each structure represents an event to be inserted into the keyboard or mouse input stream.
# Refer: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput

# hexKeyCode is the virtual keyboard mapping as defined by the Windows API. The list of codes is available on MSDN

def PressKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.keyboard_i = KeyBoardInput(0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra))
    x = Input(ctypes.c_ulong(1), ii_)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def ReleaseKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.keyboard_i = KeyBoardInput(0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra))
    x = Input(ctypes.c_ulong(1), ii_)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

# KEYEVENTF_EXTENDEDKEY = 0x0001
# KEYEVENTF_KEYUP = 0x0002
# KEYEVENTF_UNICODE = 0x0004
# KEYEVENTF_SCANCODE = 0x0008

# INPUT_MOUSE = 0
# INPUT_KEYBOARD = 1
# INPUT_HARDWARE = 2

if __name__ == '__main__':
    PressKey(0x11)
    time.sleep(1)
    ReleaseKey(0x11)
    time.sleep(1)

# Loading the libraries we need
import ctypes  # library to wrap C compatible data types, calling functions in DLLs or shared libraries in Python
import time

SendInput = ctypes.windll.user32.SendInput
# windll is used to loading dynamic link libraries for Windows
# DLL stands for Dynamic Link Library  file.
# Unline exe files, they run in the address space of some other program, i.e. they need to be invoked
# Helpful for Reusability of code. Can be used by multiple applications at the same time
# user32.dll is one such dll used in windows by multiple applications
# SendInput is a function inside user32.dll that synthesizes keystrokes, mouse motions, and button clicks. 

# Each key on any keyboard has a unique Direct Input Keyboard(DIK) code. They are not character symbols. They refer to the position of the key on the keyboard.
# Refer: https://community.bistudio.com/wiki/DIK_KeyCodes
W = 0x11  # Direct Input Keyboard code for W
A = 0x1E  # Direct Input Keyboard code for A
S = 0x1F  # Direct Input Keyboard code for S
D = 0x20  # Direct Input Keyboard code for D

# c_ulong is unsigned long data type in C
# Pointer function is used to create a pointer
p = ctypes.POINTER(ctypes.c_ulong)


class KeyBoardInput(ctypes.Structure):
    # This contains information about a simulated keyboard event.
    # Refer: https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-keybdinput
    _fields_ = [("wVk", ctypes.c_ushort),
                ("wScan", ctypes.c_ushort),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", p)]

# wVk is a virtual-key code. 
# The code must be a value in the range 1 to 254

# wScan is a hardware scan code for the key.

# dwFlags specifies various aspects of a keystroke like if a key is being pressed or released

# time gives the time stamp for the event, in milliseconds

# dwExtraInfo is an additional value associated with the keystroke. 
# An application calls GetMessageExtraInfo to obtain this extra information.


class HardwareInput(ctypes.Structure):
    # This contains information about a simulated message generated by an input device other than a keyboard or mouse.
    # Refer: https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-hardwareinput
    _fields_ = [("uMsg", ctypes.c_ulong),
                ("wParamL", ctypes.c_short),
                ("wParamH", ctypes.c_ushort)]

# uMsg is the message generated by the input hardware.

# wParamL is the low-order word of the lParam parameter for uMsg.

# wParamH is the high-order word of the lParam parameter for uMsg.

class MouseInput(ctypes.Structure):
    # This contains information about a simulated mouse event.
    # Refer: https: // docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput
    _fields_ = [("dx", ctypes.c_long),
                ("dy", ctypes.c_long),
                ("mouseData", ctypes.c_ulong),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", p)]


# dx is the mouse's absolute position along the x-axis or its amount of motion since the last mouse event was generated, 
# depending on the setting of MOUSEEVENTF_ABSOLUTE

# dy is the mouse's absolute position along the y-axis or its amount of motion since the last mouse event was generated,
#  depending on the setting of MOUSEEVENTF_ABSOLUTE

# mouseData specifies the amount of wheel movement. 
# A positive value indicates that the wheel was rotated forward, away from the user
# A negative value indicates that the wheel was rotated backward, toward the user

# dwFlags is controls various aspects of mouse motion and button clicking like left button down, left button up,right button down,etc

# time gives the time stamp for the event, in milliseconds

# dwExtraInfo is an additional value associated with the mouse event. 
#   An application calls GetMessageExtraInfo to obtain this extra information.

class Input_I(ctypes.Union):
    # Creating an union for the KeyBoard Input,Mouse Input and Hardware Input
    _fields_ = [("keyboard_i", KeyBoardInput),
                ("mouse_i", MouseInput),
                ("hardware_i", HardwareInput)]

class Input(ctypes.Structure):
    _fields_ = [("type", ctypes.c_ulong),
                ("ii", Input_I)]


# SendInput Function synthesizes keystrokes, mouse motions, and button clicks.
# The number of structures in the pInputs array.
# An array of INPUT structures. Each structure represents an event to be inserted into the keyboard or mouse input stream.
# Refer: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput

# hexKeyCode is the virtual keyboard mapping as defined by the Windows API. The list of codes is available on MSDN

def PressKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.keyboard_i = KeyBoardInput(0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra))
    x = Input(ctypes.c_ulong(1), ii_)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def ReleaseKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.keyboard_i = KeyBoardInput(0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra))
    x = Input(ctypes.c_ulong(1), ii_)
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

# KEYEVENTF_EXTENDEDKEY = 0x0001
# KEYEVENTF_KEYUP = 0x0002
# KEYEVENTF_UNICODE = 0x0004
# KEYEVENTF_SCANCODE = 0x0008

# INPUT_MOUSE = 0
# INPUT_KEYBOARD = 1
# INPUT_HARDWARE = 2

if __name__ == '__main__':
    PressKey(0x11)
    time.sleep(1)
    ReleaseKey(0x11)
    time.sleep(1)

# Loading the libraries we need # library to wrap C compatible data types, calling functions in DLLs or shared libraries in Python # windll is used to loading dynamic link libraries for Windows # DLL stands for Dynamic Link Library  file. # Unline exe files, they run in the address space of some other program, i.e. they need to be invoked # Helpful for Reusability of code. Can be used by multiple applications at the same time # user32.dll is one such dll used in windows by multiple applications # SendInput is a function inside user32.dll that synthesizes keystrokes, mouse motions, and button clicks. # Each key on any keyboard has a unique Direct Input Keyboard(DIK) code. They are not character symbols. They refer to the position of the key on the keyboard. # Refer: https://community.bistudio.com/wiki/DIK_KeyCodes # Direct Input Keyboard code for W # Direct Input Keyboard code for A # Direct Input Keyboard code for S # Direct Input Keyboard code for D # c_ulong is unsigned long data type in C # Pointer function is used to create a pointer # This contains information about a simulated keyboard event. # Refer: https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-keybdinput # wVk is a virtual-key code. # The code must be a value in the range 1 to 254 # wScan is a hardware scan code for the key. # dwFlags specifies various aspects of a keystroke like if a key is being pressed or released # time gives the time stamp for the event, in milliseconds # dwExtraInfo is an additional value associated with the keystroke. # An application calls GetMessageExtraInfo to obtain this extra information. # This contains information about a simulated message generated by an input device other than a keyboard or mouse. # Refer: https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-hardwareinput # uMsg is the message generated by the input hardware. # wParamL is the low-order word of the lParam parameter for uMsg. # wParamH is the high-order word of the lParam parameter for uMsg. # This contains information about a simulated mouse event. # Refer: https: // docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput # dx is the mouse's absolute position along the x-axis or its amount of motion since the last mouse event was generated, # depending on the setting of MOUSEEVENTF_ABSOLUTE # dy is the mouse's absolute position along the y-axis or its amount of motion since the last mouse event was generated, #  depending on the setting of MOUSEEVENTF_ABSOLUTE # mouseData specifies the amount of wheel movement. # A positive value indicates that the wheel was rotated forward, away from the user # A negative value indicates that the wheel was rotated backward, toward the user # dwFlags is controls various aspects of mouse motion and button clicking like left button down, left button up,right button down,etc # time gives the time stamp for the event, in milliseconds # dwExtraInfo is an additional value associated with the mouse event. #   An application calls GetMessageExtraInfo to obtain this extra information. # Creating an union for the KeyBoard Input,Mouse Input and Hardware Input # SendInput Function synthesizes keystrokes, mouse motions, and button clicks. # The number of structures in the pInputs array. # An array of INPUT structures. Each structure represents an event to be inserted into the keyboard or mouse input stream. # Refer: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput # hexKeyCode is the virtual keyboard mapping as defined by the Windows API. The list of codes is available on MSDN # KEYEVENTF_EXTENDEDKEY = 0x0001 # KEYEVENTF_KEYUP = 0x0002 # KEYEVENTF_UNICODE = 0x0004 # KEYEVENTF_SCANCODE = 0x0008 # INPUT_MOUSE = 0 # INPUT_KEYBOARD = 1 # INPUT_HARDWARE = 2