AsphyreKeyboard.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:11k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit AsphyreKeyboard;
  2. //---------------------------------------------------------------------------
  3. // AsphyreKeyboard.pas                                  Modified: 28-Jan-2007
  4. // Keyboard DirectInput wrapper for Asphyre                      Version 1.02
  5. //---------------------------------------------------------------------------
  6. // Important Notice:
  7. //
  8. // If you modify/use this code or one of its parts either in original or
  9. // modified form, you must comply with Mozilla Public License v1.1,
  10. // specifically section 3, "Distribution Obligations". Failure to do so will
  11. // result in the license breach, which will be resolved in the court.
  12. // Remember that violating author's rights is considered a serious crime in
  13. // many countries. Thank you!
  14. //
  15. // !! Please *read* Mozilla Public License 1.1 document located at:
  16. //  http://www.mozilla.org/MPL/
  17. //
  18. // If you require any clarifications about the license, feel free to contact
  19. // us or post your question on our forums at: http://www.afterwarp.net
  20. //---------------------------------------------------------------------------
  21. // The contents of this file are subject to the Mozilla Public License
  22. // Version 1.1 (the "License"); you may not use this file except in
  23. // compliance with the License. You may obtain a copy of the License at
  24. // http://www.mozilla.org/MPL/
  25. //
  26. // Software distributed under the License is distributed on an "AS IS"
  27. // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
  28. // License for the specific language governing rights and limitations
  29. // under the License.
  30. //
  31. // The Original Code is AsphyreKeyboard.pas.
  32. //
  33. // The Initial Developer of the Original Code is M. Sc. Yuriy Kotsarenko.
  34. // Portions created by M. Sc. Yuriy Kotsarenko are Copyright (C) 2007,
  35. // Afterwarp Interactive. All Rights Reserved.
  36. //---------------------------------------------------------------------------
  37. interface
  38. //---------------------------------------------------------------------------
  39. uses
  40.  Windows, DirectInput, AsphyreAsserts;
  41. //---------------------------------------------------------------------------
  42. type
  43.  TDIKeyBuf = array[0..255] of Byte;
  44. //---------------------------------------------------------------------------
  45.  TAsphyreKeyboard = class
  46.  private
  47.   FOwnerInput : TObject;
  48.   FInputDevice: IDirectInputDevice8;
  49.   FForeground : Boolean;
  50.   FInitialized: Boolean;
  51.   Buffer : TDIKeyBuf;
  52.   PrevBuf: TDIKeyBuf;
  53.   procedure SetForeground(const Value: Boolean);
  54.   function GetKeyBuffer(): Pointer;
  55.   function GetKey(KeyNum: Integer): Boolean;
  56.   function GetKeyPressed(KeyNum: Integer): Boolean;
  57.   function GetKeyReleased(KeyNum: Integer): Boolean;
  58.   function GetKeyName(KeyNum: Integer): string;
  59.   function VKeyToNum(VCode: Cardinal): Integer;
  60.   function GetVKey(VCode: Cardinal): Boolean;
  61.   function GetVKeyPressed(VCode: Cardinal): Boolean;
  62.   function GetVKeyReleased(VCode: Cardinal): Boolean;
  63.   function GetVKeyName(VCode: Cardinal): string;
  64.  public
  65.   // A reference to owner of this component; it must be TAsphyreInput.
  66.   property OwnerInput: TObject read FOwnerInput;
  67.   // Interface to DirectInput 8 device.
  68.   property InputDevice: IDirectInputDevice8 read FInputDevice;
  69.   // The pointer to current key buffer.
  70.   property KeyBuffer : Pointer read GetKeyBuffer;
  71.   // Indicates whether the component has been initialized properly.
  72.   property Initialized: Boolean read FInitialized;
  73.   // This indicates whether the component should have keyboard acquired
  74.   // even when the application has no focus.
  75.   property Foreground: Boolean read FForeground write SetForeground;
  76.   // Retreives key status using scancodes (DIK_[key] constants)
  77.   property Key[KeyNum: Integer]: Boolean read GetKey;
  78.   // Retreives the name of the key for the specific scancode
  79.   property KeyName[KeyNum: Integer]: string read GetKeyName;
  80.   // Retreives key status using virtual codes (VK_[key] constants)
  81.   // Note: not all keys can be obtained this way!
  82.   property VKey[VCode: Cardinal]: Boolean read GetVKey;
  83.   // Retreives the name of the key for the specific virtual code
  84.   property VKeyName[VCode: Cardinal]: string read GetVKeyName;
  85.   // Note: The following functions try to detect key presses and releases,
  86.   // but they are limited to the resolution of Update() calls and may miss
  87.   // some key presses.
  88.   // Checks whether a key with the specific scancode has been pressed
  89.   // or released recently.
  90.   property KeyPressed[KeyNum: Integer]: Boolean read GetKeyPressed;
  91.   property KeyReleased[KeyNum: Integer]: Boolean read GetKeyReleased;
  92.   // Checks whether a key with the specific virtual code has been pressed
  93.   // or released recently.
  94.   property VKeyPressed[VCode: Cardinal]: Boolean read GetVKeyPressed;
  95.   property VKeyReleased[VCode: Cardinal]: Boolean read GetVKeyReleased;
  96.   function Initialize(): Boolean;
  97.   procedure Finalize();
  98.   function Update(): Boolean;
  99.   constructor Create(AOwnerInput: TObject);
  100.   destructor Destroy(); override;
  101.  end;
  102. //---------------------------------------------------------------------------
  103. implementation
  104. //---------------------------------------------------------------------------
  105. uses
  106.  AsphyreInputs;
  107. //---------------------------------------------------------------------------
  108. constructor TAsphyreKeyboard.Create(AOwnerInput: TObject);
  109. begin
  110.  inherited Create();
  111.  FOwnerInput:= AOwnerInput;
  112.  Assert((FOwnerInput <> nil)and(FOwnerInput is TAsphyreInput), msgNoOwnerInput);
  113.  FForeground := True;
  114.  FInitialized:= False;
  115. end;
  116. //---------------------------------------------------------------------------
  117. destructor TAsphyreKeyboard.Destroy();
  118. begin
  119.  if (FInitialized) then Finalize();
  120.  inherited;
  121. end;
  122. //---------------------------------------------------------------------------
  123. procedure TAsphyreKeyboard.SetForeground(const Value: Boolean);
  124. begin
  125.  if (not FInitialized) then FForeground:= Value;
  126. end;
  127. //---------------------------------------------------------------------------
  128. function TAsphyreKeyboard.Initialize(): Boolean;
  129. var
  130.  Input: TAsphyreInput;
  131. begin
  132.  Assert(not FInitialized, msgAlreadyInitialized);
  133.  // (1) Acquire a valid TAsphyreInput reference.
  134.  Input:= TAsphyreInput(FOwnerInput);
  135.  // (2) Make sure that TAsphyreInput is also initialized
  136.  if (not Input.Initialized) then
  137.   begin
  138.    Result:= Input.Initialize();
  139.    if (not Result) then Exit;
  140.   end;
  141.  // (3) Create Keyboard DirectInput device.
  142.  Result:= Succeeded(Input.DirectInput8.CreateDevice(GUID_SysKeyboard,
  143.   FInputDevice, nil));
  144.  if (not Result) then Exit;
  145.  // (4) Set Keyboard data format.
  146.  Result:= Succeeded(FInputDevice.SetDataFormat(c_dfDIKeyboard));
  147.  if (not Result) then
  148.   begin
  149.    FInputDevice:= nil;
  150.    Exit;
  151.   end;
  152.  // (5) Set cooperative level.
  153.  if (FForeground) then
  154.   begin // foreground cooperative level
  155.    Result:= Succeeded(FInputDevice.SetCooperativeLevel(Input.WindowHandle,
  156.     DISCL_FOREGROUND or DISCL_NONEXCLUSIVE));
  157.   end else
  158.   begin // background cooperative level
  159.    Result:= Succeeded(FInputDevice.SetCooperativeLevel(Input.WindowHandle,
  160.     DISCL_BACKGROUND or DISCL_NONEXCLUSIVE));
  161.   end;
  162.  if (not Result) then
  163.   begin
  164.    FInputDevice:= nil;
  165.    Exit;
  166.   end;
  167.  FillChar(Buffer, SizeOf(TDIKeyBuf), 0);
  168.  FillChar(PrevBuf, SizeOf(TDIKeyBuf), 0);
  169.  FInitialized:= True;
  170. end;
  171. //---------------------------------------------------------------------------
  172. procedure TAsphyreKeyboard.Finalize();
  173. begin
  174.  if (FInputDevice <> nil) then
  175.   begin
  176.    FInputDevice.Unacquire();
  177.    FInputDevice:= nil;
  178.   end;
  179.  FInitialized:= False;
  180. end;
  181. //---------------------------------------------------------------------------
  182. function TAsphyreKeyboard.GetKeyBuffer(): Pointer;
  183. begin
  184.  Result:= @Buffer;
  185. end;
  186. //---------------------------------------------------------------------------
  187. function TAsphyreKeyboard.Update(): Boolean;
  188. var
  189.  Res: Integer;
  190. begin
  191.  Result:= True;
  192.  // (1) Make sure the component is initialized.
  193.  if (not FInitialized) then
  194.   begin
  195.    Result:= Initialize();
  196.    if (not Result) then Exit;
  197.   end;
  198.  // (2) Save current buffer state.
  199.  Move(Buffer, PrevBuf, SizeOf(TDIKeyBuf));
  200.  // (3) Attempt to retreive device state.
  201.  Res:= FInputDevice.GetDeviceState(SizeOf(TDIKeyBuf), @Buffer);
  202.  if (Res <> DI_OK) then
  203.   begin
  204.    // -> can the error be corrected?
  205.    if (Res <> DIERR_INPUTLOST)and(Res <> DIERR_NOTACQUIRED) then
  206.     begin
  207.      Result:= False;
  208.      Exit;
  209.     end;
  210.    // -> device might not be acquired!
  211.    Res:= FInputDevice.Acquire();
  212.    if (Res = DI_OK) then
  213.     begin
  214.      // acquired successfully, now try retreiving the state again
  215.      Res:= FInputDevice.GetDeviceState(SizeOf(TDIKeyBuf), @Buffer);
  216.      if (Res <> DI_OK) then Result:= False;
  217.     end else Result:= False;
  218.   end; // if (Res <> DI_OK)
  219. end;
  220. //---------------------------------------------------------------------------
  221. function TAsphyreKeyboard.GetKey(KeyNum: Integer): Boolean;
  222. begin
  223.  Result:= (Buffer[KeyNum] and $80) = $80;
  224. end;
  225. //---------------------------------------------------------------------------
  226. function TAsphyreKeyboard.GetKeyPressed(KeyNum: Integer): Boolean;
  227. begin
  228.  Result:= (PrevBuf[KeyNum] and $80 <> $80) and (Buffer[KeyNum] and $80 = $80);
  229. end;
  230. //---------------------------------------------------------------------------
  231. function TAsphyreKeyboard.GetKeyReleased(KeyNum: Integer): Boolean;
  232. begin
  233.  Result:= (PrevBuf[KeyNum] and $80 = $80) and (Buffer[KeyNum] and $80 <> $80);
  234. end;
  235. //---------------------------------------------------------------------------
  236. function TAsphyreKeyboard.GetKeyName(KeyNum: Integer): string;
  237. var
  238.  KeyName: array[0..255] of Char;
  239. begin
  240.  GetKeyNameText(KeyNum or $800000, @KeyName, 255);
  241.  Result:= string(KeyName);
  242. end;
  243. //---------------------------------------------------------------------------
  244. function TAsphyreKeyboard.VKeyToNum(VCode: Cardinal): Integer;
  245. begin
  246.  Result:= MapVirtualKey(VCode, 0);
  247. end;
  248. //---------------------------------------------------------------------------
  249. function TAsphyreKeyboard.GetVKey(VCode: Cardinal): Boolean;
  250. begin
  251.  Result:= GetKey(VKeyToNum(VCode));
  252. end;
  253. //---------------------------------------------------------------------------
  254. function TAsphyreKeyboard.GetVKeyPressed(VCode: Cardinal): Boolean;
  255. begin
  256.  Result:= GetKeyPressed(VKeyToNum(VCode));
  257. end;
  258. //---------------------------------------------------------------------------
  259. function TAsphyreKeyboard.GetVKeyReleased(VCode: Cardinal): Boolean;
  260. begin
  261.  Result:= GetKeyReleased(VKeyToNum(VCode));
  262. end;
  263. //---------------------------------------------------------------------------
  264. function TAsphyreKeyboard.GetVKeyName(VCode: Cardinal): string;
  265. begin
  266.  Result:= GetKeyName(VKeyToNum(VCode));
  267. end;
  268. //---------------------------------------------------------------------------
  269. end.