// 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 hook
BOOL 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 chain
return ::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 code
return 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 here
g_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;
}