[转]Windows钩子

//ke
// from a DLL simpler. All files within this DLL are compiled with the KEYHOOKLIB_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// KEYHOOKLIB_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
#ifdef KEYHOOKLIB_EXPORTS
#define KEYHOOKLIB_API __declspec(dllexport)
#else
#define KEYHOOKLIB_API __declspec(dllimport)
#endif
// 自定义与主程序通信的消息
#define HM_KEY WM_USER+1
// 声明要导出的函数
BOOL KEYHOOKLIB_API WINAPI SetKeyHook(BOOL bInstall,
DWORD dwThreadId = 0,
HWND hWndCaller = NULL
);
// KeyHookLib.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "KeyHookLib.h"
// 共享数据段
#pragma data_seg("YCIShared")
HWND g_hWndCaller = NULL;
HHOOK g_hHook = NULL;
#pragma data_seg()
LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam);


// 一个通过内存地址取得模块句柄的帮助函数。
HMODULE WINAPI ModuleFromAddress(PVOID pv)
{
MEMORY_BASIC_INFORMATION mbi;
if(VirtualQuery(pv,&mbi,sizeof(mbi)) != 0)
{
return (HMODULE)mbi.AllocationBase;
}else
{
return NULL;
}
}

// 安装钩子,卸载钩子的函数
BOOL WINAPI SetKeyHook(
BOOL bInstall, // 安装还是卸载已安装的钩子
DWORD dwThreadId, // 目标线程的ID
HWND hWndCaller) // 指定主窗口的句柄,钩子函数会向这个窗口发送通知信息。
{
BOOL bOk;
g_hWndCaller = hWndCaller;
if(bInstall)
{
g_hHook = SetWindowsHookEx(
WH_KEYBOARD,
KeyHookProc,
ModuleFromAddress(KeyHookProc),
dwThreadId);
bOk = (g_hHook != NULL);
}
else
{
bOk = UnhookWindowsHookEx(g_hHook);
g_hHook = NULL;
}
return bOk;
}
// 键盘钩子函数
LRESULT CALLBACK KeyHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode<0 || nCode == HC_NOREMOVE )
return CallNextHookEx(g_hHook,nCode,wParam,lParam);
if(lParam & 0x40000000) // 消息重复就交给下一个HOOK链
return CallNextHookEx(g_hHook,nCode,wParam,lParam);
// 通知主窗口。wParam参数为虚拟键码,lParam包含了此键的信息
::PostMessage(g_hWndCaller,HM_KEY,wParam,lParam);
return CallNextHookEx(g_hHook,nCode,wParam,lParam);
}
// keyhooklib.def
EXPORTS
SetKeyHook
SECTIONS
YCIShared Read Write Shared2.应用
以对话框为基础建立工程(keyhookapp),改动的文件如下:
// KeyHookAppDlg.cpp : implementation file
//
#include "stdafx.h"
#include "KeyHookApp.h"
#include "KeyHookAppDlg.h"
#include "KeyHookLib.h"
#pragma comment(lib,"KeyHookLib")
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CKeyHookAppDlg dialog
CKeyHookAppDlg::CKeyHookAppDlg(CWnd* pParent /*=NULL*/)
: CDialog(CKeyHookAppDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CKeyHookAppDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CKeyHookAppDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CKeyHookAppDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CKeyHookAppDlg, CDialog)
//{{AFX_MSG_MAP(CKeyHookAppDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(HM_KEY,OnHookKey)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CKeyHookAppDlg message handlers
BOOL CKeyHookAppDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
// 安装钩子
if(!SetKeyHook(TRUE,0,m_hWnd))
MessageBox("安装钩子失败");
return TRUE; // return TRUE unless you set the focus to a control
}
void CKeyHookAppDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CKeyHookAppDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CKeyHookAppDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CKeyHookAppDlg::OnCancel()
{
// TODO: Add extra cleanup here
// 卸载钩子
SetKeyHook(FALSE);
CDialog::OnCancel();
}
void CKeyHookAppDlg::OnOK()
{
// TODO: Add extra validation here
// 卸载钩子
SetKeyHook(FALSE);
CDialog::OnOK();
}
// 钩子消息处理函数
long CKeyHookAppDlg::OnHookKey(WPARAM wParam,LPARAM lParam)
{
// 此时wParam为用户按键的虚拟键码
// lParam包含按键的重复次数,扫描码,前一个按键状态等信息
// 取得按键名称。lParam是键盘消息的第二个参数
char szKey[80];
::GetKeyNameText(lParam,szKey,80);
CString strItem;
strItem.Format("用户按键:%s ",szKey);
// 添加到编辑框
CString strEdit;
GetDlgItem(IDC_KEY)->GetWindowText(strEdit);
GetDlgItem(IDC_KEY)->SetWindowText(strItem+strEdit);
::MessageBeep(MB_OK);
return 0;
}

