哈哈,什么就是Key:=96,晕倒,不要误人子弟好吗?
这个的意思是从60H(60端口好像就是键盘端口?自己查查资料吧。)端口读入一个字符,然后把读入的字符变成Byte给Key即可。

解决方案 »

  1.   

    翻译成Pascal就是:
    Key:=ord(GetChar())之类的啊。
      

  2.   

    Delphi中好像没有GetChar这个函数!
      

  3.   

    in al, 60h 是从60H端口读入一个字节到AL寄存器,
    mov Key, al 是把AL寄存器中的值送到Key变量中。
    连起来就是从60H端口读入字节送到Key中。
      

  4.   

    你要怎么解决?翻译成PASCAL?
    这是直接操纵端口的,恐怕很难翻成PASCAL吧。
      

  5.   

    这个问题我也解决不了了,因为我也碰到过,至今没辙。
    在WIN2000下碰到IN这类汇编指令,会报特权指令什么的错。
    难道在2000下IN算特权指令?应该不会吧。搞不懂!
      

  6.   

    这个问题我已经解决了,可以用MapVirtualKey这个函数代替它的转码功能,也可以用了。
      

  7.   

    summernightrain(夏夜雨) ,那把你转换后的代码贴出来大家好学习学习啊!
      

  8.   

    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键,气死我了!!!
        哎,没办法,看来我在这条路上是死定了。。(后记:这个问题也已经被我解决,不过方法吗,不值得提倡和推广,所以就不拿出来丢丑了)
    付的源码:
    (请在这方面有经验的朋友一定要无私的奉献一下,共同进步嘛!!)
    {*************************************************************}
    {            TExKeySpy Component for Delphi 5.0               }
    { Version:   1.0                                              }
    { Author:    Xuxing                                           }
    {            ?                                               }
    { E-Mail:    [email protected];[email protected]             }
    { Created:   August, 22, 2001                                 }
    { Modified:  August, 22, 2001                                 }
    { Legal:     Copyright (c) 1999 by Xuxing from Wuhan China    }
    {*************************************************************}   
    unit ExKeySpy;interfaceuses
    {$IFDEF WIN32}Windows, {$ELSE}WinTypes, WinProcs, {$ENDIF}
      SysUtils, Controls, Classes, Messages, Forms, Dialogs;
    const
      WM_KEYSPY = WM_USER + 20;
      LowButtonName: array[1..88] of PChar = ('--Esc', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '0', '-', '=', '--BkSp', '--Tab', 'q', 'w', 'e', 'r', 't',
        'y', 'u', 'i', 'o', 'p', '[', ']', '--Enter', '--Ctrl', 'a',
        's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '''', '`',
        '--LShift Down', '\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',',
        '.', '/', '--RShift Down', '--Gray*', '--Alt', '--Space',
        '--CapsLock', '--F1', '--F2', '--F3', '--F4', '--F5',
        '--F6', '--F7', '--F8', '--F9', '--F10',
        '--NumLock', '--ScrollLock', '--Home', '--Up',
        '--PgUp', '--Gray-', '--Left', '5', '--Right',
        '--Gray+', '--End', '--Down', '--PgDown', '--Ins',
        '--Del', '--LShift Up', '--RShift Up',
        '--Unknown', '--F11', '--F12');  HiButtonName: array[1..88] of PChar = ('--Esc', '!', '@', '#', '$', '%', '^', '&', '*', '(',
        ')', '_', '+', '--BkSp', '--Tab', 'Q', 'W', 'E', 'R', 'T',
        'Y', 'U', 'I', 'O', 'P', '{', '}', '--Enter', '--Ctrl', 'A',
        'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
        '--LShift Down', '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<',
        '>', '?', '--RShift Down', '--Gray*', '--Alt', '--Space',
        '--CapsLock', '--F1', '--F2', '--F3', '--F4', '--F5',
        '--F6', '--F7', '--F8', '--F9', '--F10',
        '--NumLock', '--ScrollLock', '--HomeX', '--Up',
        '--PgUp', '--Gray-', '--Left', '5', '--Right',
        '--Gray+', '--End', '--Down', '--PgDown', '--Ins',
        '--Del', '--LShift Up', '--RShift Up',
        '--Unknown', '--F11', '--F12');
    type
      TEventMsg = packed record
        Message: UINT;
        paramL: UINT;
        paramH: UINT;
        time: DWORD;
        hwnd: HWND;
      end;
      pEventMsg = ^TEventMsg;
    type
      TOnGetKey = procedure(Sender: TObject; Key: Byte; KeyStr: string) of object;
      TExKeySpy = class(TComponent)
      private
        FEnabled: Boolean;
        FOwnerWin: THandle;
        FOnGetKey: TOnGetKey;
        FForm: TForm;
        FOldFormMethod: TWndMethod;
        procedure WM_GETKEY(var Message: TMessage);
        procedure Win_Proc(var Message: TMessage);
        procedure SetEnabled(Value: Boolean);
        { Private declarations }
      protected
        { Protected declarations }
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
        property Active: Boolean read FEnabled write SetEnabled;
        { Public declarations }
      published
        property OnGetKey: TOnGetKey read FOnGetKey write FOnGetKey;
        { Published declarations }
      end;
    var
      hNextHookProc: hHook;
      OwnerHandle: Thandle;
      Count: Cardinal;
    procedure Register;implementationprocedure Register;
    begin
      RegisterComponents('WalkSlowly', [TExKeySpy]);
    end;{ TExKeySpy }constructor TExKeySpy.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      FEnabled := False;
      FOwnerWin := 0;
      FForm := TForm(AOwner);
      if FForm <> nil then
        begin
          FOldFormMethod := FForm.WindowProc;
          OwnerHandle := FForm.Handle;
          FForm.WindowProc := Win_Proc;
        end;
    end;destructor TExKeySpy.Destroy;
    begin
      inherited Destroy;
      if FEnabled then
        begin
          UnHookWindowsHookEx(hNextHookProc);
          hNextHookProc := 0;
        end;
    end;function KeyBoardHook(iCode: Integer; wParam: wParam;
      lParam: lParam): LRESULT; stdcall;
    const _KeyPressMask = $80000000;
    var
      pMsg: PEventMsg;
      recOK: Integer;
    begin
      recOK := 1;
      Result := 0;  if iCode < 0 then
        Result := CallNextHookEx(hNextHookProc, iCode, wParam, lParam)
      else
        if iCode = HC_SYSMODALON then
          recOK := 0
        else
          if iCode = HC_SYSMODALOFF then
            recOK := 1
          else
            if ((recOK > 0) and (iCode = HC_ACTION)) then
              begin
                pMsg := pEventMsg(lParam);
                if ((pMsg.Message = WM_KEYDOWN) or (pMsg.Message = WM_SYSKEYDOWN)) then
                  PostMessage(OwnerHandle, WM_KEYSPY, pMsg.paramL, pMsg.paramH)          end;
    end;procedure DisableKeyHook;
    begin
      UnHookWindowsHookEx(hNextHookProc);
      hNextHookProc := 0;
    end;function EnableKeyHook: Boolean;
    begin
      Result := False;
      if hNextHookProc <> 0 then Exit;
      hNextHookProc := SetWindowsHookex(WH_JOURNALRECORD, KeyBoardHook, Hinstance, 0);
      Result := hNextHookProc <> 0;
    end;procedure TExKeySpy.SetEnabled(Value: Boolean);
    begin
      if Value <> FEnabled then
        begin
          FEnabled := Value;
          if FEnabled then
            EnableKeyHook
          else
            DisableKeyHook;
        end;
    end;procedure TExKeySpy.Win_Proc(var Message: TMessage);
    begin
      if (csDesigning in ComponentState) then
        FOldFormMethod(Message)
      else
        case Message.Msg of
          WM_KEYSPY: WM_GETKEY(Message);
        else
          FOldFormMethod(Message);
        end;
    end;procedure TExKeySpy.WM_GETKEY(var Message: TMessage);
    var
      Key, OldKey: Byte;
      KeyStr: string;
      Point: TPoint;
    begin
      GetCursorPos(Point);  Key := Message.WParam;
      OldKey := Key;
      
     {asm
         in al, 60h
         mov Key, al  //这就是那一段让人头疼了一段时间的汇编
      end; }
      Key := MapVirtualKey(Key, 0);  if Key = 91 then //处理WIN健
        begin
          //省略若干字
        end;  if Key = 170 then
        Key := 84;
      if Key = 182 then
        Key := 85;
      if Key = 250 then
        Key := 186;  if Key <= 88 then
        begin
          if GetKeyState(VK_Shift) < 0 then
            KeyStr := StrPas(HiButtonName[Key])
          else
            KeyStr := StrPas(LowButtonName[Key]);
          if (GetKeyState(vk_Capital) = 1) and (Length(KeyStr) = 1) then
            KeyStr := UpperCase(KeyStr);
        end
      else
        begin
          if (Key - 128 > 0) and (Key - 128 < 88) then
            begin
              if GetKeyState(VK_Shift) < 0 then
                KeyStr := StrPas(HiButtonName[Key - 128])
              else
                KeyStr := StrPas(LowButtonName[Key - 128]);
              if (GetKeyState(vk_Capital) = 1) and (Length(KeyStr) = 1) then
                KeyStr := UpperCase(KeyStr);
            end;
        end;  if (GetKeyState(VK_NUMLOCK) = 1) and (OldKey >= 96) and (OldKey <= 105) then
        KeyStr := Inttostr(OldKey - 96);  FOnGetKey(Self, Key, KeyStr);
    end;end.
      

  9.   

    上面的程序原理就是用的Hook啊!!你看,有SetWindowsHookEx这个函数!!