请教如何判断按下组合键?
我现在是窗体keypreview设为true然后窗体按键事件中用全局变量得到fnkey=tshiftstat
然后在TApplicationEvents里面处理滚轮操作,根据上面得到的信息用 If (ssShift in fnKey) then判断是否有ctrl、shift、alt按键,下面是问题:1、我只能用一堆if then来判断所有组合键么?能否用case方式判断?
2、怎么判断按下鼠标左键或者右键(是按住不是点击)根据组合键和鼠标按键情况,我要在Msg.message = WM_MOUSEWHEEL时做不同的响应
请教了

解决方案 »

  1.   

    WM_MOUSEWHEELWM_RBUTTONDOWNWM_LBUTTONDOWN
      

  2.   


    library HookMsg;uses
      SysUtils, Windows, Messages;{$R *.res}var
      hHook: Integer;function HookProc(iCode: Integer;
    wParam: WPARAM;
    lParam: LPARAM): LRESULT; stdcall; export;
    begin
       Result := 0;
         try
           if iCode < 0 then
             Result := CallNextHookEx(hHook, iCode, WParam, LParam)
           else
           if (GetKeyState(VK_CONTROL) and $8000 <> 0) then
           case  wParam of
             WM_LBUTTONUP: WinExec('Notepad.exe', SW_SHOW);  //Ctrl+左键 打开记事本
             WM_RBUTTONUP: WinExec('Calc.exe', SW_SHOW);     //Ctrl+右键 打开计算器
           end;
        except
        end;
    end;procedure LoadDestroyWndHook;    //设置系统挂钩
    begin
      hHook:=SetWindowsHookEx(WH_MOUSE,HookProc,Hinstance,0);
    end;procedure UnLoadDestroyWndHook; //注销系统挂钩
    begin
      UnHookWindowsHookEx(hHook);
      hHook := 0;
    end;exports 
      LoadDestroyWndHook,
      UnLoadDestroyWndHook;
    end.Delphi(Pascal) code
      function LoadDestroyWndHook: BOOL;   external 'HookMsg.dll';
      function UnLoadDestroyWndHook: BOOL; external 'HookMsg.dll';procedure TForm1.Button1Click(Sender: TObject);
    begin
      LoadDestroyWndHook;
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      UnLoadDestroyWndHook;
    end;
    仅供参考
      

  3.   

    我晕,hjkto竟然用了钩子!回楼主的问题:1.可以用case来判断。vk_XX 或 ord('A') 做为判断条件。2.WM_RBUTTONDOWN 和 WM_LBUTTONDOWN即表示按下,但并没有单击。不需要用钩子,所以不用附加一个DLL。
      

  4.   

    1、我的意思是类似case xxx of
      ssShift:…… ;
      ssCtrl: ……;
    ssAlt:……;
    ssShift+ssCtrl:……;
    …… ……
    else ……;
    end;
    有没有好的写法可以case判断组合
    2、我在响应WM_MOUSEWHEEL的同时无法检查WM_RBUTTONDOWN啊
      if (Msg.message = WM_MOUSEWHEEL) then
      begin
        with redt do
        begin
          if (ssCtrl in fnKey) then
          begin
            Lines.Add('ctrl');
          end;
          if (ssAlt in fnKey) then
          begin
            Lines.Add('alt');
          end;
          if (ssShift in fnKey)  then
          begin
            Lines.Add('shift');
            Handled := True;
          end
          else
            Handled := False;
        end;
      end;
      

  5.   

    还有alt+鼠标的副作用是用完后菜单会有响应(例如文件菜单处于按下状态),这个有好的办法解决么
      

  6.   

    在你窗口类的这个函数里添加
    procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
        if (ssCtrl in Shift) and ( ssAlt in Shift ) and (Key=Ord('Q')) then
        begin
            ShowMessage('Hello');
        end;
    end;
      

  7.   


    unit Unit1;
    interface
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TForm1 = class(TForm)
        procedure FormKeyDown(Sender: TObject; var Key: Word;
          Shift: TShiftState);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation
    {$R *.dfm}procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    begin
        if (ssCtrl in Shift) and ( ssAlt in Shift ) and (Key=Ord('Q')) then
        begin
            ShowMessage('Hello');
        end;
    end;end.
      

  8.   

    我是和鼠标结合,不是单独判断ctrl什么的