using System; using System.Runtime.InteropServices; using System.Text; namespace Vanara.PInvoke { public static partial class User32 { /// Modifiers for key press. [Flags] public enum HotKeyModifiers { /// Nothing held down. MOD_NONE = 0, /// Either ALT key must be held down. MOD_ALT = 0x0001, /// Either CTRL key must be held down. MOD_CONTROL = 0x0002, /// Either SHIFT key must be held down. MOD_SHIFT = 0x0004, /// /// Either WINDOWS key was held down. These keys are labeled with the Windows logo. Keyboard shortcuts that involve the WINDOWS /// key are reserved for use by the operating system. /// MOD_WIN = 0x0008, /// /// Changes the hotkey behavior so that the keyboard auto-repeat does not yield multiple hotkey notifications. /// Windows Vista: This flag is not supported. /// MOD_NOREPEAT = 0x4000, } /// Controls various aspects of function operation of . [PInvokeData("winuser.h", MSDNShortId = "")] [Flags] public enum KEYEVENTF { /// If specified, the scan code was preceded by a prefix byte having the value 0xE0 (224). KEYEVENTF_EXTENDEDKEY = 0x0001, /// If specified, the key is being released. If not specified, the key is being depressed. KEYEVENTF_KEYUP = 0x0002, /// /// If specified, the system synthesizes a VK_PACKET keystroke. The wVk parameter must be zero. This flag can only be combined /// with the KEYEVENTF_KEYUP flag. For more information, see the Remarks section. /// KEYEVENTF_UNICODE = 0x0004, /// If specified, wScan identifies the key and wVk is ignored. KEYEVENTF_SCANCODE = 0x0008, } /// Flags used by keyboard layout functions. [PInvokeData("winuser.h")] [Flags] public enum KLF { /// /// Prior to Windows 8: If the specified input locale identifier is not already loaded, the function loads and activates the /// input locale identifier for the current thread. /// /// Beginning in Windows 8: If the specified input locale identifier is not already loaded, the function loads and activates the /// input locale identifier for the system. /// /// KLF_ACTIVATE = 0x00000001, /// /// Prior to Windows 8: Prevents a ShellProchook procedure from receiving an HSHELL_LANGUAGE hook code when the new input locale /// identifier is loaded. This value is typically used when an application loads multiple input locale identifiers one after /// another. Applying this value to all but the last input locale identifier delays the shell's processing until all input locale /// identifiers have been added. /// Beginning in Windows 8: In this scenario, the last input locale identifier is set for the entire system. /// KLF_NOTELLSHELL = 0x00000080, /// /// Prior to Windows 8: Moves the specified input locale identifier to the head of the input locale identifier list, making that /// locale identifier the active locale identifier for the current thread. This value reorders the input locale identifier list /// even if KLF_ACTIVATE is not provided. /// /// Beginning in Windows 8: Moves the specified input locale identifier to the head of the input locale identifier list, making /// that locale identifier the active locale identifier for the system. This value reorders the input locale identifier list even /// if KLF_ACTIVATE is not provided. /// /// KLF_REORDER = 0x00000008, /// /// If the new input locale identifier has the same language identifier as a current input locale identifier, the new input /// locale identifier replaces the current one as the input locale identifier for that language. If this value is not provided /// and the input locale identifiers have the same language identifiers, the current input locale identifier is not replaced and /// the function returns NULL. /// KLF_REPLACELANG = 0x00000010, /// /// Substitutes the specified input locale identifier with another locale preferred by the user. The system starts with this flag /// set, and it is recommended that your application always use this flag. The substitution occurs only if the registry key /// HKEY_CURRENT_USER\Keyboard\Layout\Substitutes explicitly defines a substitution locale. For example, if the key includes the /// value name "00000409" with value "00010409", loading the U.S. English layout ("00000409") causes the Dvorak U.S. English /// layout ("00010409") to be loaded instead. The system uses KLF_SUBSTITUTE_OK when booting, and it is recommended that all /// applications use this value when loading input locale identifiers to ensure that the user's preference is selected. /// KLF_SUBSTITUTE_OK = 0x00000002, /// /// Prior to Windows 8: This flag is valid only with KLF_ACTIVATE. Activates the specified input locale identifier for the entire /// process and sends the WM_INPUTLANGCHANGE message to the current thread's Focus or Active window. Typically, /// LoadKeyboardLayout activates an input locale identifier only for the current thread. /// /// Beginning in Windows 8: This flag is not used. LoadKeyboardLayout always activates an input locale identifier for the entire /// system if the current process owns the window with keyboard focus. /// /// KLF_SETFORPROCESS = 0x00000100, /// This is used with KLF_RESET. See KLF_RESET for an explanation. KLF_SHIFTLOCK = 0x00010000, /// /// If set but KLF_SHIFTLOCK is not set, the Caps Lock state is turned off by pressing the Caps Lock key again. If set and /// KLF_SHIFTLOCK is also set, the Caps Lock state is turned off by pressing either SHIFT key. /// These two methods are mutually exclusive, and the setting persists as part of the User's profile in the registry. /// KLF_RESET = 0x40000000, } /// The translation to be performed in . [PInvokeData("winuser.h", MSDNShortId = "")] public enum MAPVK { /// /// uCode is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between /// left- and right-hand keys, the left-hand scan code is returned. If there is no translation, the function returns 0. /// MAPVK_VK_TO_VSC = 0, /// /// uCode is a scan code and is translated into a virtual-key code that does not distinguish between left- and right-hand keys. /// If there is no translation, the function returns 0. /// MAPVK_VSC_TO_VK = 1, /// /// uCode is a virtual-key code and is translated into an unshifted character value in the low-order word of the return value. /// Dead keys (diacritics) are indicated by setting the top bit of the return value. If there is no translation, the function /// returns 0. /// MAPVK_VK_TO_CHAR = 2, /// /// uCode is a scan code and is translated into a virtual-key code that distinguishes between left- and right-hand keys. If there /// is no translation, the function returns 0. /// MAPVK_VSC_TO_VK_EX = 3, /// /// The uCode parameter is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not /// distinguish between left- and right-hand keys, the left-hand scan code is returned. If the scan code is an extended scan /// code, the high byte of the uCode value can contain either 0xe0 or 0xe1 to specify the extended scan code. If there is no /// translation, the function returns 0. /// MAPVK_VK_TO_VSC_EX = 4, } /// /// Sets the input locale identifier (formerly called the keyboard layout handle) for the calling thread or the current process. The /// input locale identifier specifies a locale as well as the physical layout of the keyboard. /// /// /// Type: HKL /// Input locale identifier to be activated. /// /// The input locale identifier must have been loaded by a previous call to the LoadKeyboardLayout function. This parameter must be /// either the handle to a keyboard layout or one of the following values. /// /// /// /// Value /// Meaning /// /// /// HKL_NEXT 1 /// Selects the next locale identifier in the circular list of loaded locale identifiers maintained by the system. /// /// /// HKL_PREV 0 /// Selects the previous locale identifier in the circular list of loaded locale identifiers maintained by the system. /// /// /// /// /// Type: UINT /// Specifies how the input locale identifier is to be activated. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// KLF_REORDER 0x00000008 /// /// If this bit is set, the system's circular list of loaded locale identifiers is reordered by moving the locale identifier to the /// head of the list. If this bit is not set, the list is rotated without a change of order. For example, if a user had an English /// locale identifier active, as well as having French, German, and Spanish locale identifiers loaded (in that order), then /// activating the German locale identifier with the KLF_REORDER bit set would produce the following order: German, English, French, /// Spanish. Activating the German locale identifier without the KLF_REORDER bit set would produce the following order: German, /// Spanish, English, French. If less than three locale identifiers are loaded, the value of this flag is irrelevant. /// /// /// /// KLF_RESET 0x40000000 /// /// If set but KLF_SHIFTLOCK is not set, the Caps Lock state is turned off by pressing the Caps Lock key again. If set and /// KLF_SHIFTLOCK is also set, the Caps Lock state is turned off by pressing either SHIFT key. These two methods are mutually /// exclusive, and the setting persists as part of the User's profile in the registry. /// /// /// /// KLF_SETFORPROCESS 0x00000100 /// /// Activates the specified locale identifier for the entire process and sends the WM_INPUTLANGCHANGE message to the current thread's /// focus or active window. /// /// /// /// KLF_SHIFTLOCK 0x00010000 /// This is used with KLF_RESET. See KLF_RESET for an explanation. /// /// /// KLF_UNLOADPREVIOUS /// This flag is unsupported. Use the UnloadKeyboardLayout function instead. /// /// /// /// /// Type: HKL /// /// The return value is of type HKL. If the function succeeds, the return value is the previous input locale identifier. /// Otherwise, it is zero. /// /// To get extended error information, use the GetLastError function. /// /// /// This function only affects the layout for the current process or thread. /// /// This function is not restricted to keyboard layouts. The hkl parameter is actually an input locale identifier. This is a broader /// concept than a keyboard layout, since it can also encompass a speech-to-text converter, an Input Method Editor (IME), or any /// other form of input. Several input locale identifiers can be loaded at any one time, but only one is active at a time. Loading /// multiple input locale identifiers makes it possible to rapidly switch between them. /// /// /// When multiple IMEs are allowed for each locale, passing an input locale identifier in which the high word (the device handle) is /// zero activates the first IME in the list belonging to the locale. /// /// /// The KLF_RESET and KLF_SHIFTLOCK flags alter the method by which the Caps Lock state is turned off. By default, the /// Caps Lock state is turned off by hitting the Caps Lock key again. If only KLF_RESET is set, the default state is /// reestablished. If KLF_RESET and KLF_SHIFTLOCK are set, the Caps Lock state is turned off by pressing either Caps /// Lock key. This feature is used to conform to local keyboard behavior standards as well as for personal preferences. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-activatekeyboardlayout HKL ActivateKeyboardLayout( HKL // hkl, UINT Flags ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h")] public static extern HKL ActivateKeyboardLayout(HKL hkl, KLF Flags); /// Blocks keyboard and mouse input events from reaching applications. /// /// Type: BOOL /// /// The function's purpose. If this parameter is TRUE, keyboard and mouse input events are blocked. If this parameter is /// FALSE, keyboard and mouse events are unblocked. Note that only the thread that blocked input can successfully unblock input. /// /// /// /// Type: BOOL /// If the function succeeds, the return value is nonzero. /// If input is already blocked, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// When input is blocked, real physical input from the mouse or keyboard will not affect the input queue's synchronous key state /// (reported by GetKeyState and GetKeyboardState), nor will it affect the asynchronous key state (reported by GetAsyncKeyState). /// However, the thread that is blocking input can affect both of these key states by calling SendInput. No other thread can do this. /// /// The system will unblock input in the following cases: /// /// /// /// The thread that blocked input unexpectedly exits without calling BlockInput with fBlock set to FALSE. In this case, /// the system cleans up properly and re-enables input. /// /// /// /// /// The user presses CTRL+ALT+DEL or the system invokes the Hard System Error modal message box (for example, when a program /// faults or a device fails). /// /// /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-blockinput BOOL BlockInput( BOOL fBlockIt ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool BlockInput([MarshalAs(UnmanagedType.Bool)] bool fBlockIt); /// /// Determines whether a key is up or down at the time the function is called, and whether the key was pressed after a previous call /// to GetAsyncKeyState. /// /// /// Type: int /// The virtual-key code. For more information, see Virtual Key Codes. /// You can use left- and right-distinguishing constants to specify certain keys. See the Remarks section for further information. /// /// /// Type: SHORT /// /// If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, /// and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant /// bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last /// behavior; for more information, see the Remarks. /// /// The return value is zero for the following cases: /// /// /// The current desktop is not the active desktop /// /// /// The foreground thread belongs to another process and the desktop does not allow the hook or the journal record. /// /// /// /// /// /// The GetAsyncKeyState function works with mouse buttons. However, it checks on the state of the physical mouse buttons, not /// on the logical mouse buttons that the physical buttons are mapped to. For example, the call GetAsyncKeyState(VK_LBUTTON) /// always returns the state of the left physical mouse button, regardless of whether it is mapped to the left or right logical mouse /// button. You can determine the system's current mapping of physical mouse buttons to logical mouse buttons by calling . /// /// which returns TRUE if the mouse buttons have been swapped. /// /// Although the least significant bit of the return value indicates whether the key has been pressed since the last query, due to /// the pre-emptive multitasking nature of Windows, another application can call GetAsyncKeyState and receive the "recently /// pressed" bit instead of your application. The behavior of the least significant bit of the return value is retained strictly for /// compatibility with 16-bit Windows applications (which are non-preemptive) and should not be relied upon. /// /// /// You can use the virtual-key code constants VK_SHIFT, VK_CONTROL, and VK_MENU as values for the vKey /// parameter. This gives the state of the SHIFT, CTRL, or ALT keys without distinguishing between left and right. /// /// /// You can use the following virtual-key code constants as values for vKey to distinguish between the left and right instances of /// those keys. /// /// /// /// Code /// Meaning /// /// /// VK_LSHIFT /// Left-shift key. /// /// /// VK_RSHIFT /// Right-shift key. /// /// /// VK_LCONTROL /// Left-control key. /// /// /// VK_RCONTROL /// Right-control key. /// /// /// VK_LMENU /// Left-menu key. /// /// /// VK_RMENU /// Right-menu key. /// /// /// /// These left- and right-distinguishing constants are only available when you call the GetKeyboardState, SetKeyboardState, /// GetAsyncKeyState, GetKeyState, and MapVirtualKey functions. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getasynckeystate SHORT GetAsyncKeyState( int vKey ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern short GetAsyncKeyState(int vKey); /// /// Retrieves the current code page. /// /// Note This function is provided only for compatibility with 16-bit versions of Windows. Applications should use the /// GetOEMCP function to retrieve the OEM code-page identifier for the system. /// /// /// /// Type: UINT /// /// The return value is an OEM code-page identifier, or it is the default identifier if the registry value is not readable. For a /// list of OEM code-page identifiers, see Code Page Identifiers. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkbcodepage UINT GetKBCodePage( ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern uint GetKBCodePage(); /// Retrieves the active input locale identifier (formerly called the keyboard layout). /// /// Type: DWORD /// The identifier of the thread to query, or 0 for the current thread. /// /// /// Type: HKL /// /// The return value is the input locale identifier for the thread. The low word contains a Language Identifier for the input /// language and the high word contains a device handle to the physical layout of the keyboard. /// /// /// /// /// The input locale identifier is a broader concept than a keyboard layout, since it can also encompass a speech-to-text converter, /// an Input Method Editor (IME), or any other form of input. /// /// /// Since the keyboard layout can be dynamically changed, applications that cache information about the current keyboard layout /// should process the WM_INPUTLANGCHANGE message to be informed of changes in the input language. /// /// To get the KLID (keyboard layout ID) of the currently active HKL, call the GetKeyboardLayoutName. /// /// Beginning in Windows 8: The preferred method to retrieve the language associated with the current keyboard layout or input /// method is a call to Windows.Globalization.Language.CurrentInputMethodLanguageTag. If your app passes language tags from /// CurrentInputMethodLanguageTag to any National Language Support functions, it must first convert the tags by calling ResolveLocaleName. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeyboardlayout HKL GetKeyboardLayout( DWORD idThread ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern HKL GetKeyboardLayout(uint idThread); /// /// Retrieves the input locale identifiers (formerly called keyboard layout handles) corresponding to the current set of input /// locales in the system. The function copies the identifiers to the specified buffer. /// /// /// Type: int /// The maximum number of handles that the buffer can hold. /// /// /// Type: HKL* /// A pointer to the buffer that receives the array of input locale identifiers. /// /// /// Type: int /// /// If the function succeeds, the return value is the number of input locale identifiers copied to the buffer or, if nBuff is zero, /// the return value is the size, in array elements, of the buffer needed to receive all current input locale identifiers. /// /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// The input locale identifier is a broader concept than a keyboard layout, since it can also encompass a speech-to-text converter, /// an Input Method Editor (IME), or any other form of input. /// /// /// Beginning in Windows 8: The preferred method to retrieve the language associated with the current keyboard layout or input /// method is a call to Windows.Globalization.Language.CurrentInputMethodLanguageTag. If your app passes language tags from /// CurrentInputMethodLanguageTag to any National Language Support functions, it must first convert the tags by calling ResolveLocaleName. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeyboardlayoutlist int GetKeyboardLayoutList( int // nBuff, HKL *lpList ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern int GetKeyboardLayoutList(int nBuff, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] HKL[] lpList); /// Retrieves the name of the active input locale identifier (formerly called the keyboard layout) for the system. /// /// Type: LPTSTR /// /// The buffer (of at least KL_NAMELENGTH characters in length) that receives the name of the input locale identifier, /// including the terminating null character. This will be a copy of the string provided to the LoadKeyboardLayout function, unless /// layout substitution took place. /// /// /// /// Type: BOOL /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// The input locale identifier is a broader concept than a keyboard layout, since it can also encompass a speech-to-text converter, /// an Input Method Editor (IME), or any other form of input. /// /// /// Beginning in Windows 8: The preferred method to retrieve the language associated with the current keyboard layout or input /// method is a call to Windows.Globalization.Language.CurrentInputMethodLanguageTag. If your app passes language tags from /// CurrentInputMethodLanguageTag to any National Language Support functions, it must first convert the tags by calling ResolveLocaleName. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeyboardlayoutnamea BOOL GetKeyboardLayoutNameA( LPSTR // pwszKLID ); [DllImport(Lib.User32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("winuser.h", MSDNShortId = "")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetKeyboardLayoutName(StringBuilder pwszKLID); /// Copies the status of the 256 virtual keys to the specified buffer. /// /// Type: PBYTE /// The 256-byte array that receives the status data for each virtual key. /// /// /// Type: BOOL /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// An application can call this function to retrieve the current status of all the virtual keys. The status changes as a thread /// removes keyboard messages from its message queue. The status does not change as keyboard messages are posted to the thread's /// message queue, nor does it change as keyboard messages are posted to or retrieved from message queues of other threads. /// (Exception: Threads that are connected through AttachThreadInput share the same keyboard state.) /// /// /// When the function returns, each member of the array pointed to by the lpKeyState parameter contains status data for a virtual /// key. If the high-order bit is 1, the key is down; otherwise, it is up. If the key is a toggle key, for example CAPS LOCK, then /// the low-order bit is 1 when the key is toggled and is 0 if the key is untoggled. The low-order bit is meaningless for non-toggle /// keys. A toggle key is said to be toggled when it is turned on. A toggle key's indicator light (if any) on the keyboard will be on /// when the key is toggled, and off when the key is untoggled. /// /// /// To retrieve status information for an individual key, use the GetKeyState function. To retrieve the current state for an /// individual key regardless of whether the corresponding keyboard message has been retrieved from the message queue, use the /// GetAsyncKeyState function. /// /// /// An application can use the virtual-key code constants VK_SHIFT, VK_CONTROL and VK_MENU as indices into the /// array pointed to by lpKeyState. This gives the status of the SHIFT, CTRL, or ALT keys without distinguishing between left and /// right. An application can also use the following virtual-key code constants as indices to distinguish between the left and right /// instances of those keys: /// /// /// /// VK_LSHIFT /// /// /// VK_RSHIFT /// /// /// VK_LCONTROL /// /// /// VK_RCONTROL /// /// /// VK_LMENU /// /// /// VK_RMENU /// /// /// /// These left- and right-distinguishing constants are available to an application only through the GetKeyboardState, /// SetKeyboardState, GetAsyncKeyState, GetKeyState, and MapVirtualKey functions. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeyboardstate BOOL GetKeyboardState( PBYTE lpKeyState ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetKeyboardState(byte[] lpKeyState); /// Retrieves information about the current keyboard. /// /// Type: int /// The type of keyboard information to be retrieved. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// 0 /// Keyboard type /// /// /// 1 /// Keyboard subtype /// /// /// 2 /// The number of function keys on the keyboard /// /// /// /// /// Type: int /// If the function succeeds, the return value specifies the requested information. /// /// If the function fails and nTypeFlag is not one, the return value is zero; zero is a valid return value when nTypeFlag is one /// (keyboard subtype). To get extended error information, call GetLastError. /// /// /// /// The type may be one of the following values. /// /// /// Value /// Meaning /// /// /// 1 /// IBM PC/XT or compatible (83-key) keyboard /// /// /// 2 /// Olivetti "ICO" (102-key) keyboard /// /// /// 3 /// IBM PC/AT (84-key) or similar keyboard /// /// /// 4 /// IBM enhanced (101- or 102-key) keyboard /// /// /// 5 /// Nokia 1050 and similar keyboards /// /// /// 6 /// Nokia 9140 and similar keyboards /// /// /// 7 /// Japanese keyboard /// /// /// The subtype is an original equipment manufacturer (OEM)-dependent value. /// /// The application can also determine the number of function keys on a keyboard from the keyboard type. Following are the number of /// function keys for each keyboard type. /// /// /// /// Type /// Number of function keys /// /// /// 1 /// 10 /// /// /// 2 /// 12 (sometimes 18) /// /// /// 3 /// 10 /// /// /// 4 /// 12 /// /// /// 5 /// 10 /// /// /// 6 /// 24 /// /// /// 7 /// Hardware dependent and specified by the OEM /// /// /// When a single USB keyboard is connected to the computer, this function returns the code 81. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeyboardtype int GetKeyboardType( int nTypeFlag ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "39b9ba8b-0cab-465c-9a58-2b69eea7de76")] public static extern int GetKeyboardType(int nTypeFlag); /// Retrieves a string that represents the name of a key. /// /// Type: LONG /// /// The second parameter of the keyboard message (such as WM_KEYDOWN) to be processed. The function interprets the following bit /// positions in the lParam. /// /// /// /// Bits /// Meaning /// /// /// 16-23 /// Scan code. /// /// /// 24 /// Extended-key flag. Distinguishes some keys on an enhanced keyboard. /// /// /// 25 /// /// "Do not care" bit. The application calling this function sets this bit to indicate that the function should not distinguish /// between left and right CTRL and SHIFT keys, for example. /// /// /// /// /// /// Type: LPTSTR /// The buffer that will receive the key name. /// /// /// Type: int /// /// The maximum length, in characters, of the key name, including the terminating null character. (This parameter should be equal to /// the size of the buffer pointed to by the lpString parameter.) /// /// /// /// Type: int /// /// If the function succeeds, a null-terminated string is copied into the specified buffer, and the return value is the length of the /// string, in characters, not counting the terminating null character. /// /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// The format of the key-name string depends on the current keyboard layout. The keyboard driver maintains a list of names in the /// form of character strings for keys with names longer than a single character. The key name is translated according to the layout /// of the currently installed keyboard, thus the function may give different results for different input locales. The name of a /// character key is the character itself. The names of dead keys are spelled out in full. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeynametexta int GetKeyNameTextA( LONG lParam, LPSTR // lpString, int cchSize ); [DllImport(Lib.User32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern int GetKeyNameText(int lParam, StringBuilder lpString, int cchSize); /// /// Retrieves the status of the specified virtual key. The status specifies whether the key is up, down, or toggled (on, /// off—alternating each time the key is pressed). /// /// /// Type: int /// /// A virtual key. If the desired virtual key is a letter or digit (A through Z, a through z, or 0 through 9), nVirtKey must be set /// to the ASCII value of that character. For other keys, it must be a virtual-key code. /// /// /// If a non-English keyboard layout is used, virtual keys with values in the range ASCII A through Z and 0 through 9 are used to /// specify most of the character keys. For example, for the German keyboard layout, the virtual key of value ASCII O (0x4F) refers /// to the "o" key, whereas VK_OEM_1 refers to the "o with umlaut" key. /// /// /// /// Type: SHORT /// The return value specifies the status of the specified virtual key, as follows: /// /// /// If the high-order bit is 1, the key is down; otherwise, it is up. /// /// /// /// If the low-order bit is 1, the key is toggled. A key, such as the CAPS LOCK key, is toggled if it is turned on. The key is off /// and untoggled if the low-order bit is 0. A toggle key's indicator light (if any) on the keyboard will be on when the key is /// toggled, and off when the key is untoggled. /// /// /// /// /// /// /// The key status returned from this function changes as a thread reads key messages from its message queue. The status does not /// reflect the interrupt-level state associated with the hardware. Use the GetAsyncKeyState function to retrieve that information. /// /// /// An application calls GetKeyState in response to a keyboard-input message. This function retrieves the state of the key /// when the input message was generated. /// /// To retrieve state information for all the virtual keys, use the GetKeyboardState function. /// /// An application can use the virtual key code constants VK_SHIFT, VK_CONTROL, and VK_MENU as values for the /// nVirtKey parameter. This gives the status of the SHIFT, CTRL, or ALT keys without distinguishing between left and right. An /// application can also use the following virtual-key code constants as values for nVirtKey to distinguish between the left and /// right instances of those keys: /// /// /// VK_LSHIFTVK_RSHIFTVK_LCONTROLVK_RCONTROLVK_LMENUVK_RMENU These left- and /// right-distinguishing constants are available to an application only through the GetKeyboardState, SetKeyboardState, /// GetAsyncKeyState, GetKeyState, and MapVirtualKey functions. /// /// Examples /// For an example, see Displaying Keyboard Input. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeystate SHORT GetKeyState( int nVirtKey ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern short GetKeyState(int nVirtKey); /// /// /// Synthesizes a keystroke. The system can use such a synthesized keystroke to generate a WM_KEYUP or WM_KEYDOWN message. The /// keyboard driver's interrupt handler calls the keybd_event function. /// /// Note This function has been superseded. Use SendInput instead. /// /// /// Type: BYTE /// A virtual-key code. The code must be a value in the range 1 to 254. For a complete list, see Virtual Key Codes. /// /// /// Type: BYTE /// A hardware scan code for the key. /// /// /// Type: DWORD /// Controls various aspects of function operation. This parameter can be one or more of the following values. /// /// /// Value /// Meaning /// /// /// KEYEVENTF_EXTENDEDKEY 0x0001 /// If specified, the scan code was preceded by a prefix byte having the value 0xE0 (224). /// /// /// KEYEVENTF_KEYUP 0x0002 /// If specified, the key is being released. If not specified, the key is being depressed. /// /// /// /// /// Type: ULONG_PTR /// An additional value associated with the key stroke. /// /// /// /// An application can simulate a press of the PRINTSCRN key in order to obtain a screen snapshot and save it to the clipboard. To do /// this, call keybd_event with the bVk parameter set to VK_SNAPSHOT. /// /// Examples /// /// The following sample program toggles the NUM LOCK light by using keybd_event with a virtual key of VK_NUMLOCK. It /// takes a Boolean value that indicates whether the light should be turned off ( FALSE) or on ( TRUE). The same /// technique can be used for the CAPS LOCK key ( VK_CAPITAL) and the SCROLL LOCK key ( VK_SCROLL). /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-keybd_event void keybd_event( BYTE bVk, BYTE bScan, DWORD // dwFlags, ULONG_PTR dwExtraInfo ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern void keybd_event(byte bVk, byte bScan, KEYEVENTF dwFlags, UIntPtr dwExtraInfo); /// /// Loads a new input locale identifier (formerly called the keyboard layout) into the system. /// /// Prior to Windows 8: Several input locale identifiers can be loaded at a time, but only one per process is active at a /// time. Loading multiple input locale identifiers makes it possible to rapidly switch between them. /// /// /// Beginning in Windows 8: The input locale identifier is loaded for the entire system. This function has no effect if the /// current process does not own the window with keyboard focus. /// /// /// /// Type: LPCTSTR /// /// The name of the input locale identifier to load. This name is a string composed of the hexadecimal value of the Language /// Identifier (low word) and a device identifier (high word). For example, U.S. English has a language identifier of 0x0409, so the /// primary U.S. English layout is named "00000409". Variants of U.S. English layout (such as the Dvorak layout) are named /// "00010409", "00020409", and so on. /// /// /// /// Type: UINT /// Specifies how the input locale identifier is to be loaded. This parameter can be one of the following values. /// /// /// Value /// Meaning /// /// /// KLF_ACTIVATE 0x00000001 /// /// Prior to Windows 8: If the specified input locale identifier is not already loaded, the function loads and activates the input /// locale identifier for the current thread. Beginning in Windows 8: If the specified input locale identifier is not already loaded, /// the function loads and activates the input locale identifier for the system. /// /// /// /// KLF_NOTELLSHELL 0x00000080 /// /// Prior to Windows 8: Prevents a ShellProchook procedure from receiving an HSHELL_LANGUAGE hook code when the new input locale /// identifier is loaded. This value is typically used when an application loads multiple input locale identifiers one after another. /// Applying this value to all but the last input locale identifier delays the shell's processing until all input locale identifiers /// have been added. Beginning in Windows 8: In this scenario, the last input locale identifier is set for the entire system. /// /// /// /// KLF_REORDER 0x00000008 /// /// Prior to Windows 8: Moves the specified input locale identifier to the head of the input locale identifier list, making that /// locale identifier the active locale identifier for the current thread. This value reorders the input locale identifier list even /// if KLF_ACTIVATE is not provided. Beginning in Windows 8: Moves the specified input locale identifier to the head of the input /// locale identifier list, making that locale identifier the active locale identifier for the system. This value reorders the input /// locale identifier list even if KLF_ACTIVATE is not provided. /// /// /// /// KLF_REPLACELANG 0x00000010 /// /// If the new input locale identifier has the same language identifier as a current input locale identifier, the new input locale /// identifier replaces the current one as the input locale identifier for that language. If this value is not provided and the input /// locale identifiers have the same language identifiers, the current input locale identifier is not replaced and the function /// returns NULL. /// /// /// /// KLF_SUBSTITUTE_OK 0x00000002 /// /// Substitutes the specified input locale identifier with another locale preferred by the user. The system starts with this flag /// set, and it is recommended that your application always use this flag. The substitution occurs only if the registry key /// HKEY_CURRENT_USER\Keyboard\Layout\Substitutes explicitly defines a substitution locale. For example, if the key includes the /// value name "00000409" with value "00010409", loading the U.S. English layout ("00000409") causes the Dvorak U.S. English layout /// ("00010409") to be loaded instead. The system uses KLF_SUBSTITUTE_OK when booting, and it is recommended that all applications /// use this value when loading input locale identifiers to ensure that the user's preference is selected. /// /// /// /// KLF_SETFORPROCESS 0x00000100 /// /// Prior to Windows 8: This flag is valid only with KLF_ACTIVATE. Activates the specified input locale identifier for the entire /// process and sends the WM_INPUTLANGCHANGE message to the current thread's Focus or Active window. Typically, LoadKeyboardLayout /// activates an input locale identifier only for the current thread. Beginning in Windows 8: This flag is not used. /// LoadKeyboardLayout always activates an input locale identifier for the entire system if the current process owns the window with /// keyboard focus. /// /// /// /// KLF_UNLOADPREVIOUS /// This flag is unsupported. Use the UnloadKeyboardLayout function instead. /// /// /// /// /// Type: HKL /// /// If the function succeeds, the return value is the input locale identifier corresponding to the name specified in pwszKLID. If no /// matching locale is available, the return value is the default language of the system. To get extended error information, call GetLastError. /// /// /// /// /// The input locale identifier is a broader concept than a keyboard layout, since it can also encompass a speech-to-text converter, /// an Input Method Editor (IME), or any other form of input. /// /// /// An application can and will typically load the default input locale identifier or IME for a language and can do so by specifying /// only a string version of the language identifier. If an application wants to load a specific locale or IME, it should read the /// registry to determine the specific input locale identifier to pass to LoadKeyboardLayout. In this case, a request to /// activate the default input locale identifier for a locale will activate the first matching one. A specific IME should be /// activated using an explicit input locale identifier returned from GetKeyboardLayout or LoadKeyboardLayout. /// /// Prior to Windows 8: This function only affects the layout for the current process or thread. /// Beginning in Windows 8: This function affects the layout for the entire system. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-loadkeyboardlayouta HKL LoadKeyboardLayoutA( LPCSTR // pwszKLID, UINT Flags ); [DllImport(Lib.User32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern SafeHKL LoadKeyboardLayout(string pwszKLID, KLF Flags); /// /// /// Translates (maps) a virtual-key code into a scan code or character value, or translates a scan code into a virtual-key code. /// /// To specify a handle to the keyboard layout to use for translating the specified code, use the MapVirtualKeyEx function. /// /// /// Type: UINT /// The virtual key code or scan code for a key. How this value is interpreted depends on the value of the uMapType parameter. /// /// /// Type: UINT /// The translation to be performed. The value of this parameter depends on the value of the uCode parameter. /// /// /// Value /// Meaning /// /// /// MAPVK_VK_TO_CHAR 2 /// /// uCode is a virtual-key code and is translated into an unshifted character value in the low-order word of the return value. Dead /// keys (diacritics) are indicated by setting the top bit of the return value. If there is no translation, the function returns 0. /// /// /// /// MAPVK_VK_TO_VSC 0 /// /// uCode is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between /// left- and right-hand keys, the left-hand scan code is returned. If there is no translation, the function returns 0. /// /// /// /// MAPVK_VSC_TO_VK 1 /// /// uCode is a scan code and is translated into a virtual-key code that does not distinguish between left- and right-hand keys. If /// there is no translation, the function returns 0. /// /// /// /// MAPVK_VSC_TO_VK_EX 3 /// /// uCode is a scan code and is translated into a virtual-key code that distinguishes between left- and right-hand keys. If there is /// no translation, the function returns 0. /// /// /// /// /// /// Type: UINT /// /// The return value is either a scan code, a virtual-key code, or a character value, depending on the value of uCode and uMapType. /// If there is no translation, the return value is zero. /// /// /// /// /// An application can use MapVirtualKey to translate scan codes to the virtual-key code constants VK_SHIFT, /// VK_CONTROL, and VK_MENU, and vice versa. These translations do not distinguish between the left and right instances /// of the SHIFT, CTRL, or ALT keys. /// /// /// An application can get the scan code corresponding to the left or right instance of one of these keys by calling /// MapVirtualKey with uCode set to one of the following virtual-key code constants. /// /// /// /// VK_LSHIFT /// /// /// VK_RSHIFT /// /// /// VK_LCONTROL /// /// /// VK_RCONTROL /// /// /// VK_LMENU /// /// /// VK_RMENU /// /// /// /// These left- and right-distinguishing constants are available to an application only through the GetKeyboardState, /// SetKeyboardState, GetAsyncKeyState, GetKeyState, and MapVirtualKey functions. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-mapvirtualkeya UINT MapVirtualKeyA( UINT uCode, UINT // uMapType ); [DllImport(Lib.User32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern uint MapVirtualKey(uint uCode, MAPVK uMapType); /// /// Translates (maps) a virtual-key code into a scan code or character value, or translates a scan code into a virtual-key code. The /// function translates the codes using the input language and an input locale identifier. /// /// /// Type: UINT /// The virtual-key code or scan code for a key. How this value is interpreted depends on the value of the uMapType parameter. /// /// Starting with Windows Vista, the high byte of the uCode value can contain either 0xe0 or 0xe1 to specify the extended scan code. /// /// /// /// Type: UINT /// The translation to perform. The value of this parameter depends on the value of the uCode parameter. /// /// /// Value /// Meaning /// /// /// MAPVK_VK_TO_CHAR 2 /// /// The uCode parameter is a virtual-key code and is translated into an unshifted character value in the low order word of the return /// value. Dead keys (diacritics) are indicated by setting the top bit of the return value. If there is no translation, the function /// returns 0. /// /// /// /// MAPVK_VK_TO_VSC 0 /// /// The uCode parameter is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not /// distinguish between left- and right-hand keys, the left-hand scan code is returned. If there is no translation, the function /// returns 0. /// /// /// /// MAPVK_VK_TO_VSC_EX 4 /// /// The uCode parameter is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not /// distinguish between left- and right-hand keys, the left-hand scan code is returned. If the scan code is an extended scan code, /// the high byte of the uCode value can contain either 0xe0 or 0xe1 to specify the extended scan code. If there is no translation, /// the function returns 0. /// /// /// /// MAPVK_VSC_TO_VK 1 /// /// The uCode parameter is a scan code and is translated into a virtual-key code that does not distinguish between left- and /// right-hand keys. If there is no translation, the function returns 0. /// /// /// /// MAPVK_VSC_TO_VK_EX 3 /// /// The uCode parameter is a scan code and is translated into a virtual-key code that distinguishes between left- and right-hand /// keys. If there is no translation, the function returns 0. /// /// /// /// /// /// Type: HKL /// /// Input locale identifier to use for translating the specified code. This parameter can be any input locale identifier previously /// returned by the LoadKeyboardLayout function. /// /// /// /// Type: UINT /// /// The return value is either a scan code, a virtual-key code, or a character value, depending on the value of uCode and uMapType. /// If there is no translation, the return value is zero. /// /// /// /// /// The input locale identifier is a broader concept than a keyboard layout, since it can also encompass a speech-to-text converter, /// an Input Method Editor (IME), or any other form of input. /// /// /// An application can use MapVirtualKeyEx to translate scan codes to the virtual-key code constants VK_SHIFT, /// VK_CONTROL, and VK_MENU, and vice versa. These translations do not distinguish between the left and right instances /// of the SHIFT, CTRL, or ALT keys. /// /// /// An application can get the scan code corresponding to the left or right instance of one of these keys by calling /// MapVirtualKeyEx with uCode set to one of the following virtual-key code constants. /// /// /// /// VK_LSHIFT /// /// /// VK_RSHIFT /// /// /// VK_LCONTROL /// /// /// VK_RCONTROL /// /// /// VK_LMENU /// /// /// VK_RMENU /// /// /// /// These left- and right-distinguishing constants are available to an application only through the GetKeyboardState, /// SetKeyboardState, GetAsyncKeyState, GetKeyState, MapVirtualKey, and MapVirtualKeyEx functions. For list complete table of /// virtual key codes, see Virtual Key Codes. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-mapvirtualkeyexa UINT MapVirtualKeyExA( UINT uCode, UINT // uMapType, HKL dwhkl ); [DllImport(Lib.User32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern uint MapVirtualKeyEx(uint uCode, MAPVK uMapType, HKL dwhkl); /// /// Maps OEMASCII codes 0 through 0x0FF into the OEM scan codes and shift states. The function provides information that allows a /// program to send OEM text to another program by simulating keyboard input. /// /// /// Type: WORD /// The ASCII value of the OEM character. /// /// /// Type: DWORD /// /// The low-order word of the return value contains the scan code of the OEM character, and the high-order word contains the shift /// state, which can be a combination of the following bits. /// /// /// /// Bit /// Description /// /// /// 1 /// Either SHIFT key is pressed. /// /// /// 2 /// Either CTRL key is pressed. /// /// /// 4 /// Either ALT key is pressed. /// /// /// 8 /// The Hankaku key is pressed. /// /// /// 16 /// Reserved (defined by the keyboard layout driver). /// /// /// 32 /// Reserved (defined by the keyboard layout driver). /// /// /// If the character cannot be produced by a single keystroke using the current keyboard layout, the return value is –1. /// /// /// /// This function does not provide translations for characters that require CTRL+ALT or dead keys. Characters not translated by this /// function must be copied by simulating input using the ALT+ keypad mechanism. The NUMLOCK key must be off. /// /// /// This function does not provide translations for characters that cannot be typed with one keystroke using the current keyboard /// layout, such as characters with diacritics requiring dead keys. Characters not translated by this function may be simulated using /// the ALT+ keypad mechanism. The NUMLOCK key must be on. /// /// This function is implemented using the VkKeyScan function. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-oemkeyscan DWORD OemKeyScan( WORD wOemChar ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern uint OemKeyScan(ushort wOemChar); /// /// Defines a system-wide hot key. /// /// /// Type: HWND /// /// A handle to the window that will receive WM_HOTKEY messages generated by the hot key. If this parameter is NULL, /// WM_HOTKEY messages are posted to the message queue of the calling thread and must be processed in the message loop. /// /// /// /// Type: int /// /// The identifier of the hot key. If the hWnd parameter is NULL, then the hot key is associated with the current thread rather than /// with a particular window. If a hot key already exists with the same hWnd and id parameters, see Remarks for the action taken. /// /// /// /// Type: UINT /// /// The keys that must be pressed in combination with the key specified by the uVirtKey parameter in order to generate the WM_HOTKEY /// message. The fsModifiers parameter can be a combination of the following values. /// /// /// /// Value /// Meaning /// /// /// MOD_ALT 0x0001 /// Either ALT key must be held down. /// /// /// MOD_CONTROL 0x0002 /// Either CTRL key must be held down. /// /// /// MOD_NOREPEAT 0x4000 /// /// Changes the hotkey behavior so that the keyboard auto-repeat does not yield multiple hotkey notifications. Windows Vista: This /// flag is not supported. /// /// /// /// MOD_SHIFT 0x0004 /// Either SHIFT key must be held down. /// /// /// MOD_WIN 0x0008 /// /// Either WINDOWS key was held down. These keys are labeled with the Windows logo. Keyboard shortcuts that involve the WINDOWS key /// are reserved for use by the operating system. /// /// /// /// /// /// Type: UINT /// The virtual-key code of the hot key. See Virtual Key Codes. /// /// /// Type: BOOL /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// When a key is pressed, the system looks for a match against all hot keys. Upon finding a match, the system posts the WM_HOTKEY /// message to the message queue of the window with which the hot key is associated. If the hot key is not associated with a window, /// then the WM_HOTKEY message is posted to the thread associated with the hot key. /// /// This function cannot associate a hot key with a window created by another thread. /// RegisterHotKey fails if the keystrokes specified for the hot key have already been registered by another hot key. /// /// If a hot key already exists with the same hWnd and id parameters, it is maintained along with the new hot key. The application /// must explicitly call UnregisterHotKey to unregister the old hot key. /// /// /// Windows Server 2003: If a hot key already exists with the same hWnd and id parameters, it is replaced by the new hot key. /// /// /// The F12 key is reserved for use by the debugger at all times, so it should not be registered as a hot key. Even when you are not /// debugging an application, F12 is reserved in case a kernel-mode debugger or a just-in-time debugger is resident. /// /// /// An application must specify an id value in the range 0x0000 through 0xBFFF. A shared DLL must specify a value in the range 0xC000 /// through 0xFFFF (the range returned by the GlobalAddAtom function). To avoid conflicts with hot-key identifiers defined by other /// shared DLLs, a DLL should use the GlobalAddAtom function to obtain the hot-key identifier. /// /// Examples /// /// The following example shows how to use the RegisterHotKey function with the MOD_NOREPEAT flag. In this example, the /// hotkey 'ALT+b' is registered for the main thread. When the hotkey is pressed, the thread will receive a WM_HOTKEY message, which /// will get picked up in the GetMessage call. Because this example uses MOD_ALT with the MOD_NOREPEAT value for /// fsModifiers, the thread will only receive another WM_HOTKEY message when the 'b' key is released and then pressed again /// while the 'ALT' key is being pressed down. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registerhotkey BOOL RegisterHotKey( HWND hWnd, int id, // UINT fsModifiers, UINT vk ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "registerhotkey")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool RegisterHotKey(HWND hWnd, int id, HotKeyModifiers fsModifiers, uint vk); /// /// /// Copies an array of keyboard key states into the calling thread's keyboard input-state table. This is the same table accessed by /// the GetKeyboardState and GetKeyState functions. Changes made to this table do not affect keyboard input to any other thread. /// /// /// /// Type: LPBYTE /// A pointer to a 256-byte array that contains keyboard key states. /// /// /// Type: BOOL /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// /// /// /// Because the SetKeyboardState function alters the input state of the calling thread and not the global input state of the /// system, an application cannot use SetKeyboardState to set the NUM LOCK, CAPS LOCK, or SCROLL LOCK (or the Japanese KANA) /// indicator lights on the keyboard. These can be set or cleared using SendInput to simulate keystrokes. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setkeyboardstate BOOL SetKeyboardState( LPBYTE lpKeyState ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetKeyboardState([In] byte[] lpKeyState); /// /// /// Translates the specified virtual-key code and keyboard state to the corresponding character or characters. The function /// translates the code using the input language and physical keyboard layout identified by the keyboard layout handle. /// /// To specify a handle to the keyboard layout to use to translate the specified code, use the ToAsciiEx function. /// /// /// Type: UINT /// The virtual-key code to be translated. See Virtual-Key Codes. /// /// /// Type: UINT /// The hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up (not pressed). /// /// /// Type: const BYTE* /// /// A pointer to a 256-byte array that contains the current keyboard state. Each element (byte) in the array contains the state of /// one key. If the high-order bit of a byte is set, the key is down (pressed). /// /// /// The low bit, if set, indicates that the key is toggled on. In this function, only the toggle bit of the CAPS LOCK key is /// relevant. The toggle state of the NUM LOCK and SCROLL LOCK keys is ignored. /// /// /// /// Type: LPWORD /// The buffer that receives the translated character or characters. /// /// /// Type: UINT /// This parameter must be 1 if a menu is active, or 0 otherwise. /// /// /// Type: int /// If the specified key is a dead key, the return value is negative. Otherwise, it is one of the following values. /// /// /// Return value /// Description /// /// /// 0 /// The specified virtual key has no translation for the current state of the keyboard. /// /// /// 1 /// One character was copied to the buffer. /// /// /// 2 /// /// Two characters were copied to the buffer. This usually happens when a dead-key character (accent or diacritic) stored in the /// keyboard layout cannot be composed with the specified virtual key to form a single character. /// /// /// /// /// /// /// The parameters supplied to the ToAscii function might not be sufficient to translate the virtual-key code, because a /// previous dead key is stored in the keyboard layout. /// /// /// Typically, ToAscii performs the translation based on the virtual-key code. In some cases, however, bit 15 of the uScanCode /// parameter may be used to distinguish between a key press and a key release. The scan code is used for translating ALT+ number key combinations. /// /// /// Although NUM LOCK is a toggle key that affects keyboard behavior, ToAscii ignores the toggle setting (the low bit) of /// lpKeyState ( VK_NUMLOCK) because the uVirtKey parameter alone is sufficient to distinguish the cursor movement keys ( /// VK_HOME, VK_INSERT, and so on) from the numeric keys ( VK_DECIMAL, VK_NUMPAD0 - VK_NUMPAD9). /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-toascii int ToAscii( UINT uVirtKey, UINT uScanCode, const // BYTE *lpKeyState, LPWORD lpChar, UINT uFlags ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern int ToAscii(uint uVirtKey, uint uScanCode, byte[] lpKeyState, out ushort lpChar, uint uFlags); /// /// Translates the specified virtual-key code and keyboard state to the corresponding character or characters. The function /// translates the code using the input language and physical keyboard layout identified by the input locale identifier. /// /// /// Type: UINT /// The virtual-key code to be translated. See Virtual-Key Codes. /// /// /// Type: UINT /// The hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up (not pressed). /// /// /// Type: const BYTE* /// /// A pointer to a 256-byte array that contains the current keyboard state. Each element (byte) in the array contains the state of /// one key. If the high-order bit of a byte is set, the key is down (pressed). /// /// /// The low bit, if set, indicates that the key is toggled on. In this function, only the toggle bit of the CAPS LOCK key is /// relevant. The toggle state of the NUM LOCK and SCOLL LOCK keys is ignored. /// /// /// /// Type: LPWORD /// A pointer to the buffer that receives the translated character or characters. /// /// /// Type: UINT /// This parameter must be 1 if a menu is active, zero otherwise. /// /// /// Type: HKL /// /// Input locale identifier to use to translate the code. This parameter can be any input locale identifier previously returned by /// the LoadKeyboardLayout function. /// /// /// /// Type: int /// If the specified key is a dead key, the return value is negative. Otherwise, it is one of the following values. /// /// /// Return value /// Description /// /// /// 0 /// The specified virtual key has no translation for the current state of the keyboard. /// /// /// 1 /// One character was copied to the buffer. /// /// /// 2 /// /// Two characters were copied to the buffer. This usually happens when a dead-key character (accent or diacritic) stored in the /// keyboard layout cannot be composed with the specified virtual key to form a single character. /// /// /// /// /// /// /// The input locale identifier is a broader concept than a keyboard layout, since it can also encompass a speech-to-text converter, /// an Input Method Editor (IME), or any other form of input. /// /// /// The parameters supplied to the ToAsciiEx function might not be sufficient to translate the virtual-key code, because a /// previous dead key is stored in the keyboard layout. /// /// /// Typically, ToAsciiEx performs the translation based on the virtual-key code. In some cases, however, bit 15 of the /// uScanCode parameter may be used to distinguish between a key press and a key release. The scan code is used for translating /// ALT+number key combinations. /// /// /// Although NUM LOCK is a toggle key that affects keyboard behavior, ToAsciiEx ignores the toggle setting (the low bit) of /// lpKeyState ( VK_NUMLOCK) because the uVirtKey parameter alone is sufficient to distinguish the cursor movement keys ( /// VK_HOME, VK_INSERT, and so on) from the numeric keys ( VK_DECIMAL, VK_NUMPAD0 - VK_NUMPAD9). /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-toasciiex int ToAsciiEx( UINT uVirtKey, UINT uScanCode, // const BYTE *lpKeyState, LPWORD lpChar, UINT uFlags, HKL dwhkl ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern int ToAsciiEx(uint uVirtKey, uint uScanCode, byte[] lpKeyState, out ushort lpChar, uint uFlags, HKL dwhkl); /// /// Translates the specified virtual-key code and keyboard state to the corresponding Unicode character or characters. /// To specify a handle to the keyboard layout to use to translate the specified code, use the ToUnicodeEx function. /// /// /// Type: UINT /// The virtual-key code to be translated. See Virtual-Key Codes. /// /// /// Type: UINT /// The hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up. /// /// /// Type: const BYTE* /// /// A pointer to a 256-byte array that contains the current keyboard state. Each element (byte) in the array contains the state of /// one key. If the high-order bit of a byte is set, the key is down. /// /// /// /// Type: LPWSTR /// /// The buffer that receives the translated Unicode character or characters. However, this buffer may be returned without being /// null-terminated even though the variable name suggests that it is null-terminated. /// /// /// /// Type: int /// The size, in characters, of the buffer pointed to by the pwszBuff parameter. /// /// /// Type: UINT /// The behavior of the function. /// If bit 0 is set, a menu is active. /// If bit 2 is set, keyboard state is not changed (Windows 10, version 1607 and newer) /// All other bits (through 31) are reserved. /// /// /// Type: int /// The function returns one of the following values. /// /// /// Return value /// Description /// /// /// -1 /// /// The specified virtual key is a dead-key character (accent or diacritic). This value is returned regardless of the keyboard /// layout, even if several characters have been typed and are stored in the keyboard state. If possible, even with Unicode keyboard /// layouts, the function has written a spacing version of the dead-key character to the buffer specified by pwszBuff. For example, /// the function writes the character SPACING ACUTE (0x00B4), rather than the character NON_SPACING ACUTE (0x0301). /// /// /// /// 0 /// /// The specified virtual key has no translation for the current state of the keyboard. Nothing was written to the buffer specified /// by pwszBuff. /// /// /// /// 1 /// One character was written to the buffer specified by pwszBuff. /// /// /// 2 ≤ value /// /// Two or more characters were written to the buffer specified by pwszBuff. The most common cause for this is that a dead-key /// character (accent or diacritic) stored in the keyboard layout could not be combined with the specified virtual key to form a /// single character. However, the buffer may contain more characters than the return value specifies. When this happens, any extra /// characters are invalid and should be ignored. /// /// /// /// /// /// /// The parameters supplied to the ToUnicode function might not be sufficient to translate the virtual-key code because a /// previous dead key is stored in the keyboard layout. /// /// /// Typically, ToUnicode performs the translation based on the virtual-key code. In some cases, however, bit 15 of the /// wScanCode parameter can be used to distinguish between a key press and a key release. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-tounicode int ToUnicode( UINT wVirtKey, UINT wScanCode, // const BYTE *lpKeyState, LPWSTR pwszBuff, int cchBuff, UINT wFlags ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern int ToUnicode(uint wVirtKey, uint wScanCode, byte[] lpKeyState, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszBuff, int cchBuff, uint wFlags); /// Translates the specified virtual-key code and keyboard state to the corresponding Unicode character or characters. /// /// Type: UINT /// The virtual-key code to be translated. See Virtual-Key Codes. /// /// /// Type: UINT /// The hardware scan code of the key to be translated. The high-order bit of this value is set if the key is up. /// /// /// Type: const BYTE* /// /// A pointer to a 256-byte array that contains the current keyboard state. Each element (byte) in the array contains the state of /// one key. If the high-order bit of a byte is set, the key is down. /// /// /// /// Type: LPWSTR /// /// The buffer that receives the translated Unicode character or characters. However, this buffer may be returned without being /// null-terminated even though the variable name suggests that it is null-terminated. /// /// /// /// Type: int /// The size, in characters, of the buffer pointed to by the pwszBuff parameter. /// /// /// Type: UINT /// The behavior of the function. /// If bit 0 is set, a menu is active. /// If bit 2 is set, keyboard state is not changed (Windows 10, version 1607 and newer) /// All other bits (through 31) are reserved. /// /// /// Type: HKL /// /// The input locale identifier used to translate the specified code. This parameter can be any input locale identifier previously /// returned by the LoadKeyboardLayout function. /// /// /// /// Type: int /// The function returns one of the following values. /// /// /// Return value /// Description /// /// /// -1 /// /// The specified virtual key is a dead-key character (accent or diacritic). This value is returned regardless of the keyboard /// layout, even if several characters have been typed and are stored in the keyboard state. If possible, even with Unicode keyboard /// layouts, the function has written a spacing version of the dead-key character to the buffer specified by pwszBuff. For example, /// the function writes the character SPACING ACUTE (0x00B4), rather than the character NON_SPACING ACUTE (0x0301). /// /// /// /// 0 /// /// The specified virtual key has no translation for the current state of the keyboard. Nothing was written to the buffer specified /// by pwszBuff. /// /// /// /// 1 /// One character was written to the buffer specified by pwszBuff. /// /// /// 2 ≤ value /// /// Two or more characters were written to the buffer specified by pwszBuff. The most common cause for this is that a dead-key /// character (accent or diacritic) stored in the keyboard layout could not be combined with the specified virtual key to form a /// single character. However, the buffer may contain more characters than the return value specifies. When this happens, any extra /// characters are invalid and should be ignored. /// /// /// /// /// /// /// The input locale identifier is a broader concept than a keyboard layout, since it can also encompass a speech-to-text converter, /// an Input Method Editor (IME), or any other form of input. /// /// /// The parameters supplied to the ToUnicodeEx function might not be sufficient to translate the virtual-key code because a /// previous dead key is stored in the keyboard layout. /// /// /// Typically, ToUnicodeEx performs the translation based on the virtual-key code. In some cases, however, bit 15 of the /// wScanCode parameter can be used to distinguish between a key press and a key release. /// /// /// As ToUnicodeEx translates the virtual-key code, it also changes the state of the kernel-mode keyboard buffer. This /// state-change affects dead keys, ligatures, alt+numpad key entry, and so on. It might also cause undesired side-effects if used in /// conjunction with TranslateMessage (which also changes the state of the kernel-mode keyboard buffer). /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-tounicodeex int ToUnicodeEx( UINT wVirtKey, UINT // wScanCode, const BYTE *lpKeyState, LPWSTR pwszBuff, int cchBuff, UINT wFlags, HKL dwhkl ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern int ToUnicodeEx(uint wVirtKey, uint wScanCode, byte[] lpKeyState, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszBuff, int cchBuff, uint wFlags, HKL dwhkl); /// Unloads an input locale identifier (formerly called a keyboard layout). /// /// Type: HKL /// The input locale identifier to be unloaded. /// /// /// Type: BOOL /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. The function can fail for the following reasons: /// /// /// An invalid input locale identifier was passed. /// /// /// The input locale identifier was preloaded. /// /// /// The input locale identifier is in use. /// /// /// To get extended error information, call GetLastError. /// /// /// /// The input locale identifier is a broader concept than a keyboard layout, since it can also encompass a speech-to-text converter, /// an Input Method Editor (IME), or any other form of input. /// /// /// UnloadKeyboardLayout cannot unload the system default input locale identifier if it is the only keyboard layout loaded. /// You must first load another input locale identifier before unloading the default input locale identifier. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-unloadkeyboardlayout BOOL UnloadKeyboardLayout( HKL hkl ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool UnloadKeyboardLayout(HKL hkl); /// /// Frees a hot key previously registered by the calling thread. /// /// /// Type: HWND /// /// A handle to the window associated with the hot key to be freed. This parameter should be NULL if the hot key is not /// associated with a window. /// /// /// /// Type: int /// The identifier of the hot key to be freed. /// /// /// Type: BOOL /// If the function succeeds, the return value is nonzero. /// If the function fails, the return value is zero. To get extended error information, call GetLastError. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-unregisterhotkey BOOL UnregisterHotKey( HWND hWnd, int id ); [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "unregisterhotkey")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool UnregisterHotKey(HWND hWnd, int id); /// /// /// [This function has been superseded by the VkKeyScanEx function. You can still use VkKeyScan, however, if you do not need /// to specify a keyboard layout.] /// /// Translates a character to the corresponding virtual-key code and shift state for the current keyboard. /// /// /// Type: TCHAR /// The character to be translated into a virtual-key code. /// /// /// Type: SHORT /// /// If the function succeeds, the low-order byte of the return value contains the virtual-key code and the high-order byte contains /// the shift state, which can be a combination of the following flag bits. /// /// /// /// Return value /// Description /// /// /// 1 /// Either SHIFT key is pressed. /// /// /// 2 /// Either CTRL key is pressed. /// /// /// 4 /// Either ALT key is pressed. /// /// /// 8 /// The Hankaku key is pressed /// /// /// 16 /// Reserved (defined by the keyboard layout driver). /// /// /// 32 /// Reserved (defined by the keyboard layout driver). /// /// /// /// If the function finds no key that translates to the passed character code, both the low-order and high-order bytes contain –1. /// /// /// /// /// For keyboard layouts that use the right-hand ALT key as a shift key (for example, the French keyboard layout), the shift state is /// represented by the value 6, because the right-hand ALT key is converted internally into CTRL+ALT. /// /// /// Translations for the numeric keypad ( VK_NUMPAD0 through VK_DIVIDE) are ignored. This function is intended to /// translate characters into keystrokes from the main keyboard section only. For example, the character "7" is translated into VK_7, /// not VK_NUMPAD7. /// /// VkKeyScan is used by applications that send characters by using the WM_KEYUP and WM_KEYDOWN messages. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-vkkeyscana SHORT VkKeyScanA( CHAR ch ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern short VkKeyScanA(byte ch); /// /// Translates a character to the corresponding virtual-key code and shift state. The function translates the character using the /// input language and physical keyboard layout identified by the input locale identifier. /// /// /// Type: TCHAR /// The character to be translated into a virtual-key code. /// /// /// Type: HKL /// /// Input locale identifier used to translate the character. This parameter can be any input locale identifier previously returned by /// the LoadKeyboardLayout function. /// /// /// /// Type: SHORT /// /// If the function succeeds, the low-order byte of the return value contains the virtual-key code and the high-order byte contains /// the shift state, which can be a combination of the following flag bits. /// /// /// /// Return value /// Description /// /// /// 1 /// Either SHIFT key is pressed. /// /// /// 2 /// Either CTRL key is pressed. /// /// /// 4 /// Either ALT key is pressed. /// /// /// 8 /// The Hankaku key is pressed /// /// /// 16 /// Reserved (defined by the keyboard layout driver). /// /// /// 32 /// Reserved (defined by the keyboard layout driver). /// /// /// /// If the function finds no key that translates to the passed character code, both the low-order and high-order bytes contain –1. /// /// /// /// /// The input locale identifier is a broader concept than a keyboard layout, since it can also encompass a speech-to-text converter, /// an Input Method Editor (IME), or any other form of input. /// /// /// For keyboard layouts that use the right-hand ALT key as a shift key (for example, the French keyboard layout), the shift state is /// represented by the value 6, because the right-hand ALT key is converted internally into CTRL+ALT. /// /// /// Translations for the numeric keypad (VK_NUMPAD0 through VK_DIVIDE) are ignored. This function is intended to translate characters /// into keystrokes from the main keyboard section only. For example, the character "7" is translated into VK_7, not VK_NUMPAD7. /// /// VkKeyScanEx is used by applications that send characters by using the WM_KEYUP and WM_KEYDOWN messages. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-vkkeyscanexa SHORT VkKeyScanExA( CHAR ch, HKL dwhkl ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern short VkKeyScanExA(byte ch, HKL dwhkl); /// /// Translates a character to the corresponding virtual-key code and shift state. The function translates the character using the /// input language and physical keyboard layout identified by the input locale identifier. /// /// /// Type: TCHAR /// The character to be translated into a virtual-key code. /// /// /// Type: HKL /// /// Input locale identifier used to translate the character. This parameter can be any input locale identifier previously returned by /// the LoadKeyboardLayout function. /// /// /// /// Type: SHORT /// /// If the function succeeds, the low-order byte of the return value contains the virtual-key code and the high-order byte contains /// the shift state, which can be a combination of the following flag bits. /// /// /// /// Return value /// Description /// /// /// 1 /// Either SHIFT key is pressed. /// /// /// 2 /// Either CTRL key is pressed. /// /// /// 4 /// Either ALT key is pressed. /// /// /// 8 /// The Hankaku key is pressed /// /// /// 16 /// Reserved (defined by the keyboard layout driver). /// /// /// 32 /// Reserved (defined by the keyboard layout driver). /// /// /// /// If the function finds no key that translates to the passed character code, both the low-order and high-order bytes contain –1. /// /// /// /// /// The input locale identifier is a broader concept than a keyboard layout, since it can also encompass a speech-to-text converter, /// an Input Method Editor (IME), or any other form of input. /// /// /// For keyboard layouts that use the right-hand ALT key as a shift key (for example, the French keyboard layout), the shift state is /// represented by the value 6, because the right-hand ALT key is converted internally into CTRL+ALT. /// /// /// Translations for the numeric keypad (VK_NUMPAD0 through VK_DIVIDE) are ignored. This function is intended to translate characters /// into keystrokes from the main keyboard section only. For example, the character "7" is translated into VK_7, not VK_NUMPAD7. /// /// VkKeyScanEx is used by applications that send characters by using the WM_KEYUP and WM_KEYDOWN messages. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-vkkeyscanexw SHORT VkKeyScanExW( WCHAR ch, HKL dwhkl ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern short VkKeyScanExW(char ch, HKL dwhkl); /// /// /// [This function has been superseded by the VkKeyScanEx function. You can still use VkKeyScan, however, if you do not need /// to specify a keyboard layout.] /// /// Translates a character to the corresponding virtual-key code and shift state for the current keyboard. /// /// /// Type: TCHAR /// The character to be translated into a virtual-key code. /// /// /// Type: SHORT /// /// If the function succeeds, the low-order byte of the return value contains the virtual-key code and the high-order byte contains /// the shift state, which can be a combination of the following flag bits. /// /// /// /// Return value /// Description /// /// /// 1 /// Either SHIFT key is pressed. /// /// /// 2 /// Either CTRL key is pressed. /// /// /// 4 /// Either ALT key is pressed. /// /// /// 8 /// The Hankaku key is pressed /// /// /// 16 /// Reserved (defined by the keyboard layout driver). /// /// /// 32 /// Reserved (defined by the keyboard layout driver). /// /// /// /// If the function finds no key that translates to the passed character code, both the low-order and high-order bytes contain –1. /// /// /// /// /// For keyboard layouts that use the right-hand ALT key as a shift key (for example, the French keyboard layout), the shift state is /// represented by the value 6, because the right-hand ALT key is converted internally into CTRL+ALT. /// /// /// Translations for the numeric keypad ( VK_NUMPAD0 through VK_DIVIDE) are ignored. This function is intended to /// translate characters into keystrokes from the main keyboard section only. For example, the character "7" is translated into VK_7, /// not VK_NUMPAD7. /// /// VkKeyScan is used by applications that send characters by using the WM_KEYUP and WM_KEYDOWN messages. /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-vkkeyscanw SHORT VkKeyScanW( WCHAR ch ); [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winuser.h", MSDNShortId = "")] public static extern short VkKeyScanW(char ch); /// Provides a handle to a . [StructLayout(LayoutKind.Sequential)] public struct HKL : IHandle { private IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. public HKL(IntPtr preexistingHandle) => handle = preexistingHandle; /// Returns an invalid handle by instantiating a object with . public static HKL NULL => new HKL(IntPtr.Zero); /// Gets a value indicating whether this instance is a null handle. public bool IsNull => handle == IntPtr.Zero; /// Performs an explicit conversion from to . /// The handle. /// The result of the conversion. public static explicit operator IntPtr(HKL h) => h.handle; /// Performs an implicit conversion from to . /// The pointer to a handle. /// The result of the conversion. public static implicit operator HKL(IntPtr h) => new HKL(h); /// Implements the operator !=. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator !=(HKL h1, HKL h2) => !(h1 == h2); /// Implements the operator ==. /// The first handle. /// The second handle. /// The result of the operator. public static bool operator ==(HKL h1, HKL h2) => h1.Equals(h2); /// public override bool Equals(object obj) => obj is HKL h ? handle == h.handle : false; /// public override int GetHashCode() => handle.GetHashCode(); /// public IntPtr DangerousGetHandle() => handle; } /// Contains information about a simulated keyboard event. /// /// /// INPUT_KEYBOARD supports nonkeyboard-input methods—such as handwriting recognition or voice recognition—as if it were text /// input by using the KEYEVENTF_UNICODE flag. If KEYEVENTF_UNICODE is specified, SendInput sends a WM_KEYDOWN or /// WM_KEYUP message to the foreground thread's message queue with wParam equal to VK_PACKET. Once GetMessage or PeekMessage /// obtains this message, passing the message to TranslateMessage posts a WM_CHAR message with the Unicode character originally /// specified by wScan. This Unicode character will automatically be converted to the appropriate ANSI value if it is posted /// to an ANSI window. /// /// /// Set the KEYEVENTF_SCANCODE flag to define keyboard input in terms of the scan code. This is useful to simulate a physical /// keystroke regardless of which keyboard is currently being used. The virtual key value of a key may alter depending on the current /// keyboard layout or what other keys were pressed, but the scan code will always be the same. /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winuser/ns-winuser-tagkeybdinput typedef struct tagKEYBDINPUT { WORD wVk; // WORD wScan; DWORD dwFlags; DWORD time; ULONG_PTR dwExtraInfo; } KEYBDINPUT, *PKEYBDINPUT, *LPKEYBDINPUT; [PInvokeData("winuser.h", MSDNShortId = "")] [StructLayout(LayoutKind.Sequential)] public struct KEYBDINPUT { /// /// Type: WORD /// /// A virtual-key code. The code must be a value in the range 1 to 254. If the dwFlags member specifies /// KEYEVENTF_UNICODE, wVk must be 0. /// /// public ushort wVk; /// /// Type: WORD /// /// A hardware scan code for the key. If dwFlags specifies KEYEVENTF_UNICODE, wScan specifies a Unicode /// character which is to be sent to the foreground application. /// /// public ushort wScan; /// /// Type: DWORD /// Specifies various aspects of a keystroke. This member can be certain combinations of the following values. /// /// /// Value /// Meaning /// /// /// KEYEVENTF_EXTENDEDKEY 0x0001 /// If specified, the scan code was preceded by a prefix byte that has the value 0xE0 (224). /// /// /// KEYEVENTF_KEYUP 0x0002 /// If specified, the key is being released. If not specified, the key is being pressed. /// /// /// KEYEVENTF_SCANCODE 0x0008 /// If specified, wScan identifies the key and wVk is ignored. /// /// /// KEYEVENTF_UNICODE 0x0004 /// /// If specified, the system synthesizes a VK_PACKET keystroke. The wVk parameter must be zero. This flag can only be combined /// with the KEYEVENTF_KEYUP flag. For more information, see the Remarks section. /// /// /// /// public KEYEVENTF dwFlags; /// /// Type: DWORD /// The time stamp for the event, in milliseconds. If this parameter is zero, the system will provide its own time stamp. /// public uint time; /// /// Type: ULONG_PTR /// An additional value associated with the keystroke. Use the GetMessageExtraInfo function to obtain this information. /// public UIntPtr dwExtraInfo; } /// Provides a for that is disposed using . public class SafeHKL : SafeHANDLE { /// Initializes a new instance of the class and assigns an existing handle. /// An object that represents the pre-existing handle to use. /// /// to reliably release the handle during the finalization phase; otherwise, (not recommended). /// public SafeHKL(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } /// Initializes a new instance of the class. private SafeHKL() : base() { } /// Performs an implicit conversion from to . /// The safe handle instance. /// The result of the conversion. public static implicit operator HKL(SafeHKL h) => h.handle; /// protected override bool InternalReleaseHandle() => UnloadKeyboardLayout(this); } } }