delphi系统键盘输入捕获或手势捕获
一、直接用ASCii码值捕获键盘输入
窗体FormKeyDown( //:键按下
Sender: TObject;
var Key: Word; //:用于捕获
// UInt16 = Word; //:Word无符号的SmallInt : (0..65535) (0.. -1) SmallInt : (-65536..65535) (-.. -1)
// UInt16 = Word; :用于扩展ASCii编码:(0..255) : (0.. -1):即:UInt8:Byte字节 :应用于比如某些设备上个性化的按键
// ASC编码: (0..127) :(0.. -1)
var KeyChar: Char;
Shift: TShiftState //:用于捕获
); 或 FormKeyUp //:键按下后松开
某个TFmxObject输入组件KeyDown( //:键按下
Sender: TObject;
var Key: Word;
var KeyChar: Char;
Shift: TShiftState
); 或 KeyUp //:键按下后松开
ASC编码码值对照表详见:
https://mp.csdn.net/console/editor/html/104353336
方法: #加ASCii编码: 比如:#46 :直接用ASCii码值捕获键盘的输入Del键
案例:
procedure TYourForm.FormKeyDown(
Sender: TObject;
var Key: Word; //:用于捕获
var KeyChar: Char;
Shift: TShiftState //:用于捕获
);
begin
KeyChar:=Char(Key); //:KeyChar是用于返回捕获后的键对应的字符用的
//:KeyChar并不能做捕获用
//:捕获要用 Key 和 Shift(系统数组常量,代表用的是左边还是右边的ctrl或shift的组合)
//:BackSpace等控制键是返回不了字符的:系统内部的乱码:控制符
if ( Char(Key)=#8) or ( Char(Key) =#46 ) then //:#46 :直接用ASCii码值捕获键盘的输入Del键
//:或:if (Key=vkBack) or (Key=vkDelete) then //uses System.UITypes;
begin
ShowMessage('按下了Backspace键或del键:'+KeyChar);
//memo1.Lines.Add(IntToStr(Key));
end;
二、用表达友好常量的捕获键盘输入
方法: 用下面{}中的:ASCii编码($是其对应的16进制编码)对应的友好常量调用
比如:vkDelete :代表#8的ASCii码值捕获键盘的输入Del键。
案例:
if (Key=vkBack) or (Key=vkDelete) then ; //uses System.UITypes;
uses System.UITypes;
http://docwiki.embarcadero.com/Libraries/Rio/en/System.UITypes
const
{ Virtual Keys, Standard Set }
vkLButton = $01; { 1 }
vkRButton = $02; { 2 }
vkCancel = $03; { 3 }
vkMButton = $04; { 4 }
vkXButton1 = $05; { 5 }
vkXButton2 = $06; { 6 }
vkBack = $08; { 8 }
vkTab = $09; { 9 }
vkLineFeed = $0A; { 10 }
vkClear = $0C; { 12 }
vkReturn = $0D; { 13 }
vkShift = $10; { 16 }
vkControl = $11; { 17 }
vkMenu = $12; { 18 }
vkPause = $13; { 19 }
vkCapital = $14; { 20 }
vkKana = $15; { 21 }
vkHangul = $15; { 21 }
vkJunja = $17; { 23 }
vkFinal = $18; { 24 }
vkHanja = $19; { 25 }
vkKanji = $19; { 25 }
vkConvert = $1C; { 28 }
vkNonConvert = $1D; { 29 }
vkAccept = $1E; { 30 }
vkModeChange = $1F; { 31 }
vkEscape = $1B; { 27 }
vkSpace = $20; { 32 }
vkPrior = $21; { 33 }
vkNext = $22; { 34 }
vkEnd = $23; { 35 }
vkHome = $24; { 36 }
vkLeft = $25; { 37 }
vkUp = $26; { 38 }
vkRight = $27; { 39 }
vkDown = $28; { 40 }
vkSelect = $29; { 41 }
vkPrint = $2A; { 42 }
vkExecute = $2B; { 43 }
vkSnapshot = $2C; { 44 }
vkInsert = $2D; { 45 }
vkDelete = $2E; { 46 }
vkHelp = $2F; { 47 }
{ vk0 thru vk9 are the same as ASCII '0' thru '9' ($30 - $39) }
vk0 = $30; { 48 }
vk1 = $31; { 49 }
vk2 = $32; { 50 }
vk3 = $33; { 51 }
vk4 = $34; { 52 }
vk5 = $35; { 53 }
vk6 = $36; { 54 }
vk7 = $37; { 55 }
vk8 = $38; { 56 }
vk9 = $39; { 57 }
{ vkA thru vkZ are the same as ASCII 'A' thru 'Z' ($41 - $5A) }
vkA = $41; { 65 }
vkB = $42; { 66 }
vkC = $43; { 67 }
vkD = $44; { 68 }
vkE = $45; { 69 }
vkF = $46; { 70 }
vkG = $47; { 71 }
vkH = $48; { 72 }
vkI = $49; { 73 }
vkJ = $4A; { 74 }
vkK = $4B; { 75 }
vkL = $4C; { 76 }
vkM = $4D; { 77 }
vkN = $4E; { 78 }
vkO = $4F; { 79 }
vkP = $50; { 80 }
vkQ = $51; { 81 }
vkR = $52; { 82 }
vkS = $53; { 83 }
vkT = $54; { 84 }
vkU = $55; { 85 }
vkV = $56; { 86 }
vkW = $57; { 87 }
vkX = $58; { 88 }
vkY = $59; { 89 }
vkZ = $5A; { 90 }
vkLWin = $5B; { 91 }
vkRWin = $5C; { 92 }
vkApps = $5D; { 93 }
vkSleep = $5F; { 95 }
vkNumpad0 = $60; { 96 }
vkNumpad1 = $61; { 97 }
vkNumpad2 = $62; { 98 }
vkNumpad3 = $63; { 99 }
vkNumpad4 = $64; { 100 }
vkNumpad5 = $65; { 101 }
vkNumpad6 = $66; { 102 }
vkNumpad7 = $67; { 103 }
vkNumpad8 = $68; { 104 }
vkNumpad9 = $69; { 105 }
vkMultiply = $6A; { 106 }
vkAdd = $6B; { 107 }
vkSeparator = $6C; { 108 }
vkSubtract = $6D; { 109 }
vkDecimal = $6E; { 110 }
vkDivide = $6F; { 111 }
vkF1 = $70; { 112 }
vkF2 = $71; { 113 }
vkF3 = $72; { 114 }
vkF4 = $73; { 115 }
vkF5 = $74; { 116 }
vkF6 = $75; { 117 }
vkF7 = $76; { 118 }
vkF8 = $77; { 119 }
vkF9 = $78; { 120 }
vkF10 = $79; { 121 }
vkF11 = $7A; { 122 }
vkF12 = $7B; { 123 }
vkF13 = $7C; { 124 }
vkF14 = $7D; { 125 }
vkF15 = $7E; { 126 }
vkF16 = $7F; { 127 }
vkF17 = $80; { 128 }
vkF18 = $81; { 129 }
vkF19 = $82; { 130 }
vkF20 = $83; { 131 }
vkF21 = $84; { 132 }
vkF22 = $85; { 133 }
vkF23 = $86; { 134 }
vkF24 = $87; { 135 }
vkCamera = $88; { 136 }
vkHardwareBack = $89; { 137 }
vkNumLock = $90; { 144 }
vkScroll = $91; { 145 }
vkLShift = $A0; { 160 }
vkRShift = $A1; { 161 }
vkLControl = $A2; { 162 }
vkRControl = $A3; { 163 }
vkLMenu = $A4; { 164 }
vkRMenu = $A5; { 165 }
vkBrowserBack = $A6; { 166 }
vkBrowserForward = $A7; { 167 }
vkBrowserRefresh = $A8; { 168 }
vkBrowserStop = $A9; { 169 }
vkBrowserSearch = $AA; { 170 }
vkBrowserFavorites = $AB; { 171 }
vkBrowserHome = $AC; { 172 }
vkVolumeMute = $AD; { 173 }
vkVolumeDown = $AE; { 174 }
vkVolumeUp = $AF; { 175 }
vkMediaNextTrack = $B0; { 176 }
vkMediaPrevTrack = $B1; { 177 }
vkMediaStop = $B2; { 178 }
vkMediaPlayPause = $B3; { 179 }
vkLaunchMail = $B4; { 180 }
vkLaunchMediaSelect= $B5; { 181 }
vkLaunchApp1 = $B6; { 182 }
vkLaunchApp2 = $B7; { 183 }
vkSemicolon = $BA; { 186 }
vkEqual = $BB; { 187 }
vkComma = $BC; { 188 }
vkMinus = $BD; { 189 }
vkPeriod = $BE; { 190 }
vkSlash = $BF; { 191 }
vkTilde = $C0; { 192 }
vkLeftBracket = $DB; { 219 }
vkBackslash = $DC; { 220 }
vkRightBracket = $DD; { 221 }
vkQuote = $DE; { 222 }
vkPara = $DF; { 223 }
vkOem102 = $E2; { 226 }
vkIcoHelp = $E3; { 227 }
vkIco00 = $E4; { 228 }
vkProcessKey = $E5; { 229 }
vkIcoClear = $E6; { 230 }
vkPacket = $E7; { 231 }
vkAttn = $F6; { 246 }
vkCrsel = $F7; { 247 }
vkExsel = $F8; { 248 }
vkErEof = $F9; { 249 }
vkPlay = $FA; { 250 }
vkZoom = $FB; { 251 }
vkNoname = $FC; { 252 }
vkPA1 = $FD; { 253 }
vkOemClear = $FE; { 254 }
vkNone = $FF; { 255 }
三、捕获手势
uses System.UITypes;
const
// Standard gesture id's 标准手势及其ID
sgiNoGesture = 0;
sgiLeft = 1;
sgiRight = 2;
sgiUp = 3;
sgiDown = 4;
sgiUpLeft = 5;
sgiUpRight = 6;
sgiDownLeft = 7;
sgiDownRight = 8;
sgiLeftUp = 9;
sgiLeftDown = 10;
sgiRightUp = 11;
sgiRightDown = 12;
sgiUpDown = 13;
sgiDownUp = 14;
sgiLeftRight = 15;
sgiRightLeft = 16;
sgiUpLeftLong = 17;
sgiUpRightLong = 18;
sgiDownLeftLong = 19;
sgiDownRightLong = 20;
sgiScratchout = 21;
sgiTriangle = 22;
sgiSquare = 23;
sgiCheck = 24;
sgiCurlicue = 25;
sgiDoubleCurlicue = 26;
sgiCircle = 27;
sgiDoubleCircle = 28;
sgiSemiCircleLeft = 29;
sgiSemiCircleRight = 30;
sgiChevronUp = 31;
sgiChevronDown = 32;
sgiChevronLeft = 33;
sgiChevronRight = 34;
sgiFirst = sgiLeft;
sgiLast = sgiChevronRight;
// Recorded custom gestures ID range 记录化的客制化手势的ID范围(-512..-1)
cgiFirst = -512;
cgiLast = -1;
// Registered custom gestures ID range 使用注册方法的客制化手势的ID范围:分RGI和IGI:
rgiFirst = -1024;
rgiLast = -513;
igiFirst = 256;
igiLast = 511;
const
// Interactive gesture id's (maps to Windows 7's WM_GESTURE) 映射到Win7的模拟键盘消息的手势常量:
igiBegin = 1 + igiFirst;
igiEnd = 2 + igiFirst;
igiZoom = 3 + igiFirst;
igiPan = 4 + igiFirst;
igiRotate = 5 + igiFirst;
igiTwoFingerTap = 6 + igiFirst;
igiPressAndTap = 7 + igiFirst;
// Extra interactive gestures 附加的手势常量:
igiLongTap = 8 + igiFirst;
igiDoubleTap = 9 + igiFirst;
uses FMX.Types;
TStandardGesture = (
sgLeft = sgiLeft,
sgRight = sgiRight,
sgUp = sgiUp,
sgDown = sgiDown,
sgUpLeft = sgiUpLeft,
sgUpRight = sgiUpRight,
sgDownLeft = sgiDownLeft,
sgDownRight = sgiDownRight,
sgLeftUp = sgiLeftUp,
sgLeftDown = sgiLeftDown,
sgRightUp = sgiRightUp,
sgRightDown = sgiRightDown,
sgUpDown = sgiUpDown,
sgDownUp = sgiDownUp,
sgLeftRight = sgiLeftRight,
sgRightLeft = sgiRightLeft,
sgUpLeftLong = sgiUpLeftLong,
sgUpRightLong = sgiUpRightLong,
sgDownLeftLong = sgiDownLeftLong,
sgDownRightLong = sgiDownRightLong,
sgScratchout = sgiScratchout,
sgTriangle = sgiTriangle,
sgSquare = sgiSquare,
sgCheck = sgiCheck,
sgCurlicue = sgiCurlicue,
sgDoubleCurlicue = sgiDoubleCurlicue,
sgCircle = sgiCircle,
sgDoubleCircle = sgiDoubleCircle,
sgSemiCircleLeft = sgiSemiCircleLeft,
sgSemiCircleRight = sgiSemiCircleRight,
sgChevronUp = sgiChevronUp,
sgChevronDown = sgiChevronDown,
sgChevronLeft = sgiChevronLeft,
sgChevronRight = sgiChevronRight
);
TStandardGestures = set of TStandardGesture;
TGestureEventInfo = record
GestureID: TGestureID;
Location: TPointF;
Flags: TInteractiveGestureFlags;
Angle: Double;
InertiaVector: TPointF;
Distance: Integer;
TapLocation: TPointF;
end;
TGestureID = rgiFirst .. igiLast;
方法步骤:
第1步:引用FMX手势运行时刻库 uses FMX.Gestures;
第2步:UI上放手势组件TGestureManager
第3步:UI上放1个图片组件TImage来承载手势的标准比对图(可用TImageList来预载需要用到的手势图片,每个手势图片都有1个预置的手势ID)
第4步:分平台判断是否支持手势并为TImage定义手势:
4.1、定义UI上的手势图片TImage组件的手势管理器:TImage.OnPaint: 多要跨平台支持手势,UI上的TImage组件的Touch.GestureManager属性不要去填写组件TGestureManager,而是需要代码分平台判断后,进行代码引用,如下案例中TfrmVerificPicGesture.imgGesturePaint
4.2、定义UI上的手势图片TImage组件的可用哪些手势:TImage.OnPaint: 用一个标准手势类TStandardGesture的变量引用上述手势常量定义你的软件提供了哪些手势可供使用
方法:为UI上的TFmxObject组件的Touch.StandardGestures数组属性进行赋值
如下案例中TfrmVerificPicGesture.imgGesturePaint的var a:TStandardGesture; 定义:手势
UI上的其它非手势图片的TFmxObject组件.SetFocus; //:将输入焦点移开,以免遮挡
第5步:比对操作者使用的手势:
如下案例中TfrmVerificPicGesture.imgGestureGesture
5.1、捕获用户的操作的手势的ID(参考上述手势常量定义):TImage.OnGesture
EventInfo: TGestureEventInfo.GestureID
case EventInfo.GestureID of
sgiLeft : eiGestID:=EventInfo.GestureID ; //:向左操作的手势
sgiRight : eiGestID:=EventInfo.GestureID ; //:向右操作的手势
sgiUpLeft : eiGestID:=EventInfo.GestureID ; //:向上再左操作的手势
end;
5.2、比对用户的操作的手势ID和图片的手势ID数值是否一致
if (iGestPicIndex=eiGestID) then ; //是手势图的动作:
5.3、比对正确就执行你的代码(用Handled :=true)
if EnumTGestureID then
begin
Handled :=true;
执行你验证手势后的代码 ;
end;
function EnumTGestureID :Boolean;
begin
if (iGestPicIndex=eiGestID) then //是手势图的动作:
begin TextTop.Text:='手势通过验证'+IntToStr(iGestPicIndex)+IntToStr(eiGestID);
Text2.Text:='点击进入下一步' ;Result := True;
end else
begin TextTop.Text:='手势错误'+IntToStr(iGestPicIndex)+IntToStr(eiGestID);
Result := False; end; //:不是手势图的动作
end;
案例:
D:\PulledupO2O\myPublic\LoginAndSignin\myFrames
unit frameVerificPicGesture;
interface
uses
System.SysUtils, System.Types, System.UITypes,
System.Classes, System.Variants,
FMX.Types, FMX.Graphics, FMX.Controls,
FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
FMX.Gestures, FMX.Objects, FMX.Controls.Presentation,
System.ImageList,
FMX.ImgList, FMX.Layouts;
type
TfrmVerificPicGesture = class(TFrame)
GestureManager1: TGestureManager;
Rectangle1: TRectangle;
Rectangle2: TRectangle;
Rectangle3: TRectangle;
Rectangle4: TRectangle;
Rectangle5: TRectangle;
Rectangle6: TRectangle;
TextTop: TText;
btnGetImgGestue: TSpeedButton;
Text2: TText;
imgGesture: TImage;
imgListGesture: TImageList;
procedure imgGesturePaint(Sender: TObject; Canvas: TCanvas;
const ARect: TRectF);
procedure btnGetImgGestueClick(Sender: TObject);
procedure imgGestureGesture(Sender: TObject;
const EventInfo: TGestureEventInfo; var Handled: Boolean);
private
{ Private declarations }
///<summary>系统打开时或点刷新按钮产生的手势图索引随机号iGestPicIndex:</summary>
iGestPicIndex:Integer;
public
{ Public declarations }
frmVerificPicGesture: TfrmVerificPicGesture; //frame被引用的方法
end;
implementation
//uses myFuc_UnifiedPlatForm;
{$R *.fmx}
procedure TfrmVerificPicGesture.btnGetImgGestueClick(Sender: TObject);
begin
TextTop.Text:='安全验证';
iGestPicIndex:=0; iGestPicIndex:=RandomNumber(6);
while ( (iGestPicIndex<>1) and (iGestPicIndex<>2) and (iGestPicIndex<>5) ) do
begin
iGestPicIndex:=RandomNumber(6);
end;
imgGesture.Bitmap
:=ImgGetFromImgList(imgListGesture,64,64,iGestPicIndex );
end;
procedure TfrmVerificPicGesture.imgGestureGesture(Sender: TObject;
const EventInfo: TGestureEventInfo; var Handled: Boolean);
var eiGestID:Integer;
function EnumTGestureID:Boolean;
begin
if (iGestPicIndex=eiGestID) then //是手势图的动作:
begin TextTop.Text:='手势通过验证'+IntToStr(iGestPicIndex)+IntToStr(eiGestID);
Text2.Text:='点击进入下一步' ;Result := True; end else
begin TextTop.Text:='手势错误'+IntToStr(iGestPicIndex)+IntToStr(eiGestID);
Result := False; end; //:不是手势图的动作
end;
begin
//系统打开时或点刷新按钮产生的手势图索引随机号iGestPicIndex
//说明:FMX.Types: 点TGestureID =再点rgiFirst .. igiLast;
//System.UITypes : Standard gesture
//查看GestureID的常量整数数值 0~34,Dx10.3.1目前能支持0~20有效的
//步骤:
//1.设置事件通知EventInfo
eiGestID:=1;
case EventInfo.GestureID of
sgiLeft :begin eiGestID:=EventInfo.GestureID ; Handled := EnumTGestureID end; //sgiLeft:左或1
// begin
// if iGestPicIndex=1 then
// begin
// TextTop.Text:='手势通过验证';
// Handled := True;
// end;
// end;
//2.设置**事件通知:Handled := True; //EnumTGestureID函数实现
sgiRight :begin eiGestID:=EventInfo.GestureID ; Handled := EnumTGestureID end; //sgiRight:右或2//不能用
//sgiUp :begin eiGestID:=EventInfo.GestureID ; Handled := EnumTGestureID end; //sgiUp:上或3//不能用
//sgiDown :begin eiGestID:=EventInfo.GestureID ; Handled := EnumTGestureID end; //sgiDown:下或4//不能用
sgiUpLeft :begin eiGestID:=EventInfo.GestureID ; Handled := EnumTGestureID end; //sgiUpLeft:上左或5
//sgiUpRight :begin eiGestID:=EventInfo.GestureID ; Handled := EnumTGestureID end; //sgiUpRight:上右或6//不能用
end;
end;
procedure TfrmVerificPicGesture.imgGesturePaint(Sender: TObject;
Canvas: TCanvas; const ARect: TRectF);
var a:TStandardGesture;
begin
// btnGetImgGestueClick(Sender); //btnGetImgGestueClick 界面的任何变化会触发
//分操作系统,代码定义控件的手势管理组件:
//:小控件如按钮,不要使用手势,因为其很慢
{$IFDEF MSWINDOWS}
//MSWINDOWS:不支持手势
imgGesture.Touch.GestureManager:=nil;
imgGesture.Touch.StandardGestures:=[];
{$ENDIF MSWINDOWS}
{$IFDEF POSIX} //定义:手势
imgGesture.Touch.GestureManager:=GestureManager1;
imgGesture.Touch.StandardGestures //:=[a.];
:=[ TStandardGesture.sgLeft, TStandardGesture.sgRight,
TStandardGesture.sgUpLeft ];
btnGetImgGestue.SetFocus; //:将输入焦点移开,以免遮挡
{$ENDIF POSIX}
end;
end.
|
请发表评论