全局键盘(鼠标)钩子的dll问题(刚才忘记分数了)
想写一个全局的 键盘(鼠标)钩子,用来判断键盘或者鼠标已经空闲了多少时间即:鼠标和键盘没有输入。在写的过程中遇到了如下问题:
我用两种方法写的两个dll 其中一个是可以成功实现键盘(鼠标)钩子的,还有一个只能钩到对话框上的鼠标和键盘消息(因为我的测试程序的是一个对话框程序)
先看下成功的这个dll:这个dll 没有用头文件 对导出函数(就是在测试程序里面要用的函数,应该是这样叫的吧)进行声明。而是用了一个def文件
#include "stdafx.h"
#define DLLEXPORT __declspec(dllexport)
#pragma data_seg (".MouseKeyHook")
HHOOK g_hHookKbd = NULL;
HHOOK g_hHookMouse = NULL;
DWORD g_dwLastInputTick = 0;
#pragma data_seg ()
HINSTANCE hInst =NULL;
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
hInst=(HINSTANCE)hModule;
break;
}
return TRUE;
}
DLLEXPORT DWORD GetLastMouseKeyTime()
{
return g_dwLastInputTick;
}
LRESULT CALLBACK MyKbdHook(int code, WPARAM wParam, LPARAM lParam)
{
if (code==HC_ACTION)
{
g_dwLastInputTick = GetTickCount();
}
return ::CallNextHookEx(g_hHookKbd, code, wParam, lParam);
}
LRESULT CALLBACK MyMouseHook(int code, WPARAM wParam, LPARAM lParam)
{
if (code==HC_ACTION) {
g_dwLastInputTick = GetTickCount();
}
return ::CallNextHookEx(g_hHookMouse, code, wParam, lParam);
}
DLLEXPORT BOOL InitHook()
{
if (g_hHookKbd == NULL) {
g_hHookKbd = SetWindowsHookEx(WH_KEYBOARD, MyKbdHook, hInst, 0);
g_hHookMouse = SetWindowsHookEx(WH_MOUSE, MyMouseHook, hInst, 0);
g_dwLastInputTick = GetTickCount(); // init count
}
return TRUE;
}
DLLEXPORT void UninstallHook()
{
BOOL bRet1 = UnhookWindowsHookEx(g_hHookKbd);
BOOL bRet2 = UnhookWindowsHookEx(g_hHookMouse);
}
下面是 .DEF文件:
LIBRARY "MouseKeyHook"
DESCRIPTION 'MouseKeyHook DLL by Paul DiLascia'
SECTIONS .MouseKeyHook READ WRITE SHARED
用这个dll来测试的话 可以得到我想要的结果。
/////////////////////////////////////////////////////////////
第二个dll没有用def文件,而是用一个头文件将导出函数声明了一下代码如下:
#include <windows.h>
#include "IdleUI.h"
#pragma data_seg (".IdleUI") // you must define as SHARED in .def
HHOOK g_hHookKbd = NULL; // one instance for all processes
HHOOK g_hHookMouse = NULL; // one instance for all processes
DWORD g_dwLastInputTick = 0; // tick time of last input event
#pragma data_seg ()
HINSTANCE hInst =NULL;
BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)
{
switch( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
hInst=(HINSTANCE)hModule;
break;
}
return TRUE;
}
DWORD GetLastMouseKeyTime()
{
return g_dwLastInputTick;
}
LRESULT CALLBACK MyKbdHook(int code, WPARAM wParam, LPARAM lParam)
{
if (code==HC_ACTION) {
g_dwLastInputTick = GetTickCount();
}
return ::CallNextHookEx(g_hHookKbd, code, wParam, lParam);
}
LRESULT CALLBACK MyMouseHook(int code, WPARAM wParam, LPARAM lParam)
{
if (code==HC_ACTION) {
g_dwLastInputTick = GetTickCount();
}
return ::CallNextHookEx(g_hHookMouse, code, wParam, lParam);
}
BOOL InitHook()
{
if (g_hHookKbd == NULL) {
g_hHookKbd = SetWindowsHookEx(WH_KEYBOARD, MyKbdHook, hInst, 0);
g_hHookMouse = SetWindowsHookEx(WH_MOUSE, MyMouseHook, hInst, 0);
g_dwLastInputTick = GetTickCount(); // init count
}
return TRUE;
}
void UninstallHook()
{
BOOL bRet1 = UnhookWindowsHookEx(g_hHookKbd);
BOOL bRet2 = UnhookWindowsHookEx(g_hHookMouse);
}
以下是头文件:
IdleUI.h
#define DLLEXPORT __declspec(dllexport)
DLLEXPORT DWORD GetLastMouseKeyTime();
DLLEXPORT BOOL InitHook();
DLLEXPORT void UninstallHook();
我用同一个对话框程序来测试这两个dll
部分代码:
.cpp
#pragma comment(lib,"MouseKeyHook.lib")
_declspec(dllimport) DWORD GetLastMouseKeyTime();
_declspec(dllimport) BOOL InitHook();
_declspec(dllimport) void UninstallHook();
BOOL CTestHookDlg::OnInitDialog()
{....
InitHook();
SetTimer(1,1000,0);
.....
}
void CTestHookDlg::OnTimer(UINT nIDEvent)
{
CString s;
DWORD nsec = (GetTickCount()-GetLastMouseKeyTime())/1000;
s.Format("鼠标键盘已空闲 %d 秒.",nsec);
((CButton*)(GetDlgItem(IDC_STATIC)))->SetWindowText(s);
CDialog::OnTimer(nIDEvent);
}
void CTestHookDlg::OnDestroy()
{
CDialog::OnDestroy();
UninstallHook();
}
第一个dll可以成功时间我的目的。
第二个dll就有点奇怪了,只有当鼠标在我的测试对话框的上面移动的时候,会有响应,当鼠标在测试对话框外面移动的时候 时间就一秒一秒的上去了(键盘也一样)
请问这个是怎么回事啊??我估摸着是是不是和.def文件有关啊??难道全局钩子一定要用.def文件吗?不可以用头文件将导出函数声明吗??
还有一个问题: 用我所谓的成功的dll 有时候测试根本没有反映,就是说我鼠标和键盘一动不动,他照样显示的是 “鼠标键盘已空闲 0 秒”
我是第一次弄这个东西,还望各位大虾多帮帮忙。