一个键盘钩子程序(sdk实现)

改自“Delphi下深入Windows核心编程”56页HookKey程序。原来的Delphi代码使用DEMO控件来显示键盘输入,采用VC后改用多行编辑EDIT控件来显示。程序的思路是当DLL截获键盘消息后,向主程序发送一条自定义的消息,然后主程序将键盘输入显示在对话框中的编辑控件里。关键是采用共享节保存主程序的窗口句柄,并且在DLL中导出该句柄,这样主程序可以在初始化的时候给该句柄赋值,而DLL获得该句柄后,就可以向主程序窗口发送消息了;另外还有EDIT控件用作显示时,要设为只读属性,防止回显键盘输入;采用向该控件发送EM_REPLACESEL消息来连续显示字符。

代码虽然简单,但是我是在参考了WINDOWS核心编程和罗云彬WIN32汇编教程之后费了不少劲才实现了,汗。编程环境是VC2003,使用了JEFFREY大牛同志推荐的MESSAGE CRACKER宏。

Dll部分
//Key.h
//下列 ifdef 块是创建使从 DLL 导出更简单的
//宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 KEY_EXPORTS
// 符号编译的。在使用此 DLL 的
//任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// KEY_API 函数视为是从此 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef KEY_EXPORTS
#define KEY_API extern "C" __declspec(dllexport)
#else
#define KEY_API extern "C" __declspec(dllimport)
#endif
#define WM_HooKKEY (WM_USER+1000)

KEY_API void HookOn();
KEY_API void HookOff();
KEY_API HWND ViewInteger;

// Key.cpp : 定义 DLL 应用程序的入口点。
#include <windows.h>
#include "Key.h"
//#include <stdio.h>
//#define KEY_EXPORTS

// 定义共享数据段
#pragma data_seg("shared")
HWND ViewInteger= HWND(0); // 主程序句柄
#pragma data_seg()
#pragma comment(linker, "/section:shared,rws")

HHOOK HookDeTeclado = NULL; //钩子句柄
HINSTANCE hInstDLL = NULL; // DLL句柄
HWND hWndKey = NULL; // 主窗口句柄

// DLL主函数
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
  if (fdwReason == DLL_PROCESS_ATTACH)
    hInstDLL = hinstDLL;
  return TRUE;
}

// 钩子过程,监视键盘消息
LRESULT CALLBACK CallBackDelHook(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HC_ACTION)
        hWndKey = ViewInteger;
PostMessage(hWndKey,WM_HooKKEY,wParam,lParam);
return CallNextHookEx(HookDeTeclado,nCode,wParam,lParam);
}

//
void HookOn(void)
{
HookDeTeclado = SetWindowsHookEx(WH_KEYBOARD,CallBackDelHook,hInstDLL,0);
//return 0;
}

//
void HookOff(void)
{
UnhookWindowsHookEx(HookDeTeclado);
}

/
主程序部分

// stdafx.h : 标准系统包含文件的包含文件,
#pragma once
#define WIN32_LEAN_AND_MEAN // 从 Windows 头中排除极少使用的资料
// Windows 头文件:
#include <windows.h>
// C 运行时头文件
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

// TODO: 在此处引用程序要求的附加头文件a
#include <commctrl.h>
#include <windowsx.h>
#define chHANDLE_MSG(hwnd, message, fn)                 /
   case (message): return (SetDlgMsgResult(hwnd, msg,     /
      HANDLE_##message((hwnd), (wParam), (lParam), (fn))))
// This macro evaluates to the number of elements in an array.
#define chDIMOF(Array) (sizeof(Array) / sizeof(Array[0]))

// TestKeyHook.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "TestKeyHook.h"
#include <stdarg.h> //va_list
//#include <tchar.h>
#include <stdio.h> //_vstprintf
#include "Key/Key.h"
//#pragma comment(lib, "Key.lib")

//该函数改自Windows核心编程第四章
void AddText(HWND hwnd, PCTSTR pszFormat, ...) {
   va_list argList;
   va_start(argList, pszFormat);

   TCHAR sz[20 * 1024];
  // Edit_GetText(hwnd, sz, chDIMOF(sz));
  // _vstprintf(_tcschr(sz, 0), pszFormat, argList);
_vstprintf(sz, pszFormat, argList);
  // Edit_SetText(hwnd, sz);
SendMessage(hwnd, EM_REPLACESEL,0, (LPARAM)sz);  
  //SendMessage(hwnd, WM_VSCROLL,SB_BOTTOM, 0);
   va_end(argList);
}

// 此代码模块中包含的函数的前向声明:
BOOL CALLBACK Dlg_DlgProc(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,Dlg_DlgProc);
return 0;
}

//
//  Process WM_COMMAND message for window/dialog: Dlg
//
void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
// TODO: Add your message processing code here...
switch(id){
case IDCANCEL:
if(HookOff!=NULL)
HookOff();
EndDialog(hwnd,id);
break;
}

}