3。运行结果
一个对话框,检测当前键盘的状态。若有按键按下,则在对话框的EDIT控件中显示按下键的名字。
[转]Windows钩子的更多相关文章
- 《windows核心编程系列》十八谈谈windows钩子
windows应用程序是基于消息驱动的.各种应用程序对各种消息作出响应从而实现各种功能. windows钩子是windows消息处理机制的一个监视点,通过安装钩子能够达到监视指定窗体某种类型的消息的功 ...
- windows钩子函数
一 什么时候用到钩子?(when)Windows操作系统是建立在事件驱动的消息处理机制之上,系统各部分之间的沟通也都是通过消息的相互传递而实现的.通常情况下,应用程序只能处理当前进程的消息,如果需要对 ...
- windows钩子(转)
1. 消息钩子 提示: 如果要设置系统级钩子, 钩子函数必须在 DLL 中. SetWindowsHookEx( idHook: Integer; {钩子类型} lpfn: TFNHookP ...
- windows钩子 Hook示例
1.首先编写一个 win32 dll工程. #include "stdafx.h" int WINAPI add(int a,int b) { return a+b; } BOOL ...
- Windows环境下32位汇编语言程序设计(典藏版)
Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)(年,经典再现!) 罗云彬 著 ISBN 978-7-121-20759-4 2013年7月出版 定价:99.00元 756页 1 ...
- Windows API 的数据类型与 Delphi 数据类型对照表
Windows 数据类型 Delphi 数据类型 描述 LPSTR PAnsiChar 字符串指针 LPCSTR PAnsiChar 字符串指针 DWORD LongWord 整数 BOOL Long ...
- 基于HOOK和MMF的Windows密码渗透技术
随着计算机与网络的普及,信息安全越来越成为人们所普遍关心的大事.密码的渗透与反渗透在此领域表现的愈演愈烈.本文深入分析了各个版本Windows密码的特点,尤其是针对windws2K/XP安全性提高的情 ...
- Windows Hook技术
0x01 简介 有人称它为“钩子”,有人称它为“挂钩”技术.谈到钩子,很容易让人联想到在钓东西,比如鱼钩就用于钓鱼.编程技术的钩子也是在等待捕获系统中的某个消息或者动作.钩子的应用范围非常广泛,比如输 ...
- Windows系统中监控文件复制操作的几种方式
http://blog.sina.com.cn/s/blog_4596beaa0100lp4y.html 1. ICopyHook 作用: 监视文件夹和打印机移动,删除, 重命名, 复制操作. 可以得 ...
随机推荐
- python3正则表达式指南
1.正则表达式基础 1.1 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强 ...
- thinkphp 闭包支持
闭包定义 我们可以使用闭包的方式定义一些特殊需求的路由,而不需要执行控制器的操作方法了,例如: 'URL_ROUTE_RULES'=>array( 'test' => function() ...
- elasticsearch+filebeat+kibana提取多行日志
filebeat的配置文件filebeat.yml以下三行去掉注释 multiline.pattern: ^\[ multiline.negate: true //false改为true multil ...
- webstorm 初次上传代码到 远程gitlab中
1. 在 公司搭建的gitlab网站,创建project,然后生成了 git的地址. 2.在 本地电脑上,打开 webstorm,要将已有的代码上传到 git网站,那么需要在webstrom编辑器的t ...
- python基于SMTP发送邮件
import smtplib from email.header import Header from email.mime.text import MIMEText ''' SMTP是发送邮件的协议 ...
- scrapy - 给scrapy 的spider 传值
scrapy - 给scrapy 的spider 传值 方法一: 在命令行用crawl控制spider爬取的时候,加上-a选项,例如: scrapy crawl myspider -a categor ...
- 16.ajax_case06
# 抓取华尔街见闻实时快讯 # https://wallstreetcn.com/live/global?from=navbar import requests import json header ...
- MATLAB 去掉数组里面不要的元素
trainfinger=1 testingfinger=(1:8); testingfinger = testingfinger(~ismember(testingfinger,trainfinger ...
- Array.prototype.splice()
splice() 方法通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组形式返回被修改的内容.此方法会改变原数组. 在1位置上添加一项 我们没有下标为4的项,这个超了,就在最大项后面添加这 ...
- Stopwatch 计时器类
C#_Stopwatch 类 命名空间:System.Diagnostics Stopwatch 实例可以测量一个时间间隔的运行时间,也可以测量多个时间间隔的总运行时间.在典型的 Stopwatc ...