delphi 截取 pos_用Delphi截取键盘输入

delphi 截取 pos

Consider for a moment creation of some fast arcade game. All the graphics are displayed, let's say, in a TPainBox. TPaintBox is unable to receive the input focus — no events are fired when the user presses a key; we cannot intercept cursor keys to move our battleship. Delphi help!

考虑一下创建一些快速街机游戏。 假设所有图形都显示在TPainBox中。 TPaintBox无法接收输入焦点-用户按下键时不会触发任何事件; 我们无法拦截光标键来移动我们的战舰。 德尔福帮忙!

截取键盘输入 ( Intercept Keyboard Input )

Most Delphi applications typically handle user input through specific event handlers, those that enable us to capture user keystrokes and process mouse movement.

大多数Delphi应用程序通常通过特定的事件处理程序来处理用户输入,这些事件处理程序使我们能够捕获用户的击键并处理鼠标的移动

We know that focus is the ability to receive user input through the mouse or keyboard. Only the object that has the focus can receive a keyboard event. Some controls, such as TImage, TPaintBox, TPanel, and TLabel cannot receive focus. The primary purpose of most graphic controls is to display text or graphics.

我们知道焦点是通过鼠标或键盘接收用户输入的能力。 只有具有焦点对象才能接收键盘事件 。 某些控件(例如TImage,TPantBox,TPanel和TLabel)无法获得焦点。 大多数图形控件的主要目的是显示文本或图形。

If we want to intercept keyboard input for controls that cannot receive the input focus we'll have to deal with Windows API, hooks, callbacks and messages.

如果我们想截获无法接收输入焦点的控件的键盘输入,则必须处理Windows API,挂钩,回调和消息

窗户挂钩 ( Windows Hooks )

Technically, a "hook" function is a callback function that can be inserted in the Windows message system so an application can access the message stream before other processing of the message takes place. Among many types of windows hooks, a keyboard hook is called whenever the application calls the GetMessage() or PeekMessage() function and there is a WM_KEYUP or WM_KEYDOWN keyboard message to process.

从技术上讲,“挂钩”函数是一种回调函数,可以插入Windows消息系统中,以便应用程序可以在对消息进行其他处理之前访问消息流。 在许多类型的Windows挂钩中,每当应用程序调用GetMessage()或PeekMessage()函数时,就会调用键盘挂钩,并且有WM_KEYUP或WM_KEYDOWN键盘消息要处理。

To create a keyboard hook that intercepts all keyboard input directed to a given thread, we need to call SetWindowsHookEx API function. The routines that receive the keyboard events are application-defined callback functions called hook functions (KeyboardHookProc). Windows calls your hook function for each keystroke message (key up and key down) before the message is placed in the application's message queue. The hook function can process, change or discard keystrokes. Hooks can be local or global.

若要创建一个键盘挂钩来拦截指向给定线程的所有键盘输入,我们需要调用SetWindowsHookEx API函数。 接收键盘事件的例程是应用程序定义的回调函数,称为挂钩函数(KeyboardHookProc)。 在将消息放入应用程序的消息队列中之前,Windows会为每个按键消息(向上键和向下键)调用挂钩函数。 挂钩函数可以处理,更改或放弃击键。 挂钩可以是本地的也可以是全局的。

The return value of SetWindowsHookEx is a handle to the hook just installed. Before terminating, an application must call the UnhookWindowsHookEx function to free system resources associated with the hook.

SetWindowsHookEx的返回值是刚安装的挂钩的句柄。 在终止之前,应用程序必须调用UnhookWindowsHookEx函数以释放与该挂钩关联的系统资源。

键盘挂钩示例 ( Keyboard Hook Example )

As a demonstration of keyboard hooks, we'll create a project with graphical control that can receive key presses. TImage is derived from TGraphicControl, it can be used as a drawing surface for our hypothetical battle game. Since TImage is unable to receive keyboard presses through standard keyboard events we'll create a hook function that intercepts all keyboard input directed to our drawing surface.

