Home c++ Alternative _KBHIT (), _Getch () and GetKeyState (). Windows Keyboard. C++

Alternative _KBHIT (), _Getch () and GetKeyState (). Windows Keyboard. C++

Author

Date

Category

I work with the keyboard so (_kbhit () , _Getch () ):

while (true) // Cycle driving hard processor
{// ^.
  if (_kbhit ()) // this call is not blocking
  {
    char ch = tolower (_Getch ());
    Switch (CH)
    {
      Case 'R':
        // ...
        Break;
      Default:
        // ...
        Break;
    }
  }
}

or so (getkeystate () ):

void keyanaliz ()
{
  enum
  {
    e_firstindex = 0,
    E_SIZE = 255,
    E_LASTINDEX = E_FIRSTIDEX + E_SIZE,
  };
  BOOL PREVCHECKEDKEYS [E_SIZE];
  Memset (PrevCheckedKeys, True, E_SIZE);
  BOOL CHECKEDKEYS [E_SIZE];
  Memset (CheckedKeys, False, E_SIZE);
  While (ISPlay)
  {
    for (int i = 0; i & lt; e_size; ++ i)
    {
      int b = i + e_firstindex;
      Char CH = CHAR (B);
      Const Short Keystate = GetKeyState (B);
      BOOL ISCECKED = KEYSTATE & AMP; 0001;
      CheckedKEYS [i] = ischecked;
      IF (PrevCheckedKeys [i]! = CheckedKeys [i])
      {
        COUT & LT; & LT; ch;
        PrevCheckedKEYS [i] = CheckedKeys [i];
      }
    }
  }
}

But both ways do not suit me, as the processor is strongly loaded. I would like to process interrupts from the keyboard and call the Callback function.
On MSDN there is a huge section “Keyboard input , I just started studying it.

Which way to dig and where to look? Maybe someone hello examples of ready-made solutions.

Solution Options found using setWindowshooKEX () :

# define _win32_winnt 0x500
#Include & lt; Windows.h & gt;
#Include & lt; Tchar.h & gt;
Hhook g_hhook;
Handle G_HEVENT;
UINT G_UKEY = VK_CAPITAL;
Uint g_udisablekey = vk_lmenu;
Lresult Callback Keyboardhook (Int Ncode, WParam Wparam, LPARAM LPARAM)
{
  if (ncode == HC_ACTION)
  {
    Kbdllhookstruct * ks = (kbdllhookstruct *) lparam;
    If (ks- & gt; vkcode == g_ukey & amp; & amp;! (GetKeyState (G_udisableKey) & amp; 0x8000))
    {
      If (WParam == WM_KEYDOWN)
      {
        HWND HWND = GetForeGroundWindow ();
        AttachThreadInPut (getCurrentThreadid (), GetWindowthReadProcessID (HWND, NULL), TRUE);
        HWND HWND_THREAD = getFocus ();
        if (hwnd_thread)
          HWND = HWND_THREAD;
        if (hwnd)
          PostMessage (HWND, WM_INPUTLANGCHANGEREQUEST, 0, (LPARAM) HKL_NEXT);
      }
      Return 1;
    }
  }
  RETURN CallNEXTHOOKEX (G_HHHOK, NCODE, WPARAM, LPARAM);
}
Void Failed (Const Tchar * MSG)
{
  MessageBox (NULL, MSG, _T ("Error"), MB_OK | MB_ICONERROR);
  Exitprocess (1);
}
Void Callback Timercallback (HWND HWND, UINT UMSG, UINT_PTR IDEVENT, DWORD DWTIME)
{
  If (WaitForSingleObject (G_HEVENT, 0) == WAIT_OBJECT_0)
    PostQuitmessage (0);
}
Void CMDLineParse (Int Argc, WCHAR_T ** ARGV)
{
  argv = commandlinetoargvw (getcommandlinew (), & amp; argc);
  if (argv! = null & amp; & amp; argc & gt; = 2)
  {
    UINT UCMDKEY = _WTOI (ARGV [1]);
    if (UcmdKey & GT; = 0x01 & amp; & amp; ucmdkey & lt; = 0xfe)
      g_ukey = ucmdkey;
    if (argc & gt; = 3)
    {
      UINT UDISABLEKEY = _WTOI (ARGV [2]);
      if (udisableKey & gt; = 0x01 & amp; & amp; udisablekey & lt; = 0xfe)
        g_udisablekey = udisablekey;
    }
  }
  LocalFree (ARGV);
}
Void ApplicationisalreadYRunning ()
{
  g_hevent = CreateEvent (NULL, TRUE, FALSE, _T ("haalilswitch"));
  if (g_hevent == null)
    Failed (_T ("CreateEvent ()"));
  if (getLastterror () == error_already_exists)
  { 
failed (_T ("LSwitch is already running!"));
  }
}
void resolve (int argc, wchar_t ** argv)
{
  MSG msg;
  cmdLineParse (argc, argv);
  applicationIsAlreadyRunning ();
  if (SetTimer (NULL, 0, 500, TimerCallback) == 0) // Don't understand why this is needed?
    failed (_T ("SetTimer ()"));
  g_hHook = SetWindowsHookEx (WH_KEYBOARD_LL, KeyboardHook, GetModuleHandle (0), 0);
  if (! g_hHook)
    failed (_T ("SetWindowsHookEx ()"));
  while (GetMessage (& amp; msg, 0, 0, 0))
  {
    TranslateMessage (& amp; msg);
    DispatchMessage (& amp; msg);
  }
  UnhookWindowsHookEx (g_hHook);
  CloseHandle (g_hEvent);
  ExitProcess (0);
}

