我下面钩子函数当然是有问题的。首先我知道我大小写判断就不对。
楼下只要回答跟这个问题有关的就得分。
找出错误根据错误大小给分,提出建议也给分。
有什么不明白的提出来。
我只想写一个最简单的键盘钩子函数。
还有我想问为什么KeyMsg一直在桌面创建?
当然调用他的程序是在MFC中的dialogue对话框程序中,在其cpp文件中我添加了
CHookDll TempHook;
void CKeyboardDlg::OnBnClickedOk()
{
TempHook.SetHook();
AfxMessageBox(L"钩子安装");
}void CKeyboardDlg::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
TempHook.EndHook();
AfxMessageBox(L"钩子删除");
OnCancel();
}// MyHook.cpp : 定义 DLL 应用程序的入口点。
//#include "stdafx.h"
#include "MyHook.h"
#include <fstream>
#include <ctype.h>
using namespace std;#ifdef _MANAGED
#pragma managed(push, off)
#endif//Dll句柄
HINSTANCE HinsDll;
//钩子句柄
HHOOK HinsHook;BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
 )
{
//调用dll的原因,如果是创建进程赋值当前dll句柄
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
//HINSTANCE == HMODULE
HinsDll = (HINSTANCE) hModule;  
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
    return TRUE;
}//钩子回调函数
LRESULT CALLBACK KeyProc(int nCode, WPARAM wParam, LPARAM lParam)
{
//描述钩子程序是否一定要处理这个消息 如果 nCode == HC_ACTION,那么钩子程序一定要处理这个消息,
//如果 nCode 的值小于零,则一定要跳过这个消息
//第30位是表示这个键的之前状态(previous tate)是否按下,0表按下,1表没有
if ((nCode == HC_ACTION) && (DWORD)lParam & 0x40000000)
{
//最高位是1,表示按下
short stateShift = GetKeyState(VK_SHIFT);  //shift状态
//如果最低位是1,则表示键是按下状态
int stateCapLK = ((GetKeyState(VK_CAPITAL) & 0x1) == 1);
char ch = 0;
//打开输出文件
ofstream output_file;
output_file.open("c://keyMsg.txt", ofstream::app);
if (!output_file)
{
MessageBox(NULL, TEXT("打开文件出错"), TEXT("错误"), MB_OK);
return 0;
}
if((stateShift & 0x8000) && (stateCapLK != 0))
{
ch = caseLower(wParam);
}
else if (((stateShift & 0x8000) == 0) && (stateCapLK != 0))
{
ch = caseUpper(wParam);
}
else if (((stateShift & 0x8000) == 0) && (stateCapLK == 0))
{
ch = caseLower(wParam);
}
else 
ch = caseUpper(wParam);
output_file<< ch;
output_file.close();
}
return CallNextHookEx(HinsHook, nCode, wParam, lParam);
}CHookDll::~CHookDll()
{
if (HinsHook != NULL)
UnhookWindowsHookEx(HinsHook);
}
void CHookDll::SetHook()
{
HinsHook = SetWindowsHookEx(WH_KEYBOARD, KeyProc, HinsDll, 0);
}
void CHookDll::EndHook()
{
if (HinsHook != NULL)
UnhookWindowsHookEx(HinsHook);
}
char caseLower(WPARAM param)
{
char ch_temp = MapVirtualKey(param, 2); 
return ch_temp;
}
char caseUpper(WPARAM param)
{
char ch_temp = MapVirtualKey(param, 2);
return toupper(ch_temp);
}#ifdef _MANAGED
#pragma managed(pop)
#endif

解决方案 »

  1.   

    KeyMsg一直在桌面创建
    什么意思啊?
      

  2.   

    output_file.open("c://keyMsg.txt", ofstream::app);
    改成
    output_file.open("c:\\keyMsg.txt", ofstream::app);
      

  3.   

    你这是全局钩子,什么都抓。
    如果想抓某个线程的,把线程id传进SetWindowsHookEx
      

  4.   

    就是我想创建的文本文档,作为输出用到。本来是应该在可执行文件的目录下创建的,但是我搞不懂为什么他会在桌面创建。是不是MFC对话框默认是在桌面执行?还是什么的?
    我搞不懂为什么会在桌面创建一个KeyMsg的文本文档。
      

  5.   

    这个不行。我试过了。我就搞不懂,这里我指定目录了已经,为什么还会在桌面创建这个文本文档?
    是不是真的跟我在MFC的对话框的实现的cpp中文件调用这个setHook有关系?
      

  6.   

    output_file.open("c://keyMsg.txt", ofstream::app);
    改成 
    output_file.open("c:\\keyMsg.txt", ofstream::app);
    我也遇到类似问题,头痛中
    我的驱动加载代码做成DLL,弄死提示找不到驱动文件,不做成DLL,就可以找到,郁闷死
    明明PATH已经是绝对路劲了,还提示找不到文件,人都疯了
      

  7.   

    我找到问题了是asicc码的问题。 改成c:\\\\keyMsg.txt这个就可以了
    转义字符问题!!!绝对路径的问题。