[转]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 作用: 监视文件夹和打印机移动,删除, 重命名, 复制操作. 可以得 ...
随机推荐
- ReentrantLock与synchronized的区别
1.与synchronized相比,ReentrantLock提供了更多,更加全面的功能,具备更强的扩展性.例如:时间锁等候,可中断锁等候,锁投票. 2.ReentrantLock还提供了条件Cond ...
- Last_SQL_Error: Error 'Can't drop database
此文办法只用应急, 别的办法我还没想到, 文章是Copy来的 MySQL主从同步报错排错结果及修复过程之:Slave_SQL_Running: No 起因调查: 收到大量邮件报警想必事出有因,就问同 ...
- [JZOJ3362] 【NOI2013模拟】数数
题目 题目大意 求区间\([A,B]\)有多少个数是"完美的". 一个数是"完美的",当且仅当这个数的各位能分成两个集合,使得两个集合中数字的和相等. \(B\ ...
- 阿里第一颗芯片问世,平头哥发布最强AI芯片含光800
阿里巴巴第一颗自研芯片正式问世.9月25日的杭州云栖大会上,达摩院院长张建锋现场展示了这款全球最强的AI芯片——含光800.在业界标准的ResNet-50测试中,含光800推理性能达到78563 IP ...
- 基于标记的分水岭分割算法/OpenCV中距离变换
Opencv分水岭算法——watershed自动图像分割用法 OpenCV距离变换distanceTransform应用 图像分割作为图像识别的基础,在图像处理中占有重要地位,通常需要在进行图像分割算 ...
- C++——虚继承(不要使用,会导致二义性)
如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性 总结: 如果一个派生类从多个基类派生,而这些基类又有一个共同 的基类,则在对该基类中声明 ...
- 在.net core上,Web网站调用微信支付-统一下单接口(xml传参)一直返回错误:mch_id参数格式错误
这是 微信支付-统一下单 接口文档 一.问题描述 在调用统一下单接口时,报mch_id参数格式错误,但商户ID确实是10位数字正确的,可就是一直报这个错误 返回的错误xml如下: 二.排错过程 1.多 ...
- IO初步,字节输入流和字节输出流
字节输出流 OutputStream(基类,抽象) 特点:写任意的文件 方法:写出数据的方法:write write(int b) 写出1个字节 -128~127之间,写的是一个ASCLL码的值 wr ...
- 第二十篇:记下第一个mysql触发器
项目背景:给一个服务限制访问次数,当用户访问这个服务的次数达到这个值的时候,关闭他的访问权限首先访问信息存在一张表中,记录用户的ip:visitor_ip,服务的id:service_id,访问次数: ...
- mui 上拉加载 实现分页加载功能
mui 上拉加载 实现分页加载功能,效果图: 分页功能(上拉加载): 1.引入需要的css.js文件 <link href="static/css/mui.css" rel= ...