我用全局键盘钩子,想记录键盘动作保存在文件中,但是我的程序总是在窗口激活时才能正常工作、截获键盘,在窗口最小化时不可以工作,隐藏窗口也不可以工作。这是怎么回事啊?我的意思是编写一个能记录任何键盘动作的程序。请高手讲讲此类程序怎么编?
下面是我的源代码:
//Hook.h--动态链接库的头文件
#if !defined Hook_h
#define Hook_hHINSTANCE hInst;#pragma data_seg("hookdata")
HHOOK oldkeyhook=0;
#pragma data_seg()#pragma comment(linker,"/SECTION:hookdata,RWS")#define DllExport _declspec(dllexport)DllExport LRESULT CALLBACK KeyBoardProc(int nCode,WPARAM wParam, LPARAM lParam );
DllExport void InstallKeyBoardHook(int nCode);
DllExport void EndKeyBoardHook(void);#endif// Hook.cpp : Defines the entry point for the DLL application.#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "Hook.h"BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hInst = (HINSTANCE)hModule;
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break; }
return 1;
}void InstallKeyBoardHook(int nCode)
{
oldkeyhook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyBoardProc,hInst,0);
}DllExport LRESULT CALLBACK KeyBoardProc(int nCode,WPARAM wParam, LPARAM lParam )
{
WPARAM j;
FILE *fp;
if(nCode == HC_ACTION)
{
if(lParam&0x80000000) //记录在文件中
{
j = wParam;
fp=fopen("key.txt","a");
fprintf(fp,"%4d",j);
fclose(fp);
}
}
return CallNextHookEx(oldkeyhook,nCode,wParam,lParam);
}void EndKeyBoardHook(void)
{
UnhookWindowsHookEx(oldkeyhook);
}//Test.cpp--测试钩子的文件
#include "stdafx.h"
#include "Hook.h"HINSTANCE hInst; // current instance
TCHAR szTitle[] = "For WHY"; // The title bar text
TCHAR szWindowClass[] = "For WHY"; // The title bar text// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}// FUNCTION: MyRegisterClass()
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
}// FUNCTION: InitInstance(HANDLE, int)
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[] = "Hello!"; switch (message)
{
case WM_CREATE: //创建窗口式装入钩子
InstallKeyBoardHook(TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc,80,150,szHello, strlen(szHello));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
EndKeyBoardHook();//撤销钩子
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
下面是我的源代码:
//Hook.h--动态链接库的头文件
#if !defined Hook_h
#define Hook_hHINSTANCE hInst;#pragma data_seg("hookdata")
HHOOK oldkeyhook=0;
#pragma data_seg()#pragma comment(linker,"/SECTION:hookdata,RWS")#define DllExport _declspec(dllexport)DllExport LRESULT CALLBACK KeyBoardProc(int nCode,WPARAM wParam, LPARAM lParam );
DllExport void InstallKeyBoardHook(int nCode);
DllExport void EndKeyBoardHook(void);#endif// Hook.cpp : Defines the entry point for the DLL application.#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#include "Hook.h"BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hInst = (HINSTANCE)hModule;
break;
case DLL_PROCESS_DETACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break; }
return 1;
}void InstallKeyBoardHook(int nCode)
{
oldkeyhook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyBoardProc,hInst,0);
}DllExport LRESULT CALLBACK KeyBoardProc(int nCode,WPARAM wParam, LPARAM lParam )
{
WPARAM j;
FILE *fp;
if(nCode == HC_ACTION)
{
if(lParam&0x80000000) //记录在文件中
{
j = wParam;
fp=fopen("key.txt","a");
fprintf(fp,"%4d",j);
fclose(fp);
}
}
return CallNextHookEx(oldkeyhook,nCode,wParam,lParam);
}void EndKeyBoardHook(void)
{
UnhookWindowsHookEx(oldkeyhook);
}//Test.cpp--测试钩子的文件
#include "stdafx.h"
#include "Hook.h"HINSTANCE hInst; // current instance
TCHAR szTitle[] = "For WHY"; // The title bar text
TCHAR szWindowClass[] = "For WHY"; // The title bar text// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}// FUNCTION: MyRegisterClass()
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
}// FUNCTION: InitInstance(HANDLE, int)
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[] = "Hello!"; switch (message)
{
case WM_CREATE: //创建窗口式装入钩子
InstallKeyBoardHook(TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc,80,150,szHello, strlen(szHello));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
EndKeyBoardHook();//撤销钩子
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
if(lParam&0x80000000) //记录在文件中
{
j = wParam;
fp=fopen("key.txt","a");
fprintf(fp,"%4d",j);
fclose(fp);
kbhook.cpp
*/#define _WIN32_WINNT 0x400
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
DWORD g_main_tid = 0;
HHOOK g_kb_hook = 0;
BOOL CALLBACK con_handler (DWORD)
{
PostThreadMessage (g_main_tid, WM_QUIT, 0, 0);
return TRUE;
};
LRESULT CALLBACK kb_proc (int code, WPARAM w, LPARAM l)
{
PKBDLLHOOKSTRUCT p = (PKBDLLHOOKSTRUCT)l;
const char *info = NULL;
if (w == WM_KEYDOWN)
info = "key dn";
else if (w == WM_KEYUP)
info = "key up";
else if (w == WM_SYSKEYDOWN)
info = "sys key dn";
else if (w == WM_SYSKEYUP)
info = "sys key up";
printf ("%s - vkCode [%04x], scanCode [%04x]\n",
info, p->vkCode, p->scanCode);
// always call next hook
return CallNextHookEx (g_kb_hook, code, w, l);
};
int main (void)
{
g_main_tid = GetCurrentThreadId ();
SetConsoleCtrlHandler (&con_handler, TRUE);
g_kb_hook = SetWindowsHookEx (
WH_KEYBOARD_LL,
&kb_proc,
GetModuleHandle (NULL), // 不能为NULL,否则失败
0); if (g_kb_hook == NULL)
{
fprintf (stderr,
"SetWindowsHookEx failed with error %d\n",
::GetLastError ());
return 0;
};
// 消息循环是必须的,想知道原因可以查msdn
MSG msg;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
};
UnhookWindowsHookEx (g_kb_hook);
return 0;
};