b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

一个简单的鼠标钩程序

电脑杂谈  发布时间:2020-04-28 13:32:15  来源:网络整理

c 线程鼠标钩子_c 鼠标钩子_易语言键盘鼠标钩子

演示屏幕截图:

代码介绍或代码分析:

一个简单的鼠标钩程序

了解当前鼠标所在的窗口的标题并将其显示在EDITBOX中

Windows系统基于事件驱动机制. 坦率地说,整个系统是通过消息的传输来实现的. 挂钩是Windows系统中非常重要的系统界面. 它可以用来拦截和处理发送给其他应用程序的消息,以完成普通应用程序难以实现的功能. 钩子有很多类型. 每个挂钩都可以拦截和处理相应的消息. 例如,键盘挂钩可以拦截键盘消息,而外壳挂钩可以拦截,启动和关闭应用程序消息. 本文在VC6编程环境中实现了一个简单的鼠标挂钩程序,并简要说明了Win32全局挂钩的运行机制,Win32 DLL的特性,VC6环境中的MFC DLL和共享数据.

一个. Win32全局钩子的运行机制

挂钩实际上是一个处理消息的程序段,并通过系统调用将其挂钩到系统中. 每当发送特定消息时,挂钩程序都会在到达目标窗口之前首先捕获该消息,也就是说,挂钩函数首先获得控制权. 此时,挂钩函数可以处理(更改)消息,或者继续不处理就继续传递消息,或者强制结束消息的传递. 系统为每种类型的挂钩维护一个挂钩链. 最近安装的钩子放置在链的开头,而第一个安装的钩子放置在链的末端,也就是说,稍后添加的钩子将获得控制权. 要实现Win32系统挂钩,必须调用SDK中的API函数SetWindowsHookEx来安装挂钩函数. 该函数的原型是

HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId);

其中,第一个参数是hook的类型;第二个参数是挂钩函数的地址;第三个参数是包含挂钩函数的模块句柄;第四个参数指定受监视的线程. 如果指定了指定线程,则它是线程特定的挂钩;如果指定为空,则为全局钩子. 其中,全局挂钩函数必须包含在DLL(动态链接库)中,并且特定于线程的挂钩也可以包含在可执行文件中. 在获得控制权的挂钩函数完成对消息的处理之后,如果希望继续传递消息,则必须调用另一个SDK中的API函数CallNextHookEx来传递它. 挂钩函数还可以通过直接返回TRUE来丢弃消息,并阻止消息传递.

两个. Win32 DLL的功能

Win32 DLL与Win16 DLL有很大的不同,这主要是由操作系统的设计思想决定的. 一方面,程序入口点函数和出口点函数(LibMain和WEP)分别在Win16 DLL中实现;在Win32 DLL中,实现了相同的函数DLLMain. 每当进程或线程加载和卸载DLL时,都应调用此函数. 它的原型是BOOL WINAPI DllMain

(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved);其中第一个参数代表DLL的实例句柄;第三参数由系统保留;这里我们主要介绍第二个参数,它有四个可能的值: DLL_PROCESS_ATTACH(进程加载),DLL_THREAD_ATTACH(线程加载),DLL_THREAD_DETACH(线程卸载),DLL_PROCESS_DETACH(进程卸载),可以在DLLMain函数,并根据不同的参数DLL执行必要的初始化或清除. 例如,当进程加载DLL时,系统分配给DLL的第二个参数是DLL_PROCESS_ATTACH. 此时,您可以基于此参数初始化特定数据. 另一方面,在Win16环境中,所有应用程序都在相同的地址空间中. 在Win32环境中,所有应用程序都有自己的私有空间,并且每个进程的空间是彼此独立的,这减少了应用程序之间的交互数量,但同时也增加了编程的难度. 如您所知,在Win16环境中,DLL的全局数据对于每个加载它的进程都是相同的. 在Win32环境中,情况已经改变. 当进程正在加载DLL时,系统会自动将DLL地址映射到进程的私有空间,并且DLL的全局数据的副本也会复制到进程空间,这意味着全局值每个进程拥有的相同DLL的数据不一定相同. 的. 因此,如果要在Win32环境下在多个进程中共享数据,则必须进行必要的设置. 也就是说,需要共享的数据被分离并放置在一个独立的数据段中,并且该段的属性被设置为共享.

三个. VC6中MFC DLL的分类和特征

