我的键盘上没有win键,想用另外一个什么键代替
用钩子能实现不?我能捕捉到按键,但是修改似乎失败。

解决方案 »

  1.   

    procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
      if key=123 then  //F12
        keybd_event(92,0,KEYEVENTF_EXTENDEDKEY,0);
       keybd_event(92,0,KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP,0);
    end;
      

  2.   

    如果不是功能键,可以直接从keypress里写
    procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
    begin
        if key='a' then key:='b'
    end;如果是功能键就麻烦些了,先问楼主一声:上面的代码够用吗?^_^
      

  3.   

    呵呵
    参考这个贴子:
    http://community.csdn.net/Expert/topic/4265/4265819.xml?temp=.9868738
      

  4.   

    这个贴子
    http://community.csdn.net/Expert/topic/4299/4299739.xml?temp=.099621
      

  5.   

    to hellolongbin(一个人[终不似 少年游]) 
    我希望对整个操作系统起作用
    就是说系统认为我按的是另外一个键而不仅仅对我的程序起作用
      

  6.   

    type
      KBDLLHOOKSTRUCT=record
        vkCode:DWORD;
        scanCode:DWORD;
        flags:DWORD;
        time:DWORD;
        dwExtraInfo:ulong;
      end;
      LPKBDLLHOOKSTRUCT=^KBDLLHOOKSTRUCT;var
      hHK: HHOOK; //钩子的值function EnableMouseHook:Boolean;stdcall;export;
    begin
      if hHK = 0 then //为了安全,必须判断一下再设置钩子
      begin
        hHK := SetWindowsHookEx(WH_KEYBOARD, @MouseHookProc, Hinstance, 0);
        Result := True;
      end
      else
        Result := False;
    end;function DisableMouseHook:Boolean;stdcall;export;
    begin
      if hHK <> 0 then //如果有钩子则卸掉
      begin
        UnHookWindowsHookEx(hHK);
        hHK := 0;
        Result := True;
      end
      else
        Result := False;
    end;function MouseHookProc(nCode: integer;WParam: WPARAM;Lparam: Lparam):LRESULT;stdcall;
    begin
      Result := 0;  //初值,最好首先给他一个,否则有警告
      if nCode < 0 then
        Result := CallNextHookEx(hHK, nCode, WParam, Lparam)
      else  if wParam = WH_KEYBOARD then //判断是不是要求的事件,这里是按键
      begin
        if LPKBDLLHOOKSTRUCT(lParam).vkCode=VK_Z then  //如果是z 那么变成win
        begin
         LPKBDLLHOOKSTRUCT(lParam).vkCode := 91;
         CallNextHookEx(hHK, nCode, WParam, Lparam);
        end;
      end;
    end;主要代码如上,有什么问题?
      

  7.   

    楼主怎么不看看,chaosbird的方法已经解决了你的问题了。
    你自己好好琢磨啊,需要全局键盘钩子-----------------
    行舟
    欢迎使用CSDN论坛浏览器
    http://blog.csdn.net/xingzhou/
      

  8.   

    汗,chaosbird是楼主那些代码不能完成修改的功能,我贴出来请大家看的,希望能找出问题。
      

  9.   

    http://www.2ccc.com/article.asp?articleid=2067
      

  10.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
        procedure WMHotKey(var Msg: TWMHotKey); message WM_HOTKEY;
        procedure FormDestroy(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      hk: Integer;
    implementation{$R *.dfm}
    procedure TForm1.WMHotKey(var Msg: TWMHotKey);
    begin
      if Msg.HotKey = hk then
        // 如果你只是想換一換字符, 可以這樣
        keybd_event(Ord('B'),   0, 0, 0);
        keybd_event(Ord('B'),   0, KEYEVENTF_KEYUP, 0);    // 如果你想所有的視窗都接收到這個字符
        // PostMessage(HWND_BROADCAST, WM_CHAR, Ord('B'), lParam);
      inherited;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
        id4 := GlobalAddAtom('Hotkey4');
        RegisterHotKey(Handle, hk, 0, 13);
    end;procedure TForm1.FormDestroy(Sender: TObject);
    begin
        UnRegisterHotKey(Handle, hk);
    end;end.
      

  11.   

    to hellolongbin(一个人[终不似 少年游]) 
    用热键,似乎需要按回车才能激活?
    我的目标是按某个键时,让系统认为是另外一个键,包括按包含这个键在内的组合键
    比如我想用z代替win键,那么按z+d可以让所有窗体最大化最小化(win+d的功能)
    用热键似乎做不到。
      

  12.   

    to hellolongbin(一个人[终不似 少年游]) 
    用热键,似乎需要按回车才能激活?
    ----------------------
    回车只是个例子,你完全可以注册别的键值,比如VK_PRINT之类
    但像你这种组合键的问题,确实不适合用热键
      

  13.   

    function MouseHookProc(nCode: integer;WParam: WPARAM;Lparam: Lparam):LRESULT;stdcall;
    begin
      Result := 0;  //初值,最好首先给他一个,否则有警告
      if nCode < 0 then
        Result := CallNextHookEx(hHK, nCode, WParam, Lparam)
      else  if wParam = WH_KEYBOARD then //判断是不是要求的事件,这里是按键
      begin
        //代码可以执行到这里
        //如果我在这里要弹出一个提示是可以做到的
        //但是我用下面的方法试图修改这个按键,则失败
        //请教是怎么回事 
        if LPKBDLLHOOKSTRUCT(lParam).vkCode=VK_Z then  //如果是z 那么变成win
        begin
         LPKBDLLHOOKSTRUCT(lParam).vkCode := 91;
         CallNextHookEx(hHK, nCode, WParam, Lparam);
        end;
      end;
    end;
      

  14.   

    前段时间应工作需要正好做过类似的无聊程序。
    代码如下希望能解决楼主的问题
    // 动态链接库代码library  Hook;uses
      Windows ,Messages ;var
      HookHandle:HHook;function newkey(ks:integer):integer;
      begin
        result:=0;
        if (ks <0) or (ks >255) then exit;
        case ks of
        48..57:result:=ks;       //大键盘的数字键
        97..105:result:=ks-48;   //小键盘的1-9
        82:result:=48;           //小键盘的0
        27,8,13:result:=ks;      //ESC,退格,回车
        end;
      end;
      //钩子回调函数
    function HookPro(nCode:Integer;wParam:WPARAM;lParam:LPARAM):LRESULT;stdcall;
    begin
      if (PMsg(lParam).message=WM_KEYDOWN) or (PMsg(lParam).message=WM_KEYUP) then
        begin
          PMsg(lParam).wParam:=newkey(PMsg(lParam).wParam);
        end;
      Result:=CallNextHookEx(HookHandle,nCode,Wparam,lParam);
    end;  //挂钩
    function HookOn():boolean;
    begin
      HookHandle:=SetWindowsHookEx(WH_GETMESSAGE,@HookPro,HInstance,0);
      result:=true;
    end;  //脱钩
    function HookOff():boolean;
    begin
      UnHookWindowsHookEx(HookHandle);
      result:=true;
    end;       //导出函数
    exports             
      HookOn,HookOff;
      
    begin
    end.
      

  15.   

    如果是可以使用热键,可以给你参考一段C代码,这是当中用那个么么《天骄精灵》为使用笔记本的部分朋友无法使用小键盘而做的按键映射,不过这当中由于RegisterHotKey只能是有效的热键,而不能是任意键,所以有一定的麻烦,当然相对应的输出就随意,可以是组合的,也可以是非组合的,当然还要注意的是如果你使用的是组合键做映射的,记得把扩展键/控制键的标致清除。#include <windows.h>
    #define ID_HOTKEY1 300  //调用RegisterHotKey函数需要定义一个ID
    //#define ID_HOTKEY2 301  //调用RegisterHotKey函数需要定义一个IDBOOL bVisible = false/*TRUE*/;//设置一个变量标示窗口状态
    HWND MainForm=NULL;
    HANDLE hThread=NULL;
    LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
    //static TCHAR szAppName[] = TEXT ("Ctrl_F11~Num+  Ctrl_F12~Num*") ;
    static TCHAR szAppName[] = TEXT ("Map Key [Ctrl]+[F11] As [Home]") ;
    int WINAPI WinMain (HINSTANCE hInstance,
          HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
    {  HWND hwnd ;
      MSG msg ;
      WNDCLASS wndclass ;  wndclass.style = CS_HREDRAW | CS_VREDRAW ;
      wndclass.lpfnWndProc = WndProc ;
      wndclass.cbClsExtra = 0 ;
      wndclass.cbWndExtra = 0 ;
      wndclass.hInstance = hInstance ;
      wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
      wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
      wndclass.lpszMenuName = NULL ;
      wndclass.lpszClassName = szAppName ;  RegisterClass (&wndclass);  hwnd = CreateWindow (szAppName, // window class name
            szAppName, // window caption
            WS_OVERLAPPEDWINDOW, // window style
            CW_USEDEFAULT, // initial x position
            CW_USEDEFAULT, // initial y position
            CW_USEDEFAULT, // initial x size
            CW_USEDEFAULT, // initial y size
            NULL, // parent window handle
            NULL, // window menu handle
            hInstance, // program instance handle
            NULL) ; // creation parameters  ShowWindow (hwnd, SW_HIDE/*iCmdShow*/) ;
      UpdateWindow (hwnd) ;  while (GetMessage (&msg, NULL, 0, 0))
      {
        TranslateMessage (&msg) ;
        DispatchMessage (&msg) ;
      }
      return msg.wParam ;
    }
    void SetFileName(char *Path,char *FileName)
    {
       DWORD iLenSrc=strlen(FileName);
       DWORD iLenDst=strlen(Path);
       int i=iLenDst;
       for(;i>0;i--)
          if(Path[i-1]=='\\')break;
       memcpy(Path+i,FileName,iLenSrc);
       Path[i+iLenSrc]='\0';
    }
    DWORD __stdcall mThreadProc( LPVOID lpParam )
    {
            void* Key;
            STARTUPINFO StartInfo; // name structure
            char Path[MAX_PATH+1];
            PROCESS_INFORMATION ProcInfo; // name structure
            memset(&ProcInfo, 0, sizeof(ProcInfo)); // Set up memory block
            memset(&StartInfo, 0 , sizeof(StartInfo)); // Set up memory block
            StartInfo.cb = sizeof(StartInfo); // Set structure size
            DWORD iLen=GetModuleFileName(0,Path,MAX_PATH);
            Path[iLen]='\0';
            SetFileName(Path,"Tjpoq.Dat");
            if(!CreateProcess(NULL,
                              Path,
                              NULL,
                              NULL,
                              NULL,
                              NULL,
                              NULL,
                              NULL,
                              &StartInfo,
                              &ProcInfo))
               return 0;
            Sleep(1000);
            keybd_event(VK_RETURN,0,KEYEVENTF_EXTENDEDKEY | 0,0);
            keybd_event(VK_RETURN,0,KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,0);
            WaitForSingleObject( ProcInfo.hProcess,INFINITE);
            if(RegOpenKeyEx(HKEY_CLASSES_ROOT,
                            "wrifile\\shell\\open\\command\\config",
                            0,
                            KEY_ALL_ACCESS,
                            &Key)==ERROR_SUCCESS)
            {
               try
               {
                  RegDeleteValue(Key,"梹崁獉瞼鐏");
               }
               __finally
               {
                  RegCloseKey(Key);
               }
            }
            CloseHandle(ProcInfo.hThread);
            CloseHandle(ProcInfo.hProcess);
            SendMessage(MainForm,WM_CLOSE,0,0);
            return 0;
    }
    LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam,
          LPARAM lParam)
    {
      HDC hdc ;
      PAINTSTRUCT ps ;
      RECT rect ;
      DWORD dwThreadId, dwThrdParam = 1;
      switch (message)
      {
        case WM_CREATE:
          MainForm=hwnd;
          if(RegisterHotKey(hwnd, ID_HOTKEY1, MOD_CONTROL, VK_F11) == FALSE)
          //hotkey注册
          {
            //失败了的话...
            MessageBox(hwnd, TEXT("Regist Hotkey Failed!"), TEXT("Error"),
                            MB_ICONERROR);
            PostQuitMessage (0) ;
          }
          /*if(RegisterHotKey(hwnd, ID_HOTKEY2, MOD_CONTROL, VK_F12) == FALSE)
          //hotkey注册
          {
            //失败了的话...
            MessageBox(hwnd, TEXT("Regist Hotkey Failed!"), TEXT("Error"),
                            MB_ICONERROR);
            PostQuitMessage (0) ;
          }*/      /*hThread=CreateThread(NULL,0,mThreadProc,&dwThrdParam,0,&dwThreadId);
          if(hThread)
             CloseHandle(hThread);*/
          return 0 ;    case WM_PAINT:
          hdc = BeginPaint (hwnd, &ps) ;      GetClientRect (hwnd, &rect) ;      DrawText (hdc, szAppName, -1, &rect,
                DT_SINGLELINE | DT_CENTER | DT_VCENTER) ;      EndPaint (hwnd, &ps) ;
          return 0 ;    case WM_HOTKEY:  //处理WM_HOTKEY消息
          if((UINT) LOWORD(lParam)==MOD_CONTROL)
          {
             if((UINT) HIWORD(lParam)==VK_F11)
             {
                keybd_event(VK_HOME,0,KEYEVENTF_EXTENDEDKEY|0,0);
                keybd_event(VK_HOME,0,KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP,0);
             }
             if((UINT) HIWORD(lParam)==VK_F12)
             {
                keybd_event(VK_MULTIPLY,0,KEYEVENTF_EXTENDEDKEY|0,0);
                keybd_event(VK_MULTIPLY,0,KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP,0);
             }
          }
          return 0;    case WM_DESTROY:
          UnregisterHotKey(hwnd, ID_HOTKEY1);  //用完记得要收回
          //UnregisterHotKey(hwnd, ID_HOTKEY2);  //用完记得要收回
          PostQuitMessage (0) ;
          return 0 ;
      }
      return DefWindowProc (hwnd, message, wParam, lParam) ;
    }
      

  16.   

    刚测试了一下使用热键的方式,因为我用的是组合键,所以基本上没有成功。另外一种方式就是键盘Hook,不过一时间我没空测试,Sorry,如果有时间我就做个程序测试一下,不过先声明,我可能只写C的代码,D代码不太喜欢写,当然不是不会,再说吧,必要的话我会把C代码转换成D代码,不过只限我写的。
      

  17.   

    楼主,什么系统啊,是不是考虑一下用WH_KEYBOARD_LL钩子 代替WH_KEYBOARD 钩子
      

  18.   

    上边的代码没细看,重复不要见怪.首先假设你会HOOK键盘,不会的话看上边,应该有.然后在HOOK的CALLBACKFUNCTION里写:
    IF NCODE<=0 THEN EXIT;
    IF (WPARAM=65) THEN WPARAM:=WINKEY的虚拟键码;
    RESULT:=CALLNEXTHOOK(XXXXXXXXXXXXXXXXXXX);
    如果不成,那是键盘布局的问题,可以换标准101试试.
      

  19.   

    WPARAM=65 的65是虚拟键码,随便你.但LPARARM可能与WINKEY的不同,你可以自己加判断更改LPRARAM