娃娃鸭《Delphi 6集成开发环境》笔记V

娃娃鸭《Delphi 6集成开发环境》笔记V

1、键盘和鼠标事件

当用户对组件进行一些操作时,如单击,组件就会产生一个事件。还有一些事件由系统产生,如对一个对象方法调用的响应或该组件一个属性的变化(或甚至是其它组件的)。例如,如果用户将焦点设置在一个组件上,那么当前有焦点的组件就会失去它,这样就触发了相应的事件。

严格的说,大多数Delphi 事件是在收到相应的Windows 消息后被触发的,尽管事件与消息不是一一对应的。Delphi 事件的级别比Windows 消息的级别要高,而且Delphi 还另外提供事件处理程序。

从理论角度看,事件是向窗口发送消息的结果,并且该窗口(或相应组件)可以响应该消息。这样的话,为处理按钮的单击事件,需要把TButton 类划分为若干子类并添加新的事件处理程序。

Delphi 中,组件的事件处理程序是控制组件的窗体的对象方法,而不是组件自己的。换句话说,组件依赖于它的宿主——窗体——来处理它的事件。它是Delphi 基于组件模式的基础。

另一个重要的概念是,事件就是属性。这意味着,要处理组件的事件,可以赋予对象方法相应的属性。在对象编辑器中,当双击一个事件时,在宿主窗体中就添加了一个新的对象方法,并赋给组件相应的事件属性。

 

2、常用的键盘事件

1.OnKeyDown 事件

当按下键盘上的任一个键,如字母键、数字键、功能键(F1-F12)、Ctrl 键、Shift 键或Alt 键等,都将产生一个OnKeyDown 事件。

下面的一段代码说明了OnKeyDown 事件的用法:当打印的时候在窗体中按下Esc 键后,取消打印作业。

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;Shift: TShiftState);

begin

if (Key=VK_ESCAPE) and Printer.Printing then

begin

Printer.Abort; // 中止打印

MessageDlg('Stop Print', mtInformation, [mbOK],0);

end;

end;

2.OnKeyPress 事件

当按下键盘上的一个字符键,如字母键、数字键等会产生一个OnKeyPress 事件,但是单独按下功能键(F1-F12)、Ctrl 键、Shift 键或Alt 键等,不会产生OnKeyPress 事件

下面的一段显示按下的键的代码说明了OnKeyPress 事件的用法:

procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);

begin

MessageDlg ( 'You pressed'+Key+' key',mtInformation, [mbOK], 0)

end;

3OnKeyUp 事件

当按下键盘上的任一个键后松开时,都会产生一个OnKeyUp 事件。对于功能键(F1-F12)、Ctrl 键、Shift 键或Alt 键等,也会产生一个OnKeyUp 事件。

 

3、特殊的键盘事件

1.屏蔽系统功能键

有时需要将系统的功能键如Ctrl+Alt+Del(热启动)、Ctrl+Esc(弹出“开始”菜单)等屏蔽掉,然后在一定情况下再恢复系统功能键的作用。

procedure TForm1.Button1Click(Sender: TObject);

var

  tempInt: integer;

// 屏蔽系统功能键

begin

  SystemParametersInfo(SPI_SCREENSAVERRUNNING, 1, @tempInt, 0);

end;

 

procedure TForm1.Button2Click(Sender: TObject);

var

  tempInt: integer;

// 取消屏蔽系统功能键

begin

  SystemParametersInfo(SPI_SCREENSAVERRUNNING, 0, @tempInt, 0);

end;

 

程序运行后,先按下Ctrl+Esc 组合键,测试效果;然后按一下Button1 按钮,再按下Ctrl+Esc 键,测试效果;最后按一下Button2 按钮,再按下Ctrl+Esc 键,测试效果。(效果不明显)

 

2.模拟按下键盘上的某个键

Windows 环境中,如果在输入法中打开了软键盘,则可以通过点击鼠标实现键盘输入的功能。有时在一些应用程序中,也需要模拟在键盘上按下某个键的过程,这可以通过向特定对象发送按键事件来实现。

 

procedure TForm1.Button1Click(Sender: TObject);

// 模拟在Edit1组件中按下了字母a

begin

  PostMessage(Edit1.Handle, WM_KEYDOWN, 65, 0);

end;

 

procedure TForm1.Timer1Timer(Sender: TObject);

// 模拟在窗体Form1中按下了Tab

begin

  PostMessage(Form1.Handle, WM_KEYDOWN, VK_TAB, 0);

end;

3.检测功能键

在组件的OnKeyDownOnKeyUpOnMouseDown OnMouseUp 等事件的处理过程中,有一个TShiftState 类型的变量ShiftTShiftState 类型定义如下:

type TShiftState = set of (ssShift, ssAlt, ssCtrl, ssLeft, ssRight, ssMiddle, ssDouble);

所以根据Shift 的值就可以判断当键盘上的键按下时ShiftAlt Ctrl 键的状态,或者按下鼠标左键、中键时的状态或者是否双击了按键。当然,如果有OnMouseDown 事件发生了,而又不是按下左键和中键,则按下的一定是右键。

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;

  Shift: TShiftState);

