Take the 2-minute tour ×

I am working on my keystroke logger for personal interest and asked a question related to this about yesterday; While loop using a lot of CPU.

The issue with the program was that it took too much CPU Usage, and people have suggested to make the inputs key-event based.

Since I'm new to the Win32 API, I try to look for references and tutorials that will tell me how to create keyboard inputs as event-based, rather than poll based. But the problems is I could not found any solid examples or references, as it was quite difficult to understand for a complete newbie.

Most of them mentioned that the event-based programming resided in GUI application, yet I want this keystroke logger application to be a console application.

My two main questions from all this is:

  • Can I write a event-based console keystroke logger with the Win32 API? If not, what are my options?


  • Does anyone have any reference websites that will help me understand how to capture keystrokes event-based?

If additional information is needed, I am using Code Blocks under Windows XP with a GCC compiler.

share|improve this question

2 Answers 2

Key logger applications use mechanisms such as Win32 Hooks. Specifically you need to set a WH_KEYBOARD hook.

There are move advanced techniques, like creating your own keyboard driver but for a start hooks are a good choice.

Edit: To get an idea of how a hook procedure looks like, I post a fragment from my personal utility.

// ...
thehook = SetWindowsHookEx( WH_KEYBOARD_LL, hook_proc, hwnd, 0 );
// ...

    lParam: pointer to a KBDLLHOOKSTRUCT structure

    (*) "The hook procedure should process a message in less time than the
    HKEY_CURRENT_USER\Control Panel\Desktop 

    The value is in milliseconds. If the hook procedure does not 
    return during this interval, the system will pass the message to the next hook."

hook_proc( int code, WPARAM wParam, LPARAM lParam )
  static long ctrl_cnt = 0;
  static bool mmode = false;
  static DWORD time;


  if (  code < 0
  ||   (kbd->flags & 0x10) // ignore injected events
     ) return CallNextHookEx( thehook, code, wParam, lParam );

  long ret = 1; // by default I swallow the keys
  if (  mmode  ) { // macro mode is ON
    if (  WM_KEYDOWN == wParam  )
      PostMessage(mainwnd, WM_MCR_ACCUM, kbd->vkCode, 0);

    if (  WM_KEYUP == wParam  )
      switch (kbd->vkCode) {
        case VK_ESCAPE:
          mmode = false;
          PostMessage(mainwnd, WM_MCR_HIDE, 0, 0);

        case VK_RETURN:
          PostMessage(mainwnd, WM_MCR_EXEC, 0, 0);

        case VK_LCONTROL:
          mmode = false;
          PostMessage(mainwnd, WM_MCR_HIDE, 0, 0);
          PostMessage(mainwnd, WM_MCR_EXEC, 0, 0);

    /* Which non printable keys allow passing? */
    switch( kbd->vkCode ) {
      case VK_LCONTROL:
      case VK_CAPITAL:
      case VK_LSHIFT:
      case VK_RSHIFT:
        ret = CallNextHookEx( thehook, code, wParam, lParam );
  else { // macro mode is OFF
    /* Ctrl pressed */
    if (  kbd->vkCode == VK_LCONTROL && WM_KEYDOWN == wParam  ) {
      ctrl_cnt = 1;
      time = kbd->time;

    /* Prevent ctrl combinations to activate macro mode */
    if (  kbd->vkCode != VK_LCONTROL  )
      ctrl_cnt = 0;

    /* Ctrl released */
    if (  ctrl_cnt == 1 && WM_KEYUP == wParam  ) {
      if (  kbd->time - time > 40  ) {
        mmode = true;
        PostMessage(mainwnd, WM_MCR_SHOW, 0, 0);

    ret = CallNextHookEx( thehook, code, wParam, lParam ); // let it pass

  return ret;
share|improve this answer
How do you get the HINSTANCE of a different program? –  Matouš Vrba Mar 26 at 19:55
@MatoušVrba, you don't need to get handles of other programs. –  Nick Dandoulakis Mar 26 at 20:12
Yeah, now I get it, thanks! –  Matouš Vrba Mar 26 at 20:57

Take a look at the SetWindowsHookEx API.

You can do this is a console app as well as a windowed app. You will need to put your keyboard hook in a DLL so that you can capture keystrokes in processes other than your own.

There is some sample code here.

share|improve this answer
Just curious, what does a hook exactly do? I've read that it inject itself to another program, or it could be my understand. Also, would this reduce the amount of CPU Usage that the keystroke logger? –  CuriousUser Sep 17 '09 at 7:19
A hook adds a callback to your function when a selected event occurs. You would not need a loop constantly polling the keyboard. You code executes only when necessary. –  Ferruccio Sep 17 '09 at 7:31
See also this discussion stackoverflow.com/questions/3134183/… (I believe an exe can work for *_LL messages but a dll is required for anything else). –  rogerdpack Sep 10 '13 at 20:05

Your Answer

