"Fossies" - the Fresh Open Source Software Archive

Member "AutoHotkey_L-1.1.33.09/source/keyboard_mouse.h" (8 May 2021, 18415 Bytes) of package /windows/misc/AutoHotkey_L-1.1.33.09.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "keyboard_mouse.h" see the Fossies "Dox" file reference documentation.

    1 /*
    2 AutoHotkey
    3 
    4 Copyright 2003-2009 Chris Mallett (support@autohotkey.com)
    5 
    6 This program is free software; you can redistribute it and/or
    7 modify it under the terms of the GNU General Public License
    8 as published by the Free Software Foundation; either version 2
    9 of the License, or (at your option) any later version.
   10 
   11 This program is distributed in the hope that it will be useful,
   12 but WITHOUT ANY WARRANTY; without even the implied warranty of
   13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14 GNU General Public License for more details.
   15 */
   16 
   17 #ifndef keyboard_h
   18 #define keyboard_h
   19 
   20 #include "defines.h"
   21 EXTERN_G;
   22 
   23 // The max number of keystrokes to Send prior to taking a break to pump messages:
   24 #define MAX_LUMP_KEYS 50
   25 
   26 // Logging keys to a file is disabled in the main version in an effort to prevent
   27 // AutoHotkey from being branded as a key logger or trojan by various security firms and
   28 // security software. Uncomment this line to re-enabled logging of keys to a file:
   29 // #define ENABLE_KEY_HISTORY_FILE
   30 
   31 // Maybe define more of these later, perhaps with ifndef (since they should be in the normal header, and probably
   32 // will be eventually):
   33 // ALREADY DEFINED: #define VK_HELP 0x2F
   34 // In case a compiler with a non-updated header file is used:
   35 #ifndef VK_BROWSER_BACK
   36     #define VK_BROWSER_BACK        0xA6
   37     #define VK_BROWSER_FORWARD     0xA7
   38     #define VK_BROWSER_REFRESH     0xA8
   39     #define VK_BROWSER_STOP        0xA9
   40     #define VK_BROWSER_SEARCH      0xAA
   41     #define VK_BROWSER_FAVORITES   0xAB
   42     #define VK_BROWSER_HOME        0xAC
   43     #define VK_VOLUME_MUTE         0xAD
   44     #define VK_VOLUME_DOWN         0xAE
   45     #define VK_VOLUME_UP           0xAF
   46     #define VK_MEDIA_NEXT_TRACK    0xB0
   47     #define VK_MEDIA_PREV_TRACK    0xB1
   48     #define VK_MEDIA_STOP          0xB2
   49     #define VK_MEDIA_PLAY_PAUSE    0xB3
   50     #define VK_LAUNCH_MAIL         0xB4
   51     #define VK_LAUNCH_MEDIA_SELECT 0xB5
   52     #define VK_LAUNCH_APP1         0xB6
   53     #define VK_LAUNCH_APP2         0xB7
   54 #endif
   55 
   56 // Create some "fake" virtual keys to simplify sections of the code.
   57 // According to winuser.h, the following ranges (among others)
   58 // are considered "unassigned" rather than "reserved", so should be
   59 // fairly safe to use for the foreseeable future.  0xFF should probably
   60 // be avoided since it's sometimes used as a failure indictor by API
   61 // calls.  And 0x00 should definitely be avoided because it is used
   62 // to indicate failure by many functions that deal with virtual keys.
   63 // 0x88 - 0x8F : unassigned
   64 // 0x97 - 0x9F : unassigned (this range seems less likely to be used)
   65 #define VK_NEW_MOUSE_FIRST 0x9A
   66 #define VK_LBUTTON_LOGICAL 0x9A // v1.0.43: Added to support swapping of left/right mouse buttons in Control Panel.
   67 #define VK_RBUTTON_LOGICAL 0x9B //
   68 #define VK_WHEEL_LEFT      0x9C // v1.0.48: Lexikos: Fake virtual keys for support for horizontal scrolling in
   69 #define VK_WHEEL_RIGHT     0x9D // Windows Vista and later.
   70 #define VK_WHEEL_DOWN      0x9E
   71 #define VK_WHEEL_UP        0x9F
   72 #define IS_WHEEL_VK(aVK) ((aVK) >= VK_WHEEL_LEFT && (aVK) <= VK_WHEEL_UP)
   73 #define VK_NEW_MOUSE_LAST  0x9F
   74 
   75 // These are the only keys for which another key with the same VK exists.  Therefore, use scan code for these.
   76 // If use VK for some of these (due to them being more likely to be used as hotkeys, thus minimizing the
   77 // use of the keyboard hook), be sure to use SC for its counterpart.
   78 // Always use the compressed version of scancode, i.e. 0x01 for the high-order byte rather than vs. 0xE0.
   79 #define SC_NUMPADENTER 0x11C
   80 #define SC_INSERT 0x152
   81 #define SC_DELETE 0x153
   82 #define SC_HOME 0x147
   83 #define SC_END 0x14F
   84 #define SC_UP 0x148
   85 #define SC_DOWN 0x150
   86 #define SC_LEFT 0x14B
   87 #define SC_RIGHT 0x14D
   88 #define SC_PGUP 0x149
   89 #define SC_PGDN 0x151
   90 
   91 // These are the same scan codes as their counterpart except the extended flag is 0 rather than
   92 // 1 (0xE0 uncompressed):
   93 #define SC_ENTER 0x1C
   94 // In addition, the below dual-state numpad keys share the same scan code (but different vk's)
   95 // regardless of the state of numlock:
   96 #define SC_NUMPADDEL 0x53
   97 #define SC_NUMPADINS 0x52
   98 #define SC_NUMPADEND 0x4F
   99 #define SC_NUMPADHOME 0x47
  100 #define SC_NUMPADCLEAR 0x4C
  101 #define SC_NUMPADUP 0x48
  102 #define SC_NUMPADDOWN 0x50
  103 #define SC_NUMPADLEFT 0x4B
  104 #define SC_NUMPADRIGHT 0x4D
  105 #define SC_NUMPADPGUP 0x49
  106 #define SC_NUMPADPGDN 0x51
  107 
  108 #define SC_NUMPADDOT SC_NUMPADDEL
  109 #define SC_NUMPAD0 SC_NUMPADINS
  110 #define SC_NUMPAD1 SC_NUMPADEND
  111 #define SC_NUMPAD2 SC_NUMPADDOWN
  112 #define SC_NUMPAD3 SC_NUMPADPGDN
  113 #define SC_NUMPAD4 SC_NUMPADLEFT
  114 #define SC_NUMPAD5 SC_NUMPADCLEAR
  115 #define SC_NUMPAD6 SC_NUMPADRIGHT
  116 #define SC_NUMPAD7 SC_NUMPADHOME
  117 #define SC_NUMPAD8 SC_NUMPADUP
  118 #define SC_NUMPAD9 SC_NUMPADPGUP
  119 
  120 #define SC_NUMLOCK 0x145
  121 #define SC_NUMPADDIV 0x135
  122 #define SC_NUMPADMULT 0x037
  123 #define SC_NUMPADSUB 0x04A
  124 #define SC_NUMPADADD 0x04E
  125 #define SC_PAUSE 0x045
  126 
  127 #define SC_LCONTROL 0x01D
  128 #define SC_RCONTROL 0x11D
  129 #define SC_LSHIFT 0x02A
  130 #define SC_RSHIFT 0x136 // Must be extended, at least on WinXP, or there will be problems, e.g. SetModifierLRState().
  131 #define SC_LALT 0x038
  132 #define SC_RALT 0x138
  133 #define SC_LWIN 0x15B
  134 #define SC_RWIN 0x15C
  135 
  136 #define SC_APPSKEY 0x15D
  137 #define SC_PRINTSCREEN 0x137
  138 
  139 // The system injects events with these scan codes:
  140 //  - For Shift-up prior to a Numpad keydown or keyup if Numlock is on and Shift is down;
  141 //    e.g. to translate Shift+Numpad1 to unshifted-NumpadEnd.
  142 //  - For Shift-down prior to a non-Numpad keydown if a Numpad key is still held down
  143 //    after the above; e.g. for Shift+Numpad1+Esc.
  144 //  - For LCtrl generated by AltGr.
  145 // Note that the system uses the normal scan codes (0x2A or 0x36) for Shift-down following
  146 // the Numpad keyup if no other keys were pushed.  Our hook filters out the second byte to
  147 // simplify the code, so these values can only be found in KBDLLHOOKSTRUCT::scanCode.
  148 // Find "fake shift-key events" for older and more detailed comments.
  149 // Note that 0x0200 corresponds to SCANCODE_SIMULATED in kbd.h (DDK).
  150 #define SC_FAKE_LSHIFT 0x22A
  151 #define SC_FAKE_RSHIFT 0x236 // This is the actual scancode received by the hook, excluding the 0x100 we add for "extended" keys.
  152 #define SC_FAKE_LCTRL 0x21D
  153 
  154 // UPDATE for v1.0.39: Changed sc_type to USHORT vs. UINT to save memory in structs such as sc_hotkey.
  155 // This saves 60K of memory in one place, and possibly there are other large savings too.
  156 // The following older comment dates back to 2003/inception and I don't remember its exact intent,
  157 // but there is no current storage of mouse message constants in scan code variables:
  158 // OLD: Although only need 9 bits for compressed and 16 for uncompressed scan code, use a full 32 bits 
  159 // so that mouse messages (WPARAM) can be stored as scan codes.  Formerly USHORT (which is always 16-bit).
  160 typedef USHORT sc_type; // Scan code.
  161 typedef UCHAR vk_type;  // Virtual key.
  162 typedef UINT mod_type;  // Standard Windows modifier type for storing MOD_CONTROL, MOD_WIN, MOD_ALT, MOD_SHIFT.
  163 
  164 // The maximum number of virtual keys and scan codes that can ever exist.
  165 // As of WinXP, these are absolute limits, except for scan codes for which there might conceivably
  166 // be more if any non-standard keyboard or keyboard drivers generate scan codes that don't start
  167 // with either 0x00 or 0xE0.  UPDATE: Decided to allow all possible scancodes, rather than just 512,
  168 // since a lookup array for the 16-bit scan code value will only consume 64K of RAM if the element
  169 // size is one char.  UPDATE: decided to go back to 512 scan codes, because WinAPI's KeyboardProc()
  170 // itself can only handle that many (a 9-bit value).  254 is the largest valid vk, according to the
  171 // WinAPI docs (I think 255 is value that is sometimes returned to indicate an invalid vk).  But
  172 // just in case something ever tries to access such arrays using the largest 8-bit value (255), add
  173 // 1 to make it 0xFF, thus ensuring array indexes will always be in-bounds if they are 8-bit values.
  174 #define VK_MAX 0xFF
  175 #define SC_MAX 0x1FF
  176 
  177 typedef UCHAR modLR_type; // Only the left-right win/alt/ctrl/shift rather than their generic counterparts.
  178 #define MODLR_MAX 0xFF
  179 #define MODLR_COUNT 8
  180 #define MOD_LCONTROL 0x01
  181 #define MOD_RCONTROL 0x02
  182 #define MOD_LALT 0x04
  183 #define MOD_RALT 0x08
  184 #define MOD_LSHIFT 0x10
  185 #define MOD_RSHIFT 0x20
  186 #define MOD_LWIN 0x40
  187 #define MOD_RWIN 0x80
  188 #define MODLR_STRING _T("<^>^<!>!<+>+<#>#")
  189 
  190 
  191 struct CachedLayoutType
  192 {
  193     HKL hkl;
  194     ResultType has_altgr;
  195 };
  196 
  197 struct key_to_vk_type // Map key names to virtual keys.
  198 {
  199     LPTSTR key_name;
  200     vk_type vk;
  201 };
  202 
  203 struct key_to_sc_type // Map key names to scan codes.
  204 {
  205     LPTSTR key_name;
  206     sc_type sc;
  207 };
  208 
  209 enum KeyStateTypes {KEYSTATE_LOGICAL, KEYSTATE_PHYSICAL, KEYSTATE_TOGGLE}; // For use with GetKeyJoyState(), etc.
  210 enum KeyEventTypes {KEYDOWN, KEYUP, KEYDOWNANDUP};
  211 
  212 void SendKeys(LPTSTR aKeys, SendRawModes aSendRaw, SendModes aSendModeOrig, HWND aTargetWindow = NULL);
  213 void SendKey(vk_type aVK, sc_type aSC, modLR_type aModifiersLR, modLR_type aModifiersLRPersistent
  214     , int aRepeatCount, KeyEventTypes aEventType, modLR_type aKeyAsModifiersLR, HWND aTargetWindow
  215     , int aX = COORD_UNSPECIFIED, int aY = COORD_UNSPECIFIED, bool aMoveOffset = false);
  216 void SendKeySpecial(TCHAR aChar, int aRepeatCount, modLR_type aModifiersLR);
  217 void SendASC(LPCTSTR aAscii);
  218 
  219 struct PlaybackEvent
  220 {
  221     UINT message;
  222     union
  223     {
  224         struct
  225         {
  226             sc_type sc; // Placed above vk for possibly better member stacking/alignment.
  227             vk_type vk;
  228         };
  229         struct
  230         {
  231             // Screen coordinates, which can be negative.  SHORT vs. INT is used because the likelihood
  232             // have having a virtual display surface wider or taller than 32,767 seems too remote to
  233             // justify increasing the struct size, which would impact the stack space and dynamic memory
  234             // used by every script every time it uses the playback method to send keystrokes or clicks.
  235             // Note: WM_LBUTTONDOWN uses WORDs vs. SHORTs, but they're not really comparable because
  236             // journal playback/record both use screen coordinates but WM_LBUTTONDOWN et. al. use client
  237             // coordinates.
  238             SHORT x;
  239             SHORT y;
  240         };
  241         DWORD time_to_wait; // This member is present only when message==0; otherwise, a struct is present.
  242     };
  243 };
  244 LRESULT CALLBACK PlaybackProc(int aCode, WPARAM wParam, LPARAM lParam);
  245 //#define JOURNAL_RECORD_MODE  // Uncomment this line to debug/analyze via a crude journal record feature in place of SendPlay.
  246 #ifdef JOURNAL_RECORD_MODE
  247     LRESULT CALLBACK RecordProc(int aCode, WPARAM wParam, LPARAM lParam);
  248 #endif
  249 
  250 
  251 // Below uses a pseudo-random value.  It's best that this be constant so that if multiple instances
  252 // of the app are running, they will all ignore each other's keyboard & mouse events.  Also, a value
  253 // close to UINT_MAX might be a little better since it's might be less likely to be used as a pointer
  254 // value by any apps that send keybd events whose ExtraInfo is really a pointer value.
  255 #define KEY_IGNORE 0xFFC3D44F
  256 #define KEY_PHYS_IGNORE (KEY_IGNORE - 1)  // Same as above but marked as physical for other instances of the hook.
  257 #define KEY_IGNORE_ALL_EXCEPT_MODIFIER (KEY_IGNORE - 2)  // Non-physical and ignored only if it's not a modifier.
  258 // Same as KEY_IGNORE_ALL_EXCEPT_MODIFIER, but only ignored by Hotkeys & Hotstrings at InputLevel LEVEL and below.
  259 // The levels are set up to use negative offsets from KEY_IGNORE_ALL_EXCEPT_MODIFIER so that we can leave
  260 // the values above unchanged and have KEY_IGNORE_LEVEL(0) == KEY_IGNORE_ALL_EXCEPT_MODIFIER.
  261 //
  262 // In general, KEY_IGNORE_LEVEL(g->SendLevel) should be used for any input that's meant to be treated as "real",
  263 // as opposed to input generated for side effects (e.g., masking modifier keys to prevent default OS responses).
  264 // A lot of the calls that generate input fall into the latter category, so KEY_IGNORE_ALL_EXCEPT_MODIFIER
  265 // (aka KEY_IGNORE_LEVEL(0)) still gets used quite often.
  266 //
  267 // Note that there are no "level" equivalents for KEY_IGNORE or KEY_PHYS_IGNORE (only KEY_IGNORE_ALL_EXCEPT_MODIFIER).
  268 // For the KEY_IGNORE_LEVEL use cases, there isn't a need to ignore modifiers or differentiate between physical
  269 // and non-physical, and leaving them out keeps the code much simpler.
  270 #define KEY_IGNORE_LEVEL(LEVEL) (KEY_IGNORE_ALL_EXCEPT_MODIFIER - LEVEL)
  271 #define KEY_IGNORE_MIN KEY_IGNORE_LEVEL(SendLevelMax)
  272 #define KEY_IGNORE_MAX KEY_IGNORE // There are two extra values above KEY_IGNORE_LEVEL(0)
  273 // This is used to generate an Alt key-up event for the purpose of changing system state, but having the hook
  274 // block it from the active window to avoid unwanted side-effects:
  275 #define KEY_BLOCK_THIS (KEY_IGNORE + 1)
  276 
  277 
  278 // The default in the below is KEY_IGNORE_ALL_EXCEPT_MODIFIER, which causes standard calls to
  279 // KeyEvent() to update g_modifiersLR_logical_non_ignored the same way it updates g_modifiersLR_logical.
  280 // This is done because only the Send command has a realistic chance of interfering with (or being
  281 // interfered with by) hook hotkeys (namely the modifiers used to decide whether to trigger them).
  282 // There are two types of problems:
  283 // 1) Hotkeys not firing due to Send having temporarily released one of that hotkey's modifiers that
  284 //    the user is still holding down.  This causes the hotkey's suffix to flow through to the system,
  285 //    which is usually undesirable.  This happens when the user is holding down a hotkey to auto-repeat
  286 //    it, and perhaps other times.
  287 // 2) The wrong hotkey firing because Send has temporarily put a modifier into effect and (once again)
  288 //    the user is holding down the hotkey to auto-repeat it.  If the Send's temp-down modifier happens
  289 //    to make the hotkey suffix match a different set of modifiers, the wrong hotkey would fire.
  290 void KeyEvent(KeyEventTypes aEventType, vk_type aVK, sc_type aSC = 0, HWND aTargetWindow = NULL
  291     , bool aDoKeyDelay = false, DWORD aExtraInfo = KEY_IGNORE_ALL_EXCEPT_MODIFIER);
  292 void KeyEventMenuMask(KeyEventTypes aEventType, DWORD aExtraInfo = KEY_IGNORE_ALL_EXCEPT_MODIFIER);
  293 
  294 ResultType PerformClick(LPTSTR aOptions);
  295 void ParseClickOptions(LPTSTR aOptions, int &aX, int &aY, vk_type &aVK, KeyEventTypes &aEventType
  296     , int &aRepeatCount, bool &aMoveOffset);
  297 ResultType PerformMouse(ActionTypeType aActionType, LPTSTR aButton, LPTSTR aX1, LPTSTR aY1, LPTSTR aX2, LPTSTR aY2
  298     , LPTSTR aSpeed, LPTSTR aOffsetMode, LPTSTR aRepeatCount = _T(""), LPTSTR aDownUp = _T(""));
  299 void PerformMouseCommon(ActionTypeType aActionType, vk_type aVK, int aX1, int aY1, int aX2, int aY2
  300     , int aRepeatCount, KeyEventTypes aEventType, int aSpeed, bool aMoveOffset);
  301 
  302 void MouseClickDrag(vk_type aVK // Which button.
  303     , int aX1, int aY1, int aX2, int aY2, int aSpeed, bool aMoveOffset);
  304 void MouseClick(vk_type aVK // Which button.
  305     , int aX, int aY, int aRepeatCount, int aSpeed, KeyEventTypes aEventType, bool aMoveOffset = false);
  306 void MouseMove(int &aX, int &aY, DWORD &aEventFlags, int aSpeed, bool aMoveOffset);
  307 void MouseEvent(DWORD aEventFlags, DWORD aData, DWORD aX = COORD_UNSPECIFIED, DWORD aY = COORD_UNSPECIFIED);
  308 
  309 #define MSG_OFFSET_MOUSE_MOVE 0x80000000  // Bitwise flag, should be near/at high-order bit to avoid overlap messages.
  310 void PutKeybdEventIntoArray(modLR_type aKeyAsModifiersLR, vk_type aVK, sc_type aSC, DWORD aEventFlags, DWORD aExtraInfo);
  311 void PutMouseEventIntoArray(DWORD aEventFlags, DWORD aData, DWORD aX, DWORD aY);
  312 ResultType ExpandEventArray();
  313 void InitEventArray(void *aMem, UINT aMaxEvents, modLR_type aModifiersLR);
  314 void SendEventArray(int &aFinalKeyDelay, modLR_type aModsDuringSend);
  315 void CleanupEventArray(int aFinalKeyDelay);
  316 
  317 extern SendModes sSendMode;
  318 void DoKeyDelay(int aDelay = (sSendMode == SM_PLAY) ? g->KeyDelayPlay : g->KeyDelay);
  319 void DoMouseDelay();
  320 void UpdateKeyEventHistory(bool aKeyUp, vk_type aVK, sc_type aSC);
  321 #define KEYEVENT_PHYS(event_type, vk, sc) KeyEvent(event_type, vk, sc, NULL, false, KEY_PHYS_IGNORE)
  322 
  323 ToggleValueType ToggleKeyState(vk_type aVK, ToggleValueType aToggleValue);
  324 
  325 #define STD_MODS_TO_DISGUISE (MOD_LALT|MOD_RALT|MOD_LWIN|MOD_RWIN)
  326 void SetModifierLRState(modLR_type aModifiersLRnew, modLR_type aModifiersLRnow, HWND aTargetWindow
  327     , bool aDisguiseDownWinAlt, bool aDisguiseUpWinAlt, DWORD aExtraInfo = KEY_IGNORE_ALL_EXCEPT_MODIFIER);
  328 modLR_type GetModifierLRState(bool aExplicitlyGet = false);
  329 
  330 #define IsKeyDown(vk) (GetKeyState(vk) & 0x8000)
  331 #define IsKeyDownAsync(vk) (GetAsyncKeyState(vk) & 0x8000)
  332 #define IsKeyToggledOn(vk) (GetKeyState(vk) & 0x01)
  333 
  334 void AdjustKeyState(BYTE aKeyState[], modLR_type aModifiersLR);
  335 modLR_type KeyToModifiersLR(vk_type aVK, sc_type aSC = 0, bool *pIsNeutral = NULL);
  336 modLR_type ConvertModifiers(mod_type aModifiers);
  337 mod_type ConvertModifiersLR(modLR_type aModifiersLR);
  338 LPTSTR ModifiersLRToText(modLR_type aModifiersLR, LPTSTR aBuf);
  339 
  340 DWORD GetFocusedCtrlThread(HWND *apControl = NULL, HWND aWindow = GetForegroundWindow());
  341 HKL GetFocusedKeybdLayout(HWND aWindow = GetForegroundWindow());
  342 
  343 #define LAYOUT_UNDETERMINED FAIL
  344 bool ActiveWindowLayoutHasAltGr();
  345 ResultType LayoutHasAltGr(HKL aLayout, ResultType aHasAltGr = LAYOUT_UNDETERMINED);
  346 
  347 //---------------------------------------------------------------------
  348 
  349 LPTSTR SCtoKeyName(sc_type aSC, LPTSTR aBuf, int aBufSize, bool aUseFallback = true);
  350 LPTSTR VKtoKeyName(vk_type aVK, LPTSTR aBuf, int aBufSize, bool aUseFallback = true);
  351 TCHAR VKtoChar(vk_type aVK, HKL aKeybdLayout = NULL);
  352 sc_type TextToSC(LPTSTR aText, bool *aSpecifiedByNumber = NULL);
  353 vk_type TextToVK(LPTSTR aText, modLR_type *pModifiersLR = NULL, bool aExcludeThoseHandledByScanCode = false
  354     , bool aAllowExplicitVK = true, HKL aKeybdLayout = GetKeyboardLayout(0));
  355 vk_type CharToVKAndModifiers(TCHAR aChar, modLR_type *pModifiersLR, HKL aKeybdLayout, bool aEnableAZFallback = true);
  356 bool TextToVKandSC(LPTSTR aText, vk_type &aVK, sc_type &aSC, modLR_type *pModifiersLR = NULL, HKL aKeybdLayout = GetKeyboardLayout(0));
  357 vk_type TextToSpecial(LPTSTR aText, size_t aTextLength, KeyEventTypes &aEventTypem, modLR_type &aModifiersLR
  358     , bool aUpdatePersistent);
  359 
  360 #ifdef ENABLE_KEY_HISTORY_FILE
  361 ResultType KeyHistoryToFile(LPTSTR aFilespec = NULL, TCHAR aType = '\0', bool aKeyUp = false
  362     , vk_type aVK = 0, sc_type aSC = 0);
  363 #endif
  364 
  365 LPTSTR GetKeyName(vk_type aVK, sc_type aSC, LPTSTR aBuf, int aBufSize, LPTSTR aDefault = _T("not found"));
  366 sc_type vk_to_sc(vk_type aVK, bool aReturnSecondary = false);
  367 vk_type sc_to_vk(sc_type aSC);
  368 
  369 inline bool IsMouseVK(vk_type aVK)
  370 {
  371     return aVK >= VK_LBUTTON && aVK <= VK_XBUTTON2 && aVK != VK_CANCEL
  372         || aVK >= VK_NEW_MOUSE_FIRST && aVK <= VK_NEW_MOUSE_LAST;
  373 }
  374 
  375 #endif