c/c++

키보드 전역 후킹

Нуеоп 2011. 8. 29. 10:39


KeyHookApp.cpp

#include <windows.h>
#include <tchar.h>
/*
http://cboard.cprogramming.com/windows-programming/99678-setwindowshookex-wm_keyboard_ll.html
http://msdn.microsoft.com/en-us/library/ms644985(v=vs.85).aspx
*/
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hInst;
HWND hWndMain;
LPCTSTR lpszClass=_T("KeyHookApp");

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
   ,LPSTR lpszCmdParam,int nCmdShow)
{
 HWND hWnd;
 MSG Message;
 WNDCLASS WndClass;
 g_hInst=hInstance;
 
 WndClass.cbClsExtra=0;
 WndClass.cbWndExtra=0;
 WndClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
 WndClass.hCursor=LoadCursor(NULL,IDC_ARROW);
 WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
 WndClass.hInstance=hInstance;
 WndClass.lpfnWndProc=(WNDPROC)WndProc;
 WndClass.lpszClassName=lpszClass;
 WndClass.lpszMenuName=NULL;
 WndClass.style=CS_HREDRAW | CS_VREDRAW;
 RegisterClass(&WndClass);

 hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW,
  CW_USEDEFAULT,CW_USEDEFAULT,600,130,
  NULL,(HMENU)NULL,hInstance,NULL);
 ShowWindow(hWnd,nCmdShow);
 hWndMain=hWnd;
 
 while(GetMessage(&Message,0,0,0)) {
  TranslateMessage(&Message);
  DispatchMessage(&Message);
 }
 return (int)Message.wParam;
}

extern "C" __declspec(dllimport) void InstallHook(HWND hWnd);
extern "C" __declspec(dllimport) void UninstallHook();

typedef void (* INSTALL_HOOK)(HWND);
typedef void (* UNINSTALL_HOOK)(void);
INSTALL_HOOK installHook;
UNINSTALL_HOOK uninstallHook;

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
 HDC hdc;
 PAINTSTRUCT ps;

 static HINSTANCE hinstDLL = NULL;
 static TCHAR msg1[128];
 static TCHAR msg2[128];
 static TCHAR msg3[128];
 KBDLLHOOKSTRUCT *kb;

 switch(iMessage) {
 case WM_CREATE:
  hinstDLL=LoadLibrary(_T("..\\Release\\KeyHookDll.dll"));
  installHook=(INSTALL_HOOK)GetProcAddress(hinstDLL,"InstallHook");
  uninstallHook=(UNINSTALL_HOOK)GetProcAddress(hinstDLL,"UninstallHook");
  _stprintf_s(msg1,128,_T("hinstDLL:%d, installHook:%p, uninstallHook:%p"),hinstDLL,installHook,uninstallHook);
  installHook(hWnd);
  return 0;
 case WM_USER+1:
   kb =( KBDLLHOOKSTRUCT*)lParam;

  BYTE kb_state[256];
  _stprintf_s(msg3,128,_T("vkCode : %c(%d), scanCode : %d"),kb->vkCode,kb->vkCode, kb->scanCode);
 
  TCHAR key_state[64];
 switch(wParam){
 case WM_KEYDOWN:
  _stprintf_s(key_state,64,_T("%s"),_T("WM_KEYDOWN"));break;
 case WM_KEYUP:
  _stprintf_s(key_state,64,_T("%s"),_T("WM_KEYUP"));break;
 case WM_SYSKEYDOWN:
  _stprintf_s(key_state,64,_T("%s"),_T("WM_SYSKEYDOWN"));break;
 case WM_SYSKEYUP:
  _stprintf_s(key_state,64,_T("%s"),_T("WM_SYSKEYUP"));break;
 default: _stprintf_s(key_state,64,_T("%s"),_T("Unexpected KeyState"));
 }
  _stprintf_s(msg2,128,_T("Key Message : %s, lParam : %x "),key_state,lParam);
  InvalidateRect(hWnd,NULL,TRUE);
  return 0;
 case WM_PAINT:
  hdc=BeginPaint(hWnd, &ps);
  TextOut(hdc,10,10,msg1,lstrlen(msg1));
  TextOut(hdc,10,30,msg2,lstrlen(msg2));
  TextOut(hdc,10,50,msg3,lstrlen(msg3));
  EndPaint(hWnd, &ps);
  return 0;
 case WM_DESTROY:
  uninstallHook();
  FreeLibrary(hinstDLL);
  PostQuitMessage(0);
  return 0;
 }
 return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}





KeyHookDll.cpp

#include "stdafx.h"

HINSTANCE gModule=NULL;
HHOOK hKeyHook=NULL;
HWND gHwnd=NULL;

LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
 if (nCode>=0) {
  SendMessage(gHwnd,WM_USER+1,wParam,lParam);
 }
 return CallNextHookEx(hKeyHook,nCode,wParam,lParam);
}

extern "C" __declspec(dllexport) void InstallHook(HWND hWnd)
{
 gHwnd=hWnd;
 hKeyHook=SetWindowsHookEx(WH_KEYBOARD_LL,KeyHookProc,gModule,NULL);
}

extern "C" __declspec(dllexport) void UninstallHook()
{
 UnhookWindowsHookEx(hKeyHook);
}




dllmain.cpp

#include "stdafx.h"

extern HINSTANCE gModule;

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
 switch (ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:
  gModule = hModule;
  break;
 case DLL_THREAD_ATTACH:
 case DLL_THREAD_DETACH:
 case DLL_PROCESS_DETACH:
  break;
 }
 return TRUE;
}