键盘和鼠标事件处理6.1焦点什么是焦点?•焦点是接收用户鼠标或键盘输入的能力对象具有焦点时,可接收用户的输入只有具有焦点的应用程序才有活动标题栏,才能接受输入有关说明•对象得到产生OnEnter•对象失去焦点产生OnExit事件•有些对象,它是否具有焦点是可以看出来的当按钮具有焦点时,标题周围的边框将突出显示•只有当对象的Enabled和Visible属性为True时,控件才能接收焦点将焦点赋给对象的方法•运行时选择对象•运行时用快捷键选择对象•在代码中用SetFocus方法6.2TAB键顺序按下TAB或SHIFT+TAB后,焦点从一控件移动到另一控件的顺序。TAB键顺序与建立控件的顺序相同TabOrder属性可改变一个控件的TAB件顺序,且从0开始不能获得焦点的控件,无效的和不可见的控件,不包含在TAB键顺序中•按TAB键时,这些控件将被跳过TabStop属性已置为False的控件,只不过在按TAB键时这个控件被跳过,但保持它在实际Tab键顺序中的位置。一个RadioGroup组只有一个TAB位置6.3键盘事件窗体和接受键盘输入的控件都识别以下三种事件•OnKeyPress按下对应某ASCII字符的键•OnKeyDown按下键盘的任意键•OnKeyUp释放键盘的任意键只有获得焦点的对象才能够接受键盘事件•如果将窗体上的KeyPreview属性设置为True,则对每个控件在控件识别其所有键盘事件之前,窗体就会接受这些键盘事件。键盘事件彼此并不相互排斥。•按下一键时将生成OnKeyDown和OnKeyPress事件,而松开此键后生成OnKeyUp事件。•当用户按下一个OnKeyPress不能检测的键时将触发OnKeyDown事件,而松开此键后时生成OnKeyUp事件。6.3.1OnKeyPress事件产生•按下某个键时触发该事件,F1、F2、Ctrl等系统按键不会产生事件说明•OnKeyPress事件产生一个Key参数(一个字符Char),它对应于对应于ASCII字符代码•在事件过程中修改key值可过滤按键示例•如大小写转换procedureTForm1.Edit1KeyPress(Sender:TObject;varKey:Char);beginkey:=chr(ord(UpCase(key)));end;6.3.1OnKeyPress事件(续)忽略非数字键的通用过程FunctionIgnoreNonNumeric(Key:Char):Char;beginifnot(keyin['0'..'9'])thenresult:=#0elseresult:=key;end;procedureTForm1.Edit1KeyPress(Sender:TObject;varKey:Char);beginKey:=IgnoreNonNumeric(Key);end;6.3.2OnKeyDown、OnKeyUp事件提供了最低级的键盘响应•检测OnKeyPress事件无法检测到的情况SHIFT、CTRL和ALT键的特殊组合•不仅响应按键操作而且响应释放键的操作(OnKeyPress只响应按键操作)•大写与小写返回同一值说明•某些控件(命令按钮、选项按钮和复选框)不接受箭头键事件,按下箭头键后将使焦点移动到另一个控件不触发OnKeyDown和OnKeyUp事件:•命令按钮、选项按钮和复选框具有焦点时按下箭头键•窗体上有Default、Cancel按钮时,按下Enter或ESC•窗体上存在有效TabStop=True的控件时,按下Tab键•按下为菜单定义的快捷键6.4鼠标事件基本鼠标事件•OnMouseDown•OnMouseUp•OnMouseMove鼠标滚动事件•OnMouseWheel•OnMouseWheelDown•OnMouseWheelUp鼠标拖放6.4鼠标事件(续)说明•单击一个控件除了产生OnClick事件以外还可产生OnMouseDown和OnMouseUp事件•OnClick和OnDblClick只有鼠标左键才会触发•OnDbClick事件在OnClick事件之后被触发思考:什么情况下,DbClick事件永远不会被触发?•OnMouseDown按下任意鼠标按钮时发生•OnMouseUp释放任意鼠标按钮时发生•OnMouseMove每当鼠标指针移动到屏幕新位置时发生6.4鼠标事件(续)button的值•mbLeft•mbRight•mbMiddleShift值•ssShift:按下Shift•ssAlt:按下Alt•ssCtrl:按下Ctrl•ssLeft:按下鼠标左键•ssRight:按下鼠标右键•ssMiddle:按下鼠标中键•ssDouble:鼠标左右键同时按下X,Y值•鼠标在控件客户区的位置6.4.1基本鼠标事件的使用varPaintNow:Boolean;procedureTForm1.FormMouseDown(Sender:TObject;Button:TMouseButton;Shift:TShiftState;X,Y:Integer);beginPaintNow:=True;end;procedureTForm1.FormMouseUp(Sender:TObject;Button:TMouseButton;Shift:TShiftState;X,Y:Integer);beginPaintNow:=False;end;procedureTForm1.FormMouseMove(Sender:TObject;Shift:TShiftState;X,Y:Integer);beginself.Canvas.pen.Create.Color:=clRed;self.Canvas.Pen.Width:=5;IfPaintNow=trueThenself.Canvas.LineTo(X,Y);//画一个线end;6.4.2鼠标滚动事件OnMouseWheel•转动鼠标滚轮时,触发该事件OnMouseWheelDown•鼠标向下转动时,该事件发生OnMouseWheelUp•鼠标向上转动时,该事件发生6.4.3鼠标拖放实现拖动的步骤•开始拖动操作控件的DragMode属性设置为面dmAutomatic可自动开始设为dmManul,则使用BeginDrag方法开始拖动•接受拖动操作用户拖动对象经过某控件时,该控件产生OnDragOver事件接受Accept:=True•释放拖动操作在OnDragDrop事件中添加代码,响应接受,释放拖动•结束拖动操作不管接受与否,释放拖动均会产生OnEndDrag事件•用拖动对象定制拖放可用TDragObject的派生对象来进一步定制拖动操作6.5模拟按键方法•PostMessage(hWnd:HWND;Msg:UINT;wParam:WPARAM;lParam:LPARAM):BOOL;stdcall例:在StringGrid控件中模拟按下↓键•PostMessage(StringGrid1.Handle,WM_KEYDOWN,Vk_Down,0)虚拟按键值虚拟键按下键虚拟键按下键VK_LEFT←VK_PRIORPageUpVK_UP↑VK_NEXTPageDownVK_RIGHT→VK_ENDEndkeyVK_DOWN↓VK_HOMEHomekeyVK_BACKBackspaceVK_PRINTPrintkeyVK_TABTabVK_INSERTInsertkeyVK_RETURNEnterkeyVK_DELETEDeletekeyVK_SHIFTShiftkeyVK_HELPHelpkeyVK_ESCAPEEsckeyVK_NUMPAD0(1-9)0(1-9)key(numerickeypad)VK_SPACESpacebarVK_F1(F2-F20)F1(F2-F20)key