VC6中有三种形式的MFC DLL(您可以使用和继承此DLL中的现有MFC类)以进行选择c 鼠标钩子,即,静态链接到MFC DLL的Regular和使用共享MFC DLL(标准动态链接MFC DLL)的Regular和扩展MFC DLL(扩展MFC DLL). 第一个DLL的特征是在编译时将使用的MFC代码添加到DLL中. 因此,使用此程序时,不需要其他MFC动态链接库,但是它占用更多的磁盘空间. 第二个DLL的特点是在运行时将其动态链接到MFC类库,从而减少了空间的占用,但是在运行时它依赖于MFC动态链接类库. MFC程序或Win32程序可以使用这两个DLL. 采用. 第三类DLL的特征类似于第二种. 作为MFC类库的扩展,它只能由MFC程序使用.

四个. 在VC6中实现全局共享数据

在主文件中,使用#pragma data_seg创建新的数据段并定义共享数据. 具体格式为:

#pragma data_seg(“ shareddata”)

HWND sharedwnd = NULL; //共享的数据

#pragma data_seg()

仅定义数据段不能达到共享数据的目的,而且还告诉编译器该段的属性. 有两种方法可以达到此目的(效果是相同的). 添加以下语句:

设置

shareddata读写共享

另一种方法是在项目设置链接选项中添加以下语句:

/部分: shareddata,rws

五个. 具体实施步骤

因为全局挂钩函数必须包含在动态链接库中,所以此示例由两个程序主体实现.

1. 创建钩子Mousehook.DLL

(1)选择MFC AppWizard(DLL)创建项目Mousehook;

(2)选择MFC扩展DLL(共享的MFC副本)的类型;

(3)由于VC5没有现成的钩子类,因此您需要在项目目录中创建Mousehook.h文件并在其中创建钩子类:

AFX_EXT_CLASS类CMouseHook: 公共CObject

{

公开

:

CMouseHook(); //钩子类的构造函数

c 鼠标钩子_易语言键盘鼠标钩子_c 线程鼠标钩子

virtual〜CMouseHook(); //钩子类的析构函数

公开

:

BOOL StartHook(HWND hWnd); //安装钩子功能

BOOL StopHook(); //卸载钩子功能

};

(4)在Mousehook.cpp文件顶部添加#include“ Mousehook.h”语句;

(5)在Mousehook.cpp文件的顶部添加全局共享数据变量:

#pragma data_seg(“ mydata”)

HWND glhPrevTarWnd = NULL; //最后鼠标指向的窗口句柄

HWND glhDisplayWnd = NULL; //显示标题窗口标题编辑框的句柄

HHOOK glhHook = NULL; //安装的鼠标钩的手柄

HINSTANCE glhInstance = NULL; // DLL实例句柄

#pragma data_seg()

(6)在DEF文件中定义细分属性:

部分

mydata读写共享

(7)在主文件Mousehook.cpp中,添加以下语句以将DLL实例句柄保存到DllMain函数:

glhInstance = hInstance;

(8)挂钩函数的实现:

//钩子函数的实现:

LRESULT WINAPI MouseProc(整数nCode,WPARAM wparam,LPARAM lparam)

{

LPMOUSEHOOKSTRUCT pMouseHook =(MOUSEHOOKSTRUCT FAR *)lparam;

如果(nCode> = 0)

{

HWND glhTargetWnd = XYZWindowFromPoint(NULL,pMouseHook-> pt);

如果(glhTargetWnd!= glhPrevTarWnd)

{

char szCaption [100];

GetWindowText(glhTargetWnd,szCaption,100);

//获取目标窗口标题

如果(IsWindow(glhDisplayWnd))

SendMessage(glhDisplayWnd,WM_SETTEXT,0,(LPARAM)(LPCTSTR)szCaption);

glhPrevTarWnd = glhTargetWnd;

c 鼠标钩子_易语言键盘鼠标钩子_c 线程鼠标钩子

//保存目标窗口

}

}

返回CallNextHookEx(glhHook,nCode,wparam,lparam);

//继续传递消息

}

函数XYZWindowFromPoint返回光标(点)所在的子窗口的句柄