begin

  if Shift >= [ssShift] then // 如果按下了Shift键则在第一个面板上显示Shift

    StatusBar1.Panels[0].Text := 'Shift';

  if Shift >= [ssAlt] then // 如果按下了Alt键则在第二个面板上显示Alt

    StatusBar1.Panels[1].Text := 'Alt';

  if Shift >= [ssCtrl] then // 如果按下了Ctrl键则在第三个面板上显示Ctrl

    StatusBar1.Panels[2].Text := 'Ctrl';

end;

 

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;

  Shift: TShiftState);

// ShiftAltCtrl键弹起时清除状态栏中相应面板上的内容

begin

  if not (Shift >= [ssShift]) then

    StatusBar1.Panels[0].Text := ' ';

  if not (Shift >= [ssAlt]) then

    StatusBar1.Panels[1].Text := ' ';

  if not (Shift >= [ssCtrl]) then

    StatusBar1.Panels[2].Text := ' ';

end;

 

procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  if Shift >= [ssLeft] then // 如果按下了左键则在第四个面板上显示left

    StatusBar1.Panels[3].Text := 'Left';

 

  if Shift >= [ssMiddle] then // 如果按下了中键则在第五个面板上显示Middle

    StatusBar1.Panels[4].Text := 'Middle';

  if Shift >= [ssDouble] then // 如果是双击则在第六个面板上显示Double

    StatusBar1.Panels[5].Text := 'Double';

end;

 

procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

// 在鼠标按键弹起时清除状态栏中相应面板上的内容

  begin

    if not (Shift >= [ssLeft]) then

      StatusBar1.Panels[3].Text := ' ';

    if not (Shift >= [ssMiddle]) then

      StatusBar1.Panels[4].Text := ' ';

    if not (Shift >= [ssDouble]) then

      StatusBar1.Panels[5].Text := ' ';

  end;

end;

 

 

4、鼠标事件处理

常用鼠标事件

1OnMouseDown 事件

当按下鼠标上的任一个键,会产生一个OnMouseDown 事件。

2OnMouseMove 事件

当鼠标的位置发生了改变后会产生一个OnMouseMove 事件。

如果窗体有OnMouseMove 事件的处理过程,窗体中的某个组件也具有OnMouseMove事件的处理过程,那么当鼠标在窗体中移动时,执行的是窗体的OnMouseMove 事件的处理过程;当鼠标在组件上移动时,执行的则是组件的OnMouseMove 事件的处理过程,而将窗体的OnMouseMove 事件的处理过程屏蔽掉了。

3OnMouseUp 事件

当鼠标的某个按键按下,然后松开后会产生一个OnMouseUp 事件。

此外,OnClick 事件也与鼠标的操作有关,如在按钮组件上单击鼠标左键,可以产生该按钮组件的一个OnClick 事件。需要注意,OnClick 事件只有在一个组件上按下鼠标左键并在同一个组件上释放左键的情况下才会发生。如果按下左键后将鼠标移动到别的地方再释放,就不会产生该组件的OnClick 事件,但是会产生OnMouseDownOnMouseMove OnMouseUp等事件。

拖曳事件

1OnDragDrop 事件

在拖曳事件开始时会产生一个OnDragDrop 事件。

2OnDragOver 事件

当拖曳对象跨过一个组件时会产生一个OnDragOver事件。

3OnEndDrag 事件

当拖曳事件结束后会产生一个OnEndDrag 事件。

通过上面的拖曳事件,可以很方便地实现一些拖曳操作。具体过程如下:

1)拖曳操作开始

大多数的组件具有DragMode属性,表示开始拖曳操作的方式。DragMode属性的默认值为dmManual,也就是要在被拖动组件的OnMouseDown事件的处理过程中调用BeginDrag过程才开始拖曳操作。如果将DragMode属性设置为dmAutomatic,则鼠标左键在被拖动组件上按下后就自动开始拖曳操作。

2)接受拖曳操作

当拖动一个组件经过第二个组件的时候,第二个组件会产生一个OnDragOver 事件。在该事件的处理过程中有一个布尔类型的参数,该参数的设置直接影响是否产生OnDragDrop事件。

一般情况下,在OnDragOver 事件的处理过程中,根据参数Source 判断拖曳操作的源。

如果是可以接受的源,则将Accept 参数设置为True ;否则,将其设置为False

3)处理拖曳操作

在第二个组件的OnDragDrop 事件的处理过程中,根据拖曳操作的源做一些相应的处理。

4)拖曳操作结束

拖曳操作完成后释放鼠标左键,会在第一个组件中产生一个OnEndDrag 事件,可以根据参数Target 的数值进行相应的处理。如果参数Target 的值为nil,则表示拖曳操作没有被接受;如果Target 的值不为nil,则Target 的值就是接受拖曳操作的组件。

 

实例

procedure TForm1.Edit1MouseDown(Sender: TObject; Button: TMouseButton;

  Shift: TShiftState; X, Y: Integer);

begin

  if Button = mbLeft then // 开始进行拖动操作

    (Sender as TEdit).BeginDrag(False);

end;

 

procedure TForm1.Memo1DragOver(Sender, Source: TObject; X, Y: Integer;

  State: TDragState; var Accept: Boolean);

begin

  if Source is TEdit then // 可以接受拖动操作

    Accept := True;

end;

 

procedure TForm1.Memo1DragDrop(Sender, Source: TObject; X, Y: Integer);

begin

  if (Sender is TMemo) and (Source is TEdit) then

   // Edit组件中的内容添加到Memo组件的最后

    (Sender as TMemo).Lines.Add((Source as TEdit).Text);

end;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值