作为键盘挂钩的演示,我们将创建一个带有图形控件的项目,该项目可以接收按键。 TImage是从TGraphicControl派生的,可以用作我们假设的战斗游戏的绘图表面。 由于TImage无法通过标准的键盘事件接收键盘按下的信息,因此我们将创建一个钩子函数,该钩子函数将拦截指向图形表面的所有键盘输入。

TImage处理键盘事件 ( TImage Processing Keyboard Events )

Start new Delphi Project and place one Image component on a form. Set Image1.Align property to alClient. That's it for the visual part, now we have to do some coding. First, we'll need some global variables:

启动新的Delphi Project并将一个Image组件放置在表单上。 将Image1.Align属性设置为alClient。 视觉部分就是这样,现在我们必须进行一些编码。 首先,我们需要一些全局变量


var
  Form1: TForm1;
  KBHook: HHook; {this intercepts keyboard input}
  cx, cy : integer; {track battle ship's position}
  {callback's declaration}
  function KeyboardHookProc(Code: Integer; WordParam: Word; LongParam: LongInt): LongInt; stdcall;
implementation
...

To install a hook, we call SetWindowsHookEx in the OnCreate event of a form.

要安装钩子,我们在窗体的OnCreate事件中调用SetWindowsHookEx。


procedure TForm1.FormCreate(Sender: TObject) ;
begin
 {Set the keyboard hook so we  can intercept keyboard input}
 KBHook:=SetWindowsHookEx(WH_KEYBOARD,
           {callback >} @KeyboardHookProc,
                          HInstance,
                          GetCurrentThreadId()) ;
 {place the battle ship in  the middle of the screen}
 cx := Image1.ClientWidth div 2;
 cy := Image1.ClientHeight div 2;
 Image1.Canvas.PenPos := Point(cx,cy) ;
end;

To free system resources associated with the hook, we must call the UnhookWindowsHookEx function in the OnDestroy event:

要释放与挂钩相关的系统资源,我们必须在OnDestroy事件中调用UnhookWindowsHookEx函数:


procedure TForm1.FormDestroy(Sender: TObject) ;
begin
  {unhook the keyboard interception}
  UnHookWindowsHookEx(KBHook) ;
end;

The most important part of this project is the KeyboardHookProc callback procedure used to process keystrokes.

该项目最重要的部分是用于处理击键的KeyboardHookProc回调过程


function KeyboardHookProc(Code: Integer; WordParam: Word; LongParam: LongInt) : LongInt;
begin
 case WordParam of
  vk_Space: {erase battle ship's path}
   begin
    with Form1.Image1.Canvas do
    begin
     Brush.Color := clWhite;
     Brush.Style := bsSolid;
     Fillrect(Form1.Image1.ClientRect) ;
    end;
   end;
  vk_Right: cx := cx+1;
  vk_Left: cx := cx-1;
  vk_Up: cy := cy-1;
  vk_Down: cy := cy+1;
 end; {case}
 If cx < 2 then cx := Form1.Image1.ClientWidth-2;
 If cx > Form1.Image1.ClientWidth -2 then cx := 2;
 If cy < 2 then cy := Form1.Image1.ClientHeight -2 ;
 If cy > Form1.Image1.ClientHeight-2 then cy := 2;
 with Form1.Image1.Canvas do
 begin
  Pen.Color := clRed;
  Brush.Color := clYellow;
  TextOut(0,0,Format('%d, %d',[cx,cy])) ;
  Rectangle(cx-2, cy-2, cx+2,cy+2) ;
 end;
 Result:=0;
{To prevent Windows from passing the keystrokes  to the target window, the Result value must  be a nonzero value.}
end;

That's it. We now have the ultimate keyboard processing code.

而已。 现在,我们有了最终的键盘处理代码。

Note just one thing: this code is in no way restricted to be used only with TImage.

仅需注意一件事:此代码绝不限于仅与TImage一起使用。

The KeyboardHookProc function serves as a general KeyPreview & KeyProcess mechanism.

KeyboardHookProc函数用作常规的KeyPreview和KeyProcess机制。

翻译自: https://www.thoughtco.com/intercepting-keyboard-input-1058465

delphi 截取 pos

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值