Few questions left:

  1. Why call the TimerCallback () function on a timer and what happens in it? The solution works fine without it.
  2. I don’t quite understand why using a bunch GetMessage () , TranslateMessage () , and DispatchMessage () . Can you recommend a good book on WinApi to figure it out?

Answer 1, authority 100%

Use SetWindowHookEx.
An example is here: https://github.com/MikalaiR/LSwitch/blob/master/ lswitch.c


Answer 2

# include & lt; cstdio & gt;
#include & lt; Windows.h & gt;
char getch ()
{
 static INPUT_RECORD cachedInputRecord;
 INPUT_RECORD r;
 if (cachedInputRecord.EventType == 1)
  {
  r = cachedInputRecord;
  if (cachedInputRecord.Event.KeyEvent.wRepeatCount == 0)
   cachedInputRecord.EventType = -1;
  else
   cachedInputRecord.Event.KeyEvent.wRepeatCount--;
  }
 else
 {
  DWORD n;
  while (true)
   {
   ReadConsoleInput (GetStdHandle (-10), & amp; r, 1, & amp; n);
   short keyCode = r.Event.KeyEvent.wVirtualKeyCode;
   if (! (r.EventType == 1 & amp; & amp; r.Event.KeyEvent.bKeyDown) & amp; & amp; keyCode! = 0x12) continue;
   char ch = r.Event.KeyEvent.uChar.AsciiChar;
   if (ch == 0 & amp; & amp; ((keyCode & gt; = 0x10 & amp; & amp; keyCode & lt; = 0x12) || keyCode == 0x14 || keyCode == 0x90 || keyCode == 0x91)) continue;
   if (r.Event.KeyEvent.wRepeatCount & gt; 1)
   {
    r.Event.KeyEvent.wRepeatCount--;
    cachedInputRecord = r;
   }
   break;
   }
  }
  return r.Event.KeyEvent.uChar.AsciiChar;
}
int main ()
{
 char ch = '';
 for (int q = 10; q; --q)
 {
  printf ("Press% d keys (previous was% c) \ n", q, ch);
  ch = getch ();
 }
 return 0;
}

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions