// Test_Hook.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <WinError.h>// Some global variables
HINSTANCE g_Instance; // Handler of current instance
HHOOK g_Hook; // Handler of hookBOOL SetHook();
BOOL UnSetHook();// The hook function (will be called by other processes)
static LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);//
//odprintf -- debug function
void __cdecl odprintf(const char* fmt, ...)
{char buf[4096], *p = buf;va_list args;va_start(args, fmt);p += vsnprintf_s(p, sizeof(buf), _TRUNCATE, fmt, args);va_end(args);while ( p > buf && isspace(p[-1]) )*--p = '\0';*p++ = '\r';*p++ = '\n';*p = '\0';OutputDebugStringA(buf); //output as ANSI string //OutputDebugString
}LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{KBDLLHOOKSTRUCT* pkh = (KBDLLHOOKSTRUCT*)lParam;//HC_ACTION: wParam 和lParam参数包含了键盘按键消息if (nCode == HC_ACTION) {if (::GetAsyncKeyState('1') & 0x8000){odprintf("111111111111111111");}//判断函数调用时指定虚拟键的状态//BOOL bCtrlKey = ::GetAsyncKeyState(VK_CONTROL) & 0x8000;BOOL bCtrlKey = ::GetAsyncKeyState(VK_CONTROL)>>((sizeof(SHORT) * 8) - 1);if ((pkh->vkCode == VK_ESCAPE && bCtrlKey) || // Ctrl+Esc 开始菜单(pkh->vkCode == VK_TAB && pkh->flags & LLKHF_ALTDOWN) || // Alt+TAB 屏幕切换菜单(pkh->vkCode == VK_ESCAPE && pkh->flags & LLKHF_ALTDOWN) || // Alt+Esc 屏幕切换 (pkh->vkCode == VK_LWIN || pkh->vkCode==VK_RWIN) // 左右Windows键) { odprintf("ok...i'am come here!"); //这里会出现两次, 因为return 1; }}// Call next hook in chainreturn ::CallNextHookEx(g_Hook, nCode, wParam, lParam);
}BOOL SetHook()
{if (g_Instance || g_Hook) // Already hooked!return TRUE;g_Instance = (HINSTANCE)::GetModuleHandle(NULL);g_Hook = ::SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyboardProc, g_Instance, 0);if (!g_Hook){odprintf("SetHook error, error code=%ld", ::GetLastError()); //error codereturn FALSE;}return TRUE; // Hook has been created correctly
}BOOL UnSetHook()
{if (g_Hook) { // Check if hook handler is valid::UnhookWindowsHookEx(g_Hook); // Unhook is done hereg_Hook = NULL; // Remove hook handler to avoid to use it again}return TRUE; // Hook has been removed
}int _tmain(int argc, _TCHAR* argv[])
{odprintf("Test of KeyboardProc, starting...");if (!SetHook())return -1;MSG msg;while(::GetMessage(&msg, NULL, 0, 0) > 0){TranslateMessage(&msg);DispatchMessage(&msg);}//clean:UnSetHook();return 0;
}