Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何在所有其他应用程序之上监视键盘,然后将其他键发送给它们_Delphi_Keyboard Events_Delphi 2006 - Fatal编程技术网

Delphi 如何在所有其他应用程序之上监视键盘,然后将其他键发送给它们

Delphi 如何在所有其他应用程序之上监视键盘,然后将其他键发送给它们,delphi,keyboard-events,delphi-2006,Delphi,Keyboard Events,Delphi 2006,我正在基于一台运行Win7的旧计算机构建一个多媒体控制台 我想用数字键盘控制播放器。 我无法使用常用媒体控制设备,因为它们只响应windows media player。我将使用KVM播放器、Winamp和其他。因此,每一个都有自己的一套键盘快捷键,用于播放、暂停、前进、音量等 为此,我正在考虑构建一个Delphi应用程序,该应用程序检测前台应用程序,并从数据库获取该应用程序使用的快捷方式 当我使用数字键盘(普通遥控器的大小)并按5播放时,如果我使用Winamp,我的应用程序可以检测到它并向操作

我正在基于一台运行Win7的旧计算机构建一个多媒体控制台

我想用数字键盘控制播放器。 我无法使用常用媒体控制设备,因为它们只响应windows media player。我将使用KVM播放器、Winamp和其他。因此,每一个都有自己的一套键盘快捷键,用于播放、暂停、前进、音量等

为此,我正在考虑构建一个Delphi应用程序,该应用程序检测前台应用程序,并从数据库获取该应用程序使用的快捷方式

当我使用数字键盘(普通遥控器的大小)并按
5
播放时,如果我使用Winamp,我的应用程序可以检测到它并向操作系统发送
p
键,如果我使用Media Player Classic,则发送
Space


我应该使用哪些功能首先抓取按下的键,然后发送另一个键?

解决方案的一部分是使用键盘挂钩()捕获特殊的组合键或单个键,然后使用该功能发送(替换)另一次击键

尝试此示例代码,它截取
VK\u UP
键并发送一个S

var
hhk:HHOOK;
函数CBT_FUNC(nCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;
类型
PKBDLLHOOKSTRUCT=^TKBDLLHOOKSTRUCT;
TKBDLLHOOKSTRUCT=记录
vkCode:基数;
扫描码:基数;
旗帜:红衣主教;
时间:红衣主教;
dwextranfo:红衣主教;
结束;
PKeyboardLowLevelHookStruct=^TKeyboardLowLevelHookStruct;
TKeyboardLowLevelHookStruct=TKBDLLHOOKSTRUCT;
变量
LKBDLLHOOKSTRUCT:PKeyboardLowLevelHookStruct;
开始
案例代码
HC_行动:
开始
LKBDLHookStruct:=PKeyboardLowLevelHookStruct(LPRAM);
如果(LKBDLLHOOKSTRUCT^.vkCode=VK_UP),则
开始
如果(wParam=WM\u-KEYUP)或(wParam=WM\u-SYSKEYUP),则
keybd_事件(Ord('S'),0,KEYEVENTF_KEYUP,0)
其他的
keybd_事件(Ord('S'),0,0,0);
出口(1)//吃钥匙
结束;
结束;
结束;
结果:=CallNextHookEx(hhk、nCode、wParam、lParam);
结束;
程序初始化钩子();
开始
hhk:=SetWindowsHookEx(WH_KEYBOARD_LL,@CBT_FUNC,0,0);
如果hhk=0,则为r;
结束;
程序KillHook();
开始
如果(hhk 0)那么
UnhookWindowsHookEx(hhk);
结束;
初始化
InitHook();
定稿
基尔胡克();
结束。

在使用这种钩子之前,请记住阅读文档,特别是本节。

据我所知。很久以前我就用它编写了一些小应用程序。不幸的是,在一次磁盘故障后,它们都消失了。Windows Media Player也有API,不知道KMPlayer是怎么回事(如果你指的是KMPlayer,这是你问题中的一个输入错误)。我之所以指出这一点,是因为我认为实现这些API来通知播放状态的更改,而不是这种巫毒风格的键重定向,会更好。
WH\u-KEYBOARD\u-LL
KEYBOARD-hook:监视比
WH\u-KEYBOARD\u-LL
hook更有效,更可取。MSDN也这么说。@Remy此用例中原始输入的优点是什么?@DavidHeffernan:MSDN还声明:“调试挂钩无法跟踪此类低级键盘挂钩。如果应用程序必须使用低级钩子,它应该在专用线程上运行钩子,该线程将工作传递给工作线程,然后立即返回。在应用程序需要使用低级钩子的大多数情况下,它应该监视原始输入。这是因为原始输入可以比低级钩子更有效地异步监视针对其他线程的鼠标和键盘消息。”哇,它在delphi 7中经过一点修改(将其放在一个单元中,添加一些uses子句,使其成为dll,将Exit(1)替换为结果:=1;Exit;语法)
var
 hhk: HHOOK;


function CBT_FUNC(nCode: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;


type
  PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT;
  TKBDLLHOOKSTRUCT = record
    vkCode: cardinal;
    scanCode: cardinal;
    flags: cardinal;
    time: cardinal;
    dwExtraInfo: Cardinal;
  end;
  PKeyboardLowLevelHookStruct = ^TKeyboardLowLevelHookStruct;
  TKeyboardLowLevelHookStruct = TKBDLLHOOKSTRUCT;

var
 LKBDLLHOOKSTRUCT: PKeyboardLowLevelHookStruct;
begin
   case nCode of
     HC_ACTION:
     begin
       LKBDLLHOOKSTRUCT := PKeyboardLowLevelHookStruct(lParam);
        if (LKBDLLHOOKSTRUCT^.vkCode = VK_UP)  then
        begin

          if (wParam=WM_KEYUP) or (wParam=WM_SYSKEYUP)then
           keybd_event( Ord('S'), 0, KEYEVENTF_KEYUP, 0)
          else
           keybd_event( Ord('S'), 0, 0, 0);

          Exit(1); //eat the key
        end;
     end;
   end;
  Result := CallNextHookEx(hhk, nCode, wParam, lParam);
end;

Procedure InitHook();
begin
  hhk := SetWindowsHookEx(WH_KEYBOARD_LL, @CBT_FUNC, 0, 0);
  if hhk=0 then RaiseLastOSError;
end;


Procedure KillHook();
begin
  if (hhk <> 0) then
    UnhookWindowsHookEx(hhk);
end;


initialization
  InitHook();

finalization
  KillHook();
end.