用delphi截取键盘输入

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

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

Delphi Keyboard Hook for TImage

截取键盘输入

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

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

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

Windows钩子

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

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

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

键盘挂钩示例

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

timage处理键盘事件

启动新的Delphi项目,并在表单上放置一个图像组件。设置Image1。将属性与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 ...

要安装钩子,我们在表单的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;

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

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

该项目最重要的部分是用于处理击键的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;

就这样。我们现在有了最终的键盘处理代码。

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

KeyboardHookProc功能用作通用的KeyPreview和KeyProcess机制。

  • 发表于 2021-09-15 03:46
  • 阅读 ( 156 )
  • 分类:编程

你可能感兴趣的文章

如何在mac上截图

...音,屏幕截图就会以.png文件的形式出现在你的桌面上。 截取部分屏幕截图 要拍摄屏幕的一部分截图,请按Command+Shift+4。鼠标光标将变成十字头图标。单击并拖动以选择屏幕的一部分。释放鼠标按钮,屏幕的那部分将保存为桌面...

  • 发布于 2021-04-09 14:17
  • 阅读 ( 162 )

键盘忍者:不使用鼠标启动任何应用程序

...表板小部件、系统首选项窗格、文档,最后(被屏幕截图截取)搜索所有文件。如果文本“itunes”与我在苹果邮件中的任何一封邮件都匹配,那么这些邮件也会被找到。就像iPhoto中的任何图片,iTunes中的任何歌曲,等等。苹果出...

  • 发布于 2021-04-14 13:55
  • 阅读 ( 130 )

用delphi创建、解析和操作xml文档

...行诸如检索、更新和插入XML数据之类的操作。 作为一名Delphi程序员,您应该知道如何使用XML文档。 xml与delphi 有关将Delphi与XML配对的更多信息,请阅读: 了解如何将TTreeView组件项存储到XML(保留树节点的文本和其他属性)...

  • 发布于 2021-09-06 15:05
  • 阅读 ( 166 )

程序退出时delphi中的内存泄漏通知

自Delphi 2006以来的所有Delphi版本都有一个更新的内存管理器,该管理器速度更快,功能更丰富。 “新”内存管理器最出色的功能之一是允许应用程序注册(和注销)预期内存泄漏,并在程序关闭时报告意外内存泄漏。 使用De...

  • 发布于 2021-09-06 15:15
  • 阅读 ( 168 )

如何构建没有gui的控制台应用程序(build console applications with no gui)

...提供。 对于学生来说,控制台应用程序将简化Pascal和Delphi的学习——毕竟,所有Pascal入门示例都只是控制台应用程序。 新:控制台应用程序 下面介绍如何快速构建在没有图形界面的情况下运行的控制台应用程序。 如果...

  • 发布于 2021-09-10 22:34
  • 阅读 ( 251 )

用delphi编写网络感知应用程序

在Delphi为支持通过网络(internet、intranet和local)交换数据的应用程序而提供的所有组件中,最常见的两个组件是TServerSocket和TClientSocket,这两个组件都旨在通过TCP/IP连接支持读写功能。 winsock和delphi套接字组件 Windows Sockets(W...

  • 发布于 2021-09-10 23:39
  • 阅读 ( 199 )

在系统托盘中放置delphi应用程序

...还有其他图标吗?这个地方叫做Windows系统托盘。您想将Delphi应用程序的图标放在那里吗?您希望该图标设置动画还是反映应用程序的状态? 这对于长时间运行而没有用户交互的程序(通常整天都在电脑上运行的后台任务)非...

  • 发布于 2021-09-11 00:20
  • 阅读 ( 180 )

用delphi和ado编辑excel表格

...,以及如何处理这些错误。 以下内容包括: Excel和Delphi之间的数据传输方法。如何使用ADO(ActiveX数据对象)和Delphi连接Excel。 使用Delphi和ADO创建Excel电子表格编辑器 从Excel中检索数据。如何在Excel工作簿中引用表(或范围)...

  • 发布于 2021-09-11 00:21
  • 阅读 ( 243 )

优化delphi程序的内存使用

...活动,最终降低计算机的速度。 02 2006年 何时在delphi应用程序中创建表单 假设您要设计一个包含主窗体和两个附加(模态)窗体的程序。通常,根据您的Delphi版本,Delphi将把表单插入到项目单元(DPR文件)中,并包...

  • 发布于 2021-09-15 03:43
  • 阅读 ( 199 )

使用delphi创建windows服务应用程序

...以暂停和重新启动,并且不显示任何用户界面。 使用delphi的服务应用程序 使用Delphi创建服务应用程序: 创建服务、安装和卸载服务应用程序、使服务执行某些操作,并使用TService.LogMessage方法调试服务应用程序。 使用Delphi...

  • 发布于 2021-09-15 03:44
  • 阅读 ( 140 )
SHa045161561
SHa045161561

0 篇文章

相关推荐