//
//  Process WM_INITDIALOG message for window/dialog: Dlg
//
BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
{
MessageBox(hwnd,"1",0,0);
// TODO: Add your message processing code here...
ViewInteger=hwnd;
HookOn();
return(TRUE);
}

void Dlg_HooKKEY(HWND hwnd,UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND hEdit=GetDlgItem(hwnd,IDC_EDIT1);
char KeyName[101];
  //  char* Accion;
GetKeyNameText(lParam,KeyName,100);
if((lParam >> 31)&&1==1)
   AddText(hEdit,"%s %s/r/n","Key up",KeyName);
else if ((lParam >> 30)&&1==1)
   AddText(hEdit,"%s %s/r/n","ReKeyDown",KeyName);
else
AddText(hEdit,"%s %s/r/n","KeyDown",KeyName);
//MessageBox(hwnd,Accion,0,0);
//Edit_SetText(GetDlgItem(hwnd,IDC_EDIT1),(LPSTR)Accion);

}
//
// Dlg  Dialog Procedure
//
BOOL CALLBACK Dlg_DlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
chHANDLE_MSG (hwndDlg, WM_INITDIALOG, Dlg_OnInitDialog);
        chHANDLE_MSG (hwndDlg, WM_COMMAND, Dlg_OnCommand);
TODO: Add dialog message crackers here...
case WM_HooKKEY:
Dlg_HooKKEY(hwndDlg,msg,wParam,lParam);


default: return FALSE;
}
}
///
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS

/
#undef APSTUDIO_READONLY_SYMBOLS

/
// 中文(中华人民共和国) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
#pragma code_page(936)
#endif //_WIN32

/
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_TESTKEYHOOK         ICON                    "TestKeyHook.ico"
IDI_SMALL               ICON                    "small.ico"

/
//
// Accelerator
//

IDC_TESTKEYHOOK ACCELERATORS
BEGIN
    "?",            IDM_ABOUT,              ASCII,  ALT
    "/",            IDM_ABOUT,              ASCII,  ALT
END


/
//
// Dialog
//

IDD_DIALOG1 DIALOGEX 0, 0, 267, 161
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_MINIMIZEBOX |
    WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    EDITTEXT        IDC_EDIT1,7,7,253,147,ES_MULTILINE | ES_READONLY |
                    WS_VSCROLL | NOT WS_TABSTOP
END


#ifdef APSTUDIO_INVOKED
/
//
// TEXTINCLUDE
//

1 TEXTINCLUDE
BEGIN
    "resource.h/0"
END

2 TEXTINCLUDE
BEGIN
    "#define APSTUDIO_HIDDEN_SYMBOLS/r/n"
    "#include ""windows.h""/r/n"
    "#undef APSTUDIO_HIDDEN_SYMBOLS/r/n"
    "/0"
END

3 TEXTINCLUDE
BEGIN
    "/r/n"
    "/0"
END

#endif    // APSTUDIO_INVOKED


/
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_DIALOG1, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 260
        TOPMARGIN, 7
        BOTTOMMARGIN, 154
    END
END
#endif    // APSTUDIO_INVOKED

#endif    // 中文(中华人民共和国) resources
/

#ifndef APSTUDIO_INVOKED
/
//
// Generated from the TEXTINCLUDE 3 resource.
//

/
#endif    // not APSTUDIO_INVOKED

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值