各位红五星大哥出来啊~~

解决方案 »

  1.   

    MapVirtualKey是个API函数。关于它的用法可以在 API函数的帮助中查到,我想就不用多说了。
    我只是想解释一下,我为什么要这样做的原因好了。  是这样的,我要做一个监视键盘的程序(就是木马中常用的那种功能),我找到了一个自称为不用Hook方法就可以实现拦截键盘的控件,我研究了半天。因为它用来拦截键盘有问题,有顺序错误(这还得了,作为一个木马出这样的错误,不是成了废物??当然我编的不是一个木马了!!呵呵),而且其中一处汇编调用导致了还不用在Win2000使用。所以我决定自己做了。
      我开始用DLL,SetWindowsHookEx(WH_KEYBOARD.....)结果不好 ,还要带一个动态连接库,真麻烦,上面的控件(叫KeySpy)就可以不用DLL。后来我发现SetWindowsHookEx(WH_KEYBOARD.....)这个函数不用放在DLL中也可以工作,于是高兴坏了。马上动手,等我编好以后,又发现了一个致命问题焦点不再自己身上的时候就得不到,还不如在窗体中用OnKeyDown呢!!浪费时间!!!(关于这个问题我没有仔细研究,如果那位大侠知道的话,请赐教,就是不用DLL的SetWindowsHookEx(WH_KEYBOARD....也能做键盘监视吗?),
      后来我又研究了一个例子,决定利用这例子的原理写一个控件(主要原理代码付后),也是用的SetWindowsHookEx,不过变成了这样的调用SetWindowsHookex(WH_JOURNALRECORD, KeyBoardHook, Hinstance, 0);就是WH_JOURNALRECORD这种类型的钩子,是用来监视系统事件的,而function KeyBoardHook(iCode: Integer; wParam: wParam;
      lParam: lParam): LRESULT; stdcall;中 lParam就是事件结构的指针了,哈哈。得到时间结构的指针不久可以判断了吗?
      于是就有:
      pMsg := pEventMsg(lParam); //pEventMsg是一个自定义的事件结构
                if ((pMsg.Message = WM_KEYDOWN) or (pMsg.Message = WM_SYSKEYDOWN)) then
                  PostMessage(OwnerHandle, WM_KEYSPY, pMsg.paramL, pMsg.paramH)    问题似乎解决了,我长出了一个口气,上面的pMsg.ParamL就是VirtualKey Code虚拟键码,就等于OnKeyDown中的Key那个参数。
      得到虚拟键码就好办了,然后我为了监视工作跟加一目了然,当然是把这个键码转换成字符串,比如键码91就得到WIN这个字符串(这个 WIN 让我吃尽苦头,后面会详细解释原因的),27就得到ESC....等等。工作太繁琐,那以前的那个KeySpy来看,哈哈,它定义了长的常量数组,都写好了,照搬过来。成了,这里我说明一下,先开始不知道那段汇编是干吗的,于是照搬。
        这段汇编  
      {asm
        in al, 60h
        mov Key, al
        end; }
        实际上是KeySpy用来监视键盘的核心,它用一个Timer去查询当前键盘中的扫描码,就是当前被按下的那些键,而我呢?弄巧成拙了,把它当成将虚拟键码转换成扫描码的过程,当然也可以这么用,因为当时这个键确实被按下了。后来我把KeySpy中的这段汇编给去掉了,改成我的MapVirtualKey函数,看它的定义--MapVirtualKey(虚拟键码,标志):扫描码; 一看就知道返回值是以虚拟键码为前提的。KeySpy一被这样改就变成了DoNothing控件。而我的控件可不是用这原理哦,嘿嘿,因为我在调用MapVirtualKey之前已经得到正确的虚拟键码了!!  关于Win的烦恼篇:
      (抱歉,有点灌水嫌疑,请正在看的朋友耐心点),用了SetWindowsHookex(WH_JOURNALRECORD, KeyBoardHook, Hinstance, 0);和MapVirtualKey蛮以为可以高枕无忧乐,98和2000都可以用,哈哈!!完事咯!!我马上编了一个例子来测试它,它工作的非常好。突然,我莫名其妙的按下了WIN键,再按其它的键,发现它已经失效了,就是只要我按下了WIN,这个钩子就不起作用了。我开始查错。调试查错。。(叮叮光光,修理它),还是不行,不论怎样避免都不行,看来是机制问题。没办法查帮助,现在看来帮助真是个好东西啊,打开帮助看WH_JOURNALRECORD这种HOOK的说明,下面引用引起这问题的一段帮助中的原文说明:
        If the user presses CTRL+ESC or CTRL+ALT+DEL during journal playback, the system stops the playback, unhooks the journal playback procedure, and posts a WM_CANCELJOURNAL message to the journaling application. 
        看明白了吧?只要用户按了CTRL+ESC or CTRL+ALT+DEL ,所有的journal playback 都会被UnHook掉,CTRL+ESC =WIN键,气死我了!!!
        哎,没办法,看来我在这条路上是死定了。。(后记:这个问题也已经被我解决,不过方法吗,不值得提倡和推广,所以就不拿出来丢丑了)
      

  2.   

    呵呵
    200分呀?
    100%的代码

    http://www.fcedu.org/school/001-root/site/FCEdu/LYSoft/projects/