比较烦琐,希望大家有耐心,谢谢。看了一个全局鼠标钩子的例子(查找钩子例子,很多都是这个,呵呵,是以前程序员大本营中打包的),是这样做的。
在DLL中自己写了个钩子类,并且定义了构造,析构,开始,停止函数。然后用#PRAGMA定义了若干全局的变量。它的开始函数是以一个目标窗口的句柄为参数。
鼠标钩子函数中把鼠标指向的窗口名称写给这个目标窗口(用SENDMESSAGE, WM-SETTEXT)。
然后是个对话框,采用隐式连接,给对话框类定义了一个钩子对象,然后在初始化过程中取得一个编辑框的句柄,用开始函数把钩子挂上。这样编辑框就出现鼠标指向窗口的名字。这都很正常。后来我把名字改成鼠标位置,也很好。
接下来,我想把开始函数的参数改成一个点,(点在对话框中定义)鼠标钩子函数把坐标写到这个点中,但为什么总都没有效果?是不是在DLL中不能访问应用程序的地址空间?但是调用DLL时不是把DLL影射到应用程序的地址空间了吗?
而且奇怪的是,一旦我把向这个点赋值的语句写到鼠标钩子函数中,就连设置窗口标题也都不执行,只显示程序刚开始运行时的鼠标坐标,而切我一旦使用这个点,程序执行时就会报什么内存不能为读的错误。
有无办法用这样方式传递?还是必须采用复杂的方式,比如什么WM-COPYDATA的?还有,在DLL中定义的共享数据,如何在应用程序中引用?后来是第二种尝试,我在DLL中加了一些导出函数,在导出函数中定义钩子对象,挂钩子等,编译可以通过,但试验效果好象是在外面引用这些函数,钩子始终没有挂上。这个DLL有MAIN函数,并且定义了一个全局HINSTANCE 对象,glhins,在DLLMAIN函数中把hinstance赋给这个对象,然后在钩子类的开始函数中,SETWINDOWSHOOKEX时把它做为第三个参数,我的导出函数没有作用是不是因为我这样子改了之后,程序根本没有走DLLMAIN ,这个对象始终是空的?所以钩子挂不上?如果我在没有DLLMAIN的DLL中挂钩子,那么第三个参数,也就是当前模块实例该用什么?或者怎么获得?比较麻烦,谢谢。
回头我看看能不能找到那个例子。
虽然用到钩子,不过我觉得这还属于DLL问题吧。
在DLL中自己写了个钩子类,并且定义了构造,析构,开始,停止函数。然后用#PRAGMA定义了若干全局的变量。它的开始函数是以一个目标窗口的句柄为参数。
鼠标钩子函数中把鼠标指向的窗口名称写给这个目标窗口(用SENDMESSAGE, WM-SETTEXT)。
然后是个对话框,采用隐式连接,给对话框类定义了一个钩子对象,然后在初始化过程中取得一个编辑框的句柄,用开始函数把钩子挂上。这样编辑框就出现鼠标指向窗口的名字。这都很正常。后来我把名字改成鼠标位置,也很好。
接下来,我想把开始函数的参数改成一个点,(点在对话框中定义)鼠标钩子函数把坐标写到这个点中,但为什么总都没有效果?是不是在DLL中不能访问应用程序的地址空间?但是调用DLL时不是把DLL影射到应用程序的地址空间了吗?
而且奇怪的是,一旦我把向这个点赋值的语句写到鼠标钩子函数中,就连设置窗口标题也都不执行,只显示程序刚开始运行时的鼠标坐标,而切我一旦使用这个点,程序执行时就会报什么内存不能为读的错误。
有无办法用这样方式传递?还是必须采用复杂的方式,比如什么WM-COPYDATA的?还有,在DLL中定义的共享数据,如何在应用程序中引用?后来是第二种尝试,我在DLL中加了一些导出函数,在导出函数中定义钩子对象,挂钩子等,编译可以通过,但试验效果好象是在外面引用这些函数,钩子始终没有挂上。这个DLL有MAIN函数,并且定义了一个全局HINSTANCE 对象,glhins,在DLLMAIN函数中把hinstance赋给这个对象,然后在钩子类的开始函数中,SETWINDOWSHOOKEX时把它做为第三个参数,我的导出函数没有作用是不是因为我这样子改了之后,程序根本没有走DLLMAIN ,这个对象始终是空的?所以钩子挂不上?如果我在没有DLLMAIN的DLL中挂钩子,那么第三个参数,也就是当前模块实例该用什么?或者怎么获得?比较麻烦,谢谢。
回头我看看能不能找到那个例子。
虽然用到钩子,不过我觉得这还属于DLL问题吧。
//取目标窗口句柄 HWND ParentWnd=glhTargetWnd; while (ParentWnd !=NULL) { glhTargetWnd=ParentWnd; ParentWnd=GetParent(glhTargetWnd); //取应用程序主窗口句柄 } if(glhTargetWnd!=glhPrevTarWnd) { char szCaption[100]; GetWindowText(glhTargetWnd,szCaption,100); //取目标窗口标题 if(IsWindow(glhDisplayWnd)) SendMessage(glhDisplayWnd,WM_SETTEXT,0,(LPARAM)(LPCTSTR)szCaption); glhPrevTarWnd=glhTargetWnd; //保存目标窗口 } } return CallNextHookEx(glhHook,nCode,wparam,lparam); //继续传递消息 } (10)编译项目生成mousehook.dll。 2.创建钩子可执行程序 (1)用MFC的AppWizard(EXE)创建项目Mouse; (2)选择“基于对话应用”并按下“完成”键; (3)编辑对话框,删除其中原有的两个按钮,加入静态文本框和编辑框,用鼠标右键点击静态文本框,在弹出的菜单中选择“属性”,设置其标题为“鼠标所在的窗口标题”; (4)在Mouse.h中加入对Mousehook.h的包含语句#Include"..\Mousehook\Mousehook.h"; (5)在CMouseDlg.h的CMouseDlg类定义中添加私有数据成员: CMouseHook m_hook;//加入钩子类作为数据成员 (6)修改CmouseDlg::OnInitDialog()函数: BOOL CMouseDlg::OnInitDialog() { CDialog::OnInitDialog(); 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); } } SetIcon(m_hIcon, TRUE);//Set big icon SetIcon(m_hIcon, FALSE);//Set small icon //TODO: Add extra initialization here CWnd * pwnd=GetDlgItem(IDC_EDIT1); //取得编辑框的类指针 m_hook.starthook(pwnd->GetSafeHwnd()); //取得编辑框的窗口句柄并安装钩子 return TRUE; //return TRUE unless you set the focus to a control } (7)链接DLL库,即把..\Mousehook\debug\Mousehook.lib加入到项目设置链接标签中; 还是这个老例子,呵呵。
我主要改了鼠标钩子函数。
LRESULT WINAPI MouseProc(int nCode,WPARAM wparam,LPARAM lparam) { LPMOUSEHOOKSTRUCT pMouseHook=(MOUSEHOOKSTRUCT FAR *) lparam; if (nCode>=0) {
char szCaption[100];
sprintf(sz,“%d,%d”,pmousehook-》pt。x,pmousehook-》pt。y); SendMessage(glhDisplayWnd,WM_SETTEXT,0,(LPARAM)(LPCTSTR)szCaption);
//我在这里试图向一个点写值。
} return CallNextHookEx(glhHook,nCode,wparam,lparam); //继续传递消息 }
我在DLL的导出函数中这样用,是不是相当与执行模块与钩子模块就在一起了?所以要挂全局钩子,肯定是挂不上的,如果我要使用这样的导出函数,是不是需要自己再写一个DLL(就相当于那个对话框了),然后在那里连接这个DLL?
自己获得自己的实例句柄?
而且,那个参数应该十HINSTANCE类型的,可以吗?
是不是我的问题说的太长了,没人响应啊。