用VC_设计Win32全局钩子
- 格式:pdf
- 大小:789.65 KB
- 文档页数:3
Win32的API函数是微软自己的东西,可以直接在C#中直接调用,在做WinForm 时还是很有帮助的。
有时候我们之直接调用Win32 的API,可以很高效的实现想要的效果。
代码using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Runtime.InteropServices;namespace WindowsAPI{class CSharp_Win32Api{#region User32.dll 函数///<summary>///该函数检索一指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄,以后可以在GDI函数中使用该句柄来在设备上下文环境中绘图。
hWnd:设备上下文环境被检索的窗口的句柄///</summary>[DllImport("user32.dll", CharSet = CharSet.Auto)]public static extern IntPtr GetDC(IntPtr hWnd);///<summary>///函数释放设备上下文环境(DC)供其他应用程序使用。
///</summary>public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);///<summary>///该函数返回桌面窗口的句柄。
桌面窗口覆盖整个屏幕。
///</summary>static public extern IntPtr GetDesktopWindow();///<summary>///该函数设置指定窗口的显示状态。
///</summary>static public extern bool ShowWindow(IntPtr hWnd, short State );///<summary>///通过发送重绘消息 WM_PAINT 给目标窗体来更新目标窗体客户区的无效区域。
c++钩子函数的编写一、引言钩子函数是一种在特定事件发生时被操作系统调用的函数,通常用于在应用程序中拦截和处理系统事件。
在C语言中,钩子函数是一种常用的技术,它允许开发者在应用程序中监视系统事件,以便对事件进行自定义处理。
本文将介绍钩子函数的编写方法,包括钩子函数的定义、注册、触发和注销等过程。
二、钩子函数的定义钩子函数通常是一个回调函数,它接受一些参数并返回一个结果。
钩子函数的定义通常包括以下内容:1. 函数原型:定义钩子函数的返回类型和参数列表。
2. 函数体:实现钩子函数的具体逻辑。
下面是一个简单的钩子函数示例:```cint hook_func(int data) {// 钩子函数的逻辑实现// ...return 0; // 返回结果}```三、钩子函数的注册钩子函数注册是将钩子函数添加到特定事件中,以便在事件发生时被调用。
注册钩子函数通常需要提供钩子函数的地址和事件类型等信息。
注册钩子函数的方法取决于操作系统和编程语言的具体实现。
下面是一个简单的钩子函数注册示例:```c// 注册钩子函数到鼠标点击事件中int mouse_click_hook = register_hook(HOOK_MOUSE_CLICK, hook_func);```四、钩子函数的触发钩子函数触发是指在特定事件发生时,调用注册的钩子函数进行处理。
触发钩子函数通常需要提供事件的相关信息,例如事件类型、事件发生的位置等。
触发钩子函数的方法取决于操作系统和编程语言的具体实现。
下面是一个简单的钩子函数触发示例:```c// 触发鼠标点击事件钩子函数处理trigger_hook(HOOK_MOUSE_CLICK, x, y);```五、钩子函数的注销钩子函数注销是将钩子函数从特定事件中移除,以便在其他时间点再次注册。
注销钩子函数通常需要提供钩子函数的地址和事件类型等信息。
注销钩子函数的方法取决于操作系统和编程语言的具体实现。
win32 文件钩子使用例子【原创实用版】目录1.Win32 文件钩子的概念和作用2.Win32 文件钩子的使用例子3.Win32 文件钩子的优点和局限性正文【1.Win32 文件钩子的概念和作用】Win32 文件钩子是一种在 Windows 操作系统中用于监视文件操作的机制。
它允许应用程序在文件被创建、修改、删除或其他操作时得到通知。
文件钩子在系统中以回调函数的形式存在,当发生文件操作时,系统会调用这个回调函数。
通过使用文件钩子,应用程序可以在不直接操作文件系统的情况下监控文件活动,从而实现更高级的功能。
【2.Win32 文件钩子的使用例子】下面是一个使用 Win32 文件钩子的简单例子。
这个例子将演示如何使用文件钩子监控指定目录下文件的创建操作。
首先,需要包含必要的头文件:```c#include <windows.h>```接下来,定义一个回调函数,这个函数将在文件被创建时被调用:```ctypedef void (*LPFNHOOK)(HANDLE, DWORD, LPCSTR, LPCSTR, UINT);LPFNHOOK g_hHook = NULL;void MyHookFunc(HANDLE hModule, DWORD dwType, LPCSTR lpExeName, LPCSTR lpCmdLine, UINT uType){// 在此处添加处理代码,例如记录日志或进行其他操作printf("文件创建:%s", lpExeName);}```然后,使用`SetWindowsHookEx`函数安装回调函数:```cint WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved){if (dwReason == DLL_PROCESS_ATTACH){g_hHook = SetWindowsHookEx(WH_CREATE, MyHookFunc, hInstance, NULL);if (g_hHook == NULL){printf("安装钩子失败");}else{printf("安装钩子成功");}}else if (dwReason == DLL_PROCESS_DETACH){if (g_hHook!= NULL){UnhookWindowsHookEx(g_hHook);}}return 0;}```在上述代码中,`SetWindowsHookEx`函数用于安装回调函数,`WH_CREATE`表示监控文件创建操作。
c++ hook 方法在C++中,钩子(Hook)通常指的是一种在运行时改变程序行为的技术。
这通常涉及到对某个函数或某个特定事件的拦截,以便在发生某些操作时插入自定义的代码。
C++中实现钩子的方法有很多,这里我提供一个简单的例子,使用C++中的函数指针和单例模式来实现一个简单的钩子系统。
首先,定义一个函数指针类型:```cpptypedef void (*HookFunc)();```然后,定义一个钩子管理器类,它维护一个函数指针的列表:```cppclass HookManager {public:static HookManager& getInstance() {static HookManager instance; // 线程安全的单例实现return instance;}void registerHook(HookFunc func) {funcs.push_back(func);}void callHooks() {for (auto func : funcs) {func();}}private:HookManager() {}~HookManager() {} // 不允许复制和赋值std::vector<HookFunc> funcs;};```接下来,你可以在程序中注册钩子函数:```cppvoid myHookFunc1() {// 自定义代码1...}void myHookFunc2() {// 自定义代码2...}int main() {HookManager::getInstance().registerHook(myHookFunc1);HookManager::getInstance().registerHook(myHookFunc2);// ... 其他代码...HookManager::getInstance().callHooks(); // 调用所有注册的钩子函数return 0;}```上面的例子展示了一个简单的钩子系统。
注意:IDR_MENU1是菜单ID,ID_CONTROL_MUTE是需要被打勾的子菜单,加粗部分为核心部分// MFCTestDlg.h : 头文件//#pragma once// CMFCTestDlg 对话框class CMFCTestDlg : public CDialog{// 构造public:CMFCTestDlg(CWnd* pParent = NULL); // 标准构造函数// 对话框数据enum { IDD = IDD_MFCTEST_DIALOG };protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支// 实现protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()/*****************新添加部分**********************/private:BOOL m_bMute;CMenu* pMainMenu;CMenu* pSubMenu;afx_msg void OnControlMute();/*****************end新添加部分**********************/};然后再到CMFCTestDlg.cpp文件里的OnInitDialog加上// CMFCTestDlg 消息处理程序BOOL CMFCTestDlg::OnInitDialog(){CDialog::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。
系统钩子和DLL钩子的本质是一段用以处理系统消息的程序,通过系统调用,将其挂入系统。
钩子的种类有很多,每种钩子可以截获并处理相应的消息,每当特定的消息发出,在到达目的窗口之前,钩子程序先行截获该消息、得到对此消息的控制权。
此时在钩子函数中就可以对截获的消息进行加工处理,甚至可以强制结束消息的传递。
在本程序中我们需要捕获在任意窗口上的键盘输入,这就需要采用全局钩子以便拦截整个系统的消息,而全局钩子函数必须以DLL(动态连接库)为载体进行封装,VC6中有三种形式的MFC DLL可供选择,即Regular statically linked to MFC DLL(标准静态链接MFC DLL)、Regular using the shared MFC DLL(标准动态链接MFC DLL)以及Extension MFC DLL(扩展MFC DLL)。
在本程序中为方便起见采用了标准静态连接MFC DLL。
键盘钩子程序示例本示例程序用到全局钩子函数,程序分两部分:可执行程序KeyKook和动态连接库LaunchDLL。
首先创建一个MFC AppWizard(DLL)工程,并选择Regular statically linked to MFC DLL (标准静态链接MFC DLL)选项,以建立MFC扩展动态连接库LaunchDLL.dll。
之后,在相应的头文件中添加宏定义和待导出函数的声明:#define DllExport __declspec(dllexport)……DllExport void WINAPI InstallLaunchEv();……class CLaunchDLLApp : public CWinApp{public:CLaunchDLLApp();//{{AFX_VIRTUAL(CLaunchDLLApp)//}}AFX_VIRTUAL//{{AFX_MSG(CLaunchDLLApp)// NOTE - the ClassWizard will add and remove member functions here.// DO NOT EDIT what you see in these blocks of generated code !//}}AFX_MSGDECLARE_MESSAGE_MAP()};同时在实现文件中添加全局变量Hook和全局函数LauncherHook()、SaveLog():HHOOK Hook;LRESULT CALLBACK LauncherHook(int nCode,WPARAM wParam,LPARAM lParam);void SaveLog(char* c);最后,完成以上提到的这几个函数的具体编码实现:CLaunchDLLApp theApp;……DllExport void WINAPI InstallLaunchEv(){Hook=(HHOOK)SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)LauncherHook,theApp.m_hInst ance,0);}在此我们实现了Windows的系统钩子的安装,首先要调用SDK中的API函数SetWindowsHookEx()来安装这个钩子函数,其原型是:HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId);其中,第一个参数指定钩子的类型,常用的有WH_MOUSE、WH_KEYBOARD、WH_GETMESSAGE等,在此我们只关心键盘操作所以设定为WH_KEYBOARD;第二个参数标识钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数,即当不管系统的哪个窗口有键盘输入马上会引起LauncherHook的动作;第三个参数是钩子函数所在模块的句柄,我们可以很简单的设定其为本应用程序的实例句柄;最后一个参数是钩子相关函数的ID用以指定想让钩子去钩哪个线程,为0时则拦截整个系统的消息,在本程序中钩子需要为全局钩子,故设定为0。
C#,使⽤Win32钩⼦(Hook)动态更新窗体(Form)今天接到客户新的功能需求,要在原有的⼀个属性查询窗体中添加⼀个新的功能按钮。
这个功能看似简单,实际上从版本更新和后期维护的⾓度来考虑,直接修改原来的窗体并不是⼀个很好的解决⽅案。
后来跟⼀个同事讨论,他建议⽤Win32中的钩⼦机制来实现窗体的更新,并把新功能的程序逻辑单独封装,这样做会降低新增功能与原有程序的耦合度,实现了有效的分离,易于后期维护,适应性强。
以下是关于钩⼦的⽐较详细介绍(⽹络资料,⾮原创)。
基本概念:钩⼦(Hook),是Windows消息处理机制的⼀个平台,应⽤程序可以在上⾯设置⼦程以监视指定窗⼝的某种消息,⽽且所监视的窗⼝可以是其他进程所创建的。
当消息到达后,在⽬标窗⼝处理函数之前处理它。
钩⼦机制允许应⽤程序截获处理window消息或特定事件。
钩⼦实际上是⼀个处理消息的程序段,通过系统调⽤,把它挂⼊系统。
每当特定的消息发出,在没有到达⽬的窗⼝前,钩⼦程序就先捕获该消息,亦即钩⼦函数先得到控制权。
这时钩⼦函数即可以加⼯处理(改变)该消息,也可以不作处理⽽继续传递该消息,还可以强制结束消息的传递。
运⾏机制:1、钩⼦链表和钩⼦⼦程:每⼀个Hook都有⼀个与之相关联的指针列表,称之为钩⼦链表,由系统来维护。
这个列表的指针指向指定的,应⽤程序定义的,被Hook⼦程调⽤的回调函数,也就是该钩⼦的各个处理⼦程。
当与指定的Hook类型关联的消息发⽣时,系统就把这个消息传递到Hook⼦程。
⼀些Hook⼦程可以只监视消息,或者修改消息,或者停⽌消息的前进,避免这些消息传递到下⼀个Hook⼦程或者⽬的窗⼝。
最近安装的钩⼦放在链的开始,⽽最早安装的钩⼦放在最后,也就是后加⼊的先获得控制权。
Windows 并不要求钩⼦⼦程的卸载顺序⼀定得和安装顺序相反。
每当有⼀个钩⼦被卸载,Windows 便释放其占⽤的内存,并更新整个Hook 链表。
如果程序安装了钩⼦,但是在尚未卸载钩⼦之前就结束了,那么系统会⾃动为它做卸载钩⼦的操作。
setwindowshookex wh_getmessage 句柄-概述说明以及解释1.引言1.1 概述setwindowshookex函数是Windows操作系统提供的一个强大的钩子函数,可以用来监视和拦截特定的事件和消息。
而WH_GETMESSAGE 钩子是setwindowshookex函数中的一种类型,可以监视并拦截消息在消息队列发送到线程的过程中。
本文将详细介绍setwindowshookex函数和WH_GETMESSAGE钩子的原理和用法,以及使用setwindowshookex和WH_GETMESSAGE 时需要注意的事项。
通过本文的阐述,读者将能够更好地理解这两个重要的概念,并学会如何有效地利用它们来实现一些高级的Windows应用程序功能。
文章结构部分内容如下:1.2 文章结构本文将首先介绍setwindowshookex函数的作用和用法,包括其参数和返回值等相关信息。
接着将详细讲解WH_GETMESSAGE钩子的使用方法和原理,以及该钩子在Windows编程中的重要性。
最后,将结合具体实例和注意事项,探讨在实际开发过程中如何正确地使用setwindowshookex和WH_GETMESSAGE,并指出一些常见的注意事项和解决方法。
通过本文的阐述,读者将能够深入了解setwindowshookex 和WH_GETMESSAGE的作用及使用技巧,从而提高自身在Windows编程领域的技能水平。
1.3 目的本文的目的是介绍setwindowshookex函数和WH_GETMESSAGE 钩子的概念、功能和使用方法,帮助读者更好地理解这两个重要的Windows API,在开发Windows应用程序时能够灵活运用这些函数,实现特定的功能和监控消息的处理过程。
通过深入探讨setwindowshookex 和WH_GETMESSAGE的原理和实践,读者可以加深对Windows系统消息处理机制的理解,提升自己在Windows编程领域的技术水平。
不依赖的DLL的全局钩子编写(例:WH_KEYBOARD_LL)在VC中捕按键可以在OnKeyDown 或OnKeyUp 事件中进行捕获,不过这有很大的局限性,这里只能捕获用户按键。
但在一些特殊的工程(项目)中往往需要捕获某些系统按键以完成特殊的功能,我们就不得不选择钩子了,一般情况下大家都会选择WH_KEYBOARD 这个钩子类型,但是在编写过程会发现这个钩子类型并不能捕获所有的系统按键,怎么办呢?那就得选择WH_KEYBOARD_LL (低级键盘钩子)了,使用它可以捕获全部的系统按键,一个不漏……在使用低级键盘钩子之前,先在StdAfx.h 的第一行添加一条:#define _WIN32_WINNT 0x400(这里假定你是用的MFC 的DLL),不然在编译的时候会提示说WH_KEYBOARD_LL 没有定义。
网上还有另一种方法:首先定义#define WH_KEYBOARD_LL 13; 然后Winuser.h 中定义的tagKBDLLHOOKSTRUCT 代码拷贝到工程中。
下面代码用以捕获系统按键:/*用户模块return TRUE; --->丢弃该消息*/LRESULT CALLBACK LowLevelKeyboardProc(int nCode, // hook codeWPARAM wParam, // message identifierLPARAM lParam // message data){PKBDLLHOOKSTRUCT pm = NULL;if (nCode == HC_ACTION){pm = (PKBDLLHOOKSTRUCT)lParam;switch(pm->vkCode){//屏蔽win键case VK_LWIN:case VK_RWIN:return 1;break;//屏蔽alt+tabcase VK_TAB:if(pm->flags & LLKHF_ALTDOWN){return 1;}break;//屏蔽esc alt+esc ctrl+esccase VK_ESCAPE:return 1;break;//屏蔽ALT+F4case VK_F4:if(pm->flags & LLKHF_ALTDOWN){return 1;}break;//屏蔽F1case VK_F1:return 1;break;//屏蔽CTRL+ALT+DELcase VK_DELETE:if(pm->flags & LLKHF_ALTDOWN){if (GetKeyState(VK_CONTROL) < 0){return 1;}}break;default:break;}}}// if (WM_KEYDOWN == wParam || WM_SYSKEYDOWN)// //如果按键为按下状态// {// if (Key_Info->vkCode == VK_LWIN || Key_Info->vkCode == VK_RWIN) // //屏敝WIN(左右) 键// {// return TRUE;// }// if (Key_Info->vkCode == 0x4D && ((GetKeyState(VK_LWIN) & 0x8000) || // (GetKeyState(VK_RWIN) & 0x8000)))// //屏敝WIN+D 组合键(左右)// {// return TRUE;// }// if (Key_Info->vkCode == 0x44 && ((GetKeyState(VK_LWIN) & 0x8000) ||// (GetKeyState(VK_LWIN) & 0x8000)))// //屏敝WIN+M 组合键(左右)// {// return TRUE;// }// if (Key_Info->vkCode == 0x1b && GetKeyState(VK_CONTROL) & 0x8000) // //屏敝CTRL + ESC 组合键// {// return TRUE;// }// if (Key_Info->vkCode == VK_TAB && Key_Info->flags & LLKHF_ALTDOWN)// //屏敝ATL + TAB 组合键// {// return TRUE;// }// if (Key_Info->vkCode == VK_ESCAPE && Key_Info->flags & LLKHF_ALTDOWN)// //屏敝ATL + ESC 组合键// {// return TRUE;// }// if (Key_Info->flags & LLKHF_ALTDOWN)// //屏敝CTRL 键// {// return TRUE;// }// }return CallNextHookEx(g_hhk, nCode, wParam, lParam);}BOOL CTestHookDlg::OnInitDialog(){CDialog::OnInitDialog();// Set the icon for this dialog. The framework does this automatically// when the application's main window is not a dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon// TODO: Add extra initialization hereg_hhk = SetWindowsHookEx(13, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);return TRUE; // return TRUE unless you set the focus to a control}*** 注意***此钩子必须是系统级的钩子,也就是说在安装钩子的时候,ThreadID 的值必须为0。
收稿日期:2000-10-28作者简介:谢志鹏(1972-),男,福建晋江人,硕士研究生,主要研究方向:图形图像处理; 陈锻生(1959-),男,福建泉州人,副教授,主要研究方向:图像处理、多媒体技术.文章编号:1001-9081(2001)04-0085-02用VC ++设计Win32全局钩子谢志鹏,陈锻生(国立华侨大学计算机系,福建泉州362011)摘 要:通过编写一个截获并处理系统范围消息的钩子程序,介绍用MFC 扩展动态链接库封装全局钩子类和向任务栏通知区添加应用程序图标。
关键词:钩子;动态链接库;消息映射中图分类号:TP316.7 文献标识码:A在Win32系统下,使用钩子(Hook)截获并处理系统范围内的消息,能完成普通程序无法实现的功能,如创建自动演示程序,制作程序日志,辅助调试等;常见的高级应用有屏幕抓图,屏幕取词翻译,智能鼠标等,该种应用的编写涉及较多的知识:可对消息进行全局捕获与操纵的各种钩子;装载全局钩子的动态链接库;如何向系统任务栏通知区添加图标。
作为上述应用的一个较完整的例子,本文以编制一个模拟方向键盘的消息钩子为主线,逐次剖析了相关的原理。
1 设计思想Windows 系统是建立在事件驱动机制上的,各种事件的触发产生相应的消息,整个系统的运作是通过消息的传递和响应来实现的。
但是,在应用程序的消息循环中只能截获并处理本程序内的消息,无法处理其它程序产生的消息,所以这时候就要借助于全局钩子来实现;而对于这种可监控系统范围消息的全局钩子,除了日志钩子外,其它钩子函数必须包含在独立的动态链接库(DLL)中,这样才能被各种相关联的应用程序调用。
最后,作为高级的Win32钩子监控程序,如抓词翻译,智能鼠标等,大部分采用向系统任务栏通知区添加图标的作法,方便程序的加载并减小了任务栏应用程序图标的拥挤。
2 钩子的设计2.1 原理及关键函数的运用图1 消息传递路径图1说明了钩子在消息处理链中的位置和作用。
在安装钩子程序之前,系统直接处理应用程序的消息,此时消息传递路径如图1虚线所示;而安装钩子后,每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,其内置的钩子函数就可以对该消息进行处理 可以改变该消息后才向系统传递,也可以不作修改继续传递,还可以丢弃该消息,从而中止该消息的传递,这时消息传递路径如图1实线所示。
钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩子可以监视和记录输入事件。
一旦设置多种钩子,系统就会建立一个钩子链表,该链表运作方式类似于栈,开始安装的钩子放在表尾,最后安装的钩子放在表头,捕获的消息从表头流向表尾,所以最后安装的钩子最有可能处理该消息。
可调用API 函数SetWindowsHookEx 来安装钩子函数,其原型如下:HHOOK SetWi ndows HookEx(intidHook,HOOKPROC lpfn,HINSTANCE hM od,DWORD dwThreadId);各参数的含义如下:int idhook 标识钩子类型的整数,使用宏名,如WHKE YBOARD,其值为2。
HOOKPROC lpfn 表示钩子函数的地址。
HINSTANCE h Mod 包含钩子函数的钩子程序的实例句柄。
DWORD d wThreadId 代表欲监视的线程的标识,值为NULL 则为全局钩子。
由lp fn 指向的钩子函数在完成对消息的处理后,如果要继续传递该消息,必须调用API 函数CallNext HookEx ,如果直接返回TRUE 则该消息将被丢弃,不再往下传递。
LRESULT CallNextHookEx (HHOOK hhk,int nCode,WPARA MwParam,LPARA M lParam);各参数的含义如下:H HOOK hhk 表示当前的钩子句柄;int nCode 表示传给当前钩子函数的代码。
WPARAM wParam 和LPARAM lParam 均为传给当前钩子函数的消息的值。
如果要从钩子链中释放该钩子,只要调用以下函数:BOOL UnhookWi ndo ws HookEx (HHOOK hhk //欲释放的钩子函数的句柄);钩子分为线程专用钩子和全局钩子,线程专用钩子只监视指定的线程,要监视系统中的所有线程,必须用到全局钩子。
2.2 封装 MFC 扩展DLL 的调用用扩展MFC 动态链接库可方便地把钩子函数封装成类CMsgHook,而后导出整个类,具体步骤如下:1)选择MFC App Wizard(DLL)创建项目Hookdll;2)选择MFC Extension DLL 类型;第21卷2001年4月计算机应用Computer Applications Vol.21,No.4Apr.,20013)新建Hookdll.h文件,在里面声明钩子类,clas s AFX EX T CLASS CMs gHook:public CObject{ //AFX EX T CLASS表示导出整个类CM s gHookpublic:CMs gHook(); ~CM s gHook();HHOO K InstallHook();//安装钩子函数void Release Hook();//卸下钩子函数BOO L GetSate();//检查钩子是否安装};4)在文件Hookdll.def中定义共享数据段shared dataSECTIONSs hared data READ WRITE SHARED5)在Hookdll.cpp文件中定义钩子类,在文件开头增加语句#include Hookdll.h ,新增下列语句:extern C declspec(dllexport)LRESUL T WINAPIGetMsg HookFunc(int nCode,WP ARAM wParam,LPARA M lParam);#pragma data s eg( s hared data )//共享数据段shared data HHOOK g hMsg Hook=NULL;//钩子函数的句柄HINSTANCE g hInstance=NULL;//调用钩子函数的钩子程序实例的句柄BO OL g load=FALSE;//未启动消息钩子, //g load为不同钩子程序实例间互相通知钩子启动情况的共享变量#pragma data s eg()extern C int APIENTRYDllMain(HINSTANCE hInstance,DWORD dwReas on,LPVOID lpReserved){在if(dwReas on==D LL PR OCESS A TT ACH)子句中增加一语句new CDynLi nkLibrary(Hookdll DLL);}HHOOK CMsg Hook::InstallHook(){g hM s gHook=SetWindows HookEx(WH GETMESSAGE, GetMsg HookFunc,g hInstance,0);return g hM s gHook;}void CMsgHook::Release Hook(){UnhookWi ndows HookEx(g hMsg Hook);}extern C declspec(dllexport)LRESUL T WINAPIGetMsg HookFunc(int nCode,WPARA M wParam,LPAR AM lPara m){.....MSG*m=(MSG*)l Param;s witch(m->mes sage){cas e WM SYSCOM MAND:{i f(m->wParam==SC SCREENSAVE)m->wParam=PM R EMOVE;}cas e WM CHAR:i f(temp.Find(net)!=-1){s witc h((c har)(m->wParam)){case D :m->mess age=WM VSCRO LL;m->wParam=SB LINEDO WN;break;case E :m->mess age=WM VSCRO LL;m->wParam=SB LINEUP;break;case S :m->message=WM HSCROLL;m->wPara m=SB LINELEFT;break;case F :m->message=WM HSCROLL;m->wParam=SB LINERIGHT;break;}SendMessage(hWndTarge t,m->mes sage,m->wParam,N ULL);}}return CallNextHookEx(g hMs gHook,nCode,wParam,lPara m);}6)编译并生成钩子动态链接库Hookdll.dll。
2.3 任务栏通知区图标的钩子宿主程序a)创建无文档和视图的MFC程序框架,并将MainFrame 主框架窗口的显示形式设为隐含,如在InitInstance()函数中添加语句pFrame->showWindow(SW SHOW);b)在OnCreate()中调用函数Shell Noti fyIcon(),向任务栏中增加一个图标:WIN SHELLA PI BOOL WINAPI Shell NotifyIc on(DWORD dwMessage, PNO TIFYICO NDATA pnid);参数dw M essage表示发送消息的含义,可以是以下标识符之一:NIM ADD 向任务栏状态区增加图标。
NIM MODIFY 修改任务栏状态区中的图标。
NIM DE LETE 删除任务栏状态区中的图标。
参数pnid为NOT IFYICONDATA类型的数据结构的地址指针。
NOT IFYICONDATA数据结构说明。
typedef s truc t NO TIFYICONDA TA{D WORD cbsiz e,HWND hWnd, UINT uID,UINT uFlags,UINT uCallbackMessage,HICON hIcon,char sz Ti p[64];}NOTIFYICONDA TA,*PNO TIFYICOND ATA;各参数含义如下:DWORD cbsize 该数据结构的大小。
HWND hWnd 处理任务栏中图标的窗口句柄。
UINT uID 任务栏中该图标的标识值UINT uFlags 任务栏图标功能控制位,可以是以下值的组合:NIF ME SS AGE 发送控制消息;NIF ICON 显示该任务栏图标;NIF TIP 动态提示文字。