HWND XYZWindowFromPoint(HWND hwndParent,//父窗口的句柄

POINT点,//具有点坐标的结构

UINT uFlags //跳过选项

{

如果(hwndParent!= NULL)

return :: ChildWindowFromPointEx(hwndParent,point,uFlags);

//返回光标(点)所在的子窗口的句柄

//找到仍然包含该点的最小“窗口”

//这样做使我们无法在包含该点的第一个窗口处停止

RECT rect,rectSearch;

HWND pWnd,hWnd,hSearchWnd;

hWnd = :: WindowFromPoint(点); //获取光标(点)所在点的窗口句柄

如果(hWnd!= NULL)

{

//获取大小和父项以供以后比较

:: GetWindowRect(hWnd,&rect); //获取屏幕上整个窗口的矩形框位置

pWnd = :: GetParent(hWnd); //获取父窗口句柄

///如果窗口有父级,我们只会进一步搜索

如果(pWnd!= NULL)

{

//从Z顺序的窗口向下搜索

hSearchWnd = hWnd;

{

hSearchWnd = :: GetWindow(hSearchWnd,GW_HWNDNEXT);

//如果找不到这样的窗口,该函数将返回NULL

// GetWindow获取与句柄为hSearchWnd(即第一个循环为hWnd)的窗口相关的窗口,

易语言键盘鼠标钩子_c 鼠标钩子_c 线程鼠标钩子

//关系是由GW_HWNDNEXT确定的,这是寻找兄弟的窗口

//搜索窗口是否也包含该点,具有相同的父对象并且可见?

:: GetWindowRect(hSearchWnd和rectSearch);

if(:: PtInRect(&rectSearch,point)&& :: GetParent(hSearchWnd)== pWnd && :: IsWindowVisible(hSearchWnd))

{

//可以,但是更小吗?比较谁的面积最小

如果((((rectSearch.right-rectSearch.left)*(rectSearch.bottom-rectSearch.top)))<

(((rect.right-rect.left)*(rect.bottom-rect.top)))

{

//找到了新的较小的窗口,更新了比较窗口

hWnd = hSearchWnd;

:: GetWindowRect(hWnd,&rect);

}

}

}

while(hSearchWnd!= NULL);

}

}

返回hWnd;

}

(9)CMouseHook类的成员函数的具体实现:

CMouseHook :: CMouseHook()

{

}

CMouseHook ::〜CMouseHook()

{

}

//安装挂钩并设置接收显示窗口的手柄

BOOL CMouseHook :: StartHook(HWND hWnd)

{

BOOL bResult = FALSE;

glhHook = SetWindowsHookEx(WH_MOUSE,MouseProc,glhInstance,0);

如果(glhHook!= NULL)

bResult = TRUE;

glhDisplayWnd = hWnd;

c 鼠标钩子_c 线程鼠标钩子_易语言键盘鼠标钩子

//设置显示标题窗口标题编辑框的句柄

返回bResult;

}

//卸载钩子

BOOL CMouseHook :: StopHook()

{

BOOL bResult = FALSE;

如果(glhHook)

{

bResult = UnhookWindowsHookEx(glhHook);

如果(bResult)

{

glhPrevTarWnd = NULL;

glhDisplayWnd = NULL; //清除变量

glhHook = NULL;

}

}

返回bResult;

}

(10)编译项目以生成mousehook.dll.

2. 创建钩子可执行程序

(1)使用MFC的AppWizard(EXE)创建项目Mouse;

(2)选择“基于对话框的应用程序”,然后按“完成”键;

(3)编辑对话框,删除两个原始按钮,添加一个静态文本框和一个编辑框,右键单击该静态文本框,在弹出菜单中选择“属性”c 鼠标钩子,并设置其标题到“鼠标所在的窗口标题”;

(4)将包含语句#include“ Mousehook.h”添加到Mouse.h中的Mousehook.h中;

(5)在CMouseDlg.h的CMouseDlg类定义中添加私有数据成员:

CMouseHook m_hook; //将钩子类添加为数据成员

(6)修改MouseDlg :: OnInitDialog()的功能:

// TODO: 在此处添加额外的初始化

CWnd * pwnd = GetDlgItem(IDC_EDIT1); //获取编辑框的类指针

m_hook.starthook(pwnd-> GetSafeHwnd()); //获取编辑框的窗口句柄并安装钩子

(7)链接DLL库,即在项目设置的链接标记中添加.. \ Mousehook \ debug \ Mousehook.lib;

(8)编译项目以生成可执行文件;

(9)将Mousehook.DLL复制到.. \ mouse \ debug目录;

(10)首先运行几个可执行程序,然后运行Mouse.exe程序,将鼠标移到不同的窗口中,显示鼠标的应用程序的主窗口将显示在Mouse.exe的编辑框中. 程序窗口标题.


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-191824-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 杞文公益姑
        杞文公益姑

        肯定是开了没封好

      • 杨洋
        杨洋

        中国还没有宣布这三个新岛的领海基点吧

      • 卫靖伯
        卫靖伯

        #杨洋2015金投赏##杨洋icon##杨洋h

        • 温婧
          温婧

          非一个国际领袖的作为

      热点图片
      拼命载入中...