Einzelnen Beitrag anzeigen

Robert Marquardt
(Gast)

n/a Beiträge
 
#21

Re: HID Komponente - Komme nicht zurecht

  Alt 17. Mär 2007, 15:33
Ich darf den Beitrag nicht mehr aendern. Neu posten geht schneller.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  // JvComponentBase kommt automatisch dazu wenn man die HID-Komponente
  // aus der JVCL benutzt. Fuer die Standalone-Version einfach loeschen.
  Dialogs, JvComponentBase, JvHidControllerClass, StdCtrls;

type
  TForm1 = class(TForm)
    JvHidDeviceController1: TJvHidDeviceController;
    Label1: TLabel;
    Label2: TLabel;
    ListBox1: TListBox;
    procedure JvHidDeviceController1DeviceChange(Sender: TObject);
    procedure JvHidDeviceController1DeviceData(HidDev: TJvHidDevice;
      ReportID: Byte; const Data: Pointer; Size: Word);
    procedure FormDestroy(Sender: TObject);
  public
    Device: TJvHidDevice;
  end;

var
  Form1: TForm1;

implementation

uses
  HID, HidUsage;

{$R *.dfm}

const
  GriffinVID = $077D;
  PowerMatePID = $0410;

type
  // kein HID-Report kann groesser als 64 Byte sein
  THidReport = packed record
    ReportID: Byte;
    Data: array [0..62] of Byte;
  end;

// Standard-Implementierung zur Handhabung genau eines HID-Geraets.
// Es wird das erste gefundene passende Geraet genommen.

procedure TForm1.JvHidDeviceController1DeviceChange(Sender: TObject);
var
  Report: THidReport;
  Written: DWORD;
begin
  // erst mal sehen ob das Geraet ausgesteckt wurde
  if Assigned(Device) and not Device.IsPluggedIn then
  begin
    // das Objekt wird an den Controller zurueckgegeben
    // Device wird dabei auf nil gesetzt
    JvHidDeviceController1.CheckIn(Device);
    // hier gehoeren Finalisierungen der Oberflaeche hin
    Label1.Caption := '?';
    Label2.Caption := '?';
    ListBox1.Clear;
  end;
  // schauen ob wir nach einem Geraet suchen muessen
  if not Assigned(Device) then
    // schauen ob ein Griffin PowerMate vorhanden ist
    if JvHidDeviceController1.CheckOutByID(Device, GriffinVID, PowerMatePID) then
    begin
      // es wurde ein Geraet gefunden
      // hier gehoeren Initialisierungen des Geraets und der Oberflaeche hin
      // wir machen die LED an
      FillChar(Report, SizeOf(Report), 0);
      // das ist ziemlich aufwaendig dafuer das wir nur eine Usage im Report setzen wollen
      Report.ReportID := 0;
      // wir wollen in einen Output-Report schreiben
      Device.ReportTypeParam := HidP_Output;
      // das benennt die spezifische Usage die gesetzt werden soll
      Device.UsagePageParam := HID_USAGE_PAGE_CONSUMER;
      Device.LinkCollectionParam := $01; // CollectionType=Application
      Device.UsageParam := HID_USAGE_CONSUMER_CONSUMER_CONTROL;
      // den Wert setzen (LED Maximum)
      Device.SetUsageValue($FF, Report, Device.Caps.OutputReportByteLength);
      // ab damit ans Geraet
      Device.WriteFile(Report, Device.Caps.OutputReportByteLength, Written);
    end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
var
  Report: THidReport;
  Written: DWORD;
begin
  // nur wenn beim Programmende das Geraet noch eingesteckt ist
  if Assigned(Device) then
  begin
    // da wir in der Initialisierung das Licht eh die LED angemacht haben,
    // machen wir jetzt brav das Licht wieder aus.
    FillChar(Report, SizeOf(Report), 0);
    Report.ReportID := 0;
    Device.ReportTypeParam := HidP_Output;
    Device.UsagePageParam := HID_USAGE_PAGE_CONSUMER;
    Device.LinkCollectionParam := $01;
    Device.UsageParam := HID_USAGE_CONSUMER_CONSUMER_CONTROL;
    // Wert setzen (LED aus)
    Device.SetUsageValue($00, Report, Device.Caps.OutputReportByteLength);
    Device.WriteFile(Report, Device.Caps.OutputReportByteLength, Written);
  end;
end;

// Reports vom Geraet empfangen
// Der Event gilt fuer alle ausgecheckten Geraete

procedure TForm1.JvHidDeviceController1DeviceData(HidDev: TJvHidDevice;
  ReportID: Byte; const Data: Pointer; Size: Word);
var
  Report: THidReport;
  Button: TUsage;
  Len: DWORD;
  Dial: Integer;
  I: Integer;
  S: string;
begin
  // erst mal einen Designfehler der Komponente ausgleichen
  // wir brauchen den Report mit vorangestellter ReportID
  Report.ReportID := ReportID;
  Move(Data^, Report.Data[0], Size);

  // wir wollen den Buttonzustand extrahieren
  HidDev.ReportTypeParam := HidP_Input;
  HidDev.UsagePageParam := HID_USAGE_PAGE_BUTTON;
  HidDev.LinkCollectionParam := $01; // CollectionType=Application
  Len := 1;
  Button := $00;
  HidDev.GetButtons(@Button, Len, Report, Size + 1);
  // $01 ist die Usage des Buttons wie sie als "UsageMin: 1" von UsageDemo angegeben wurde.
  if Button = $01 then
    Label1.Caption := 'Button down'
  else
    Label1.Caption := 'Button up';

  // wir wollen den Wert des Drehknopfes extrahieren
  // nur die veraenderten Parameter werden gesetzt
  HidDev.UsagePageParam := HID_USAGE_PAGE_GENERIC;
  HidDev.UsageParam := HID_USAGE_GENERIC_RX;
  HidDev.GetScaledUsageValue(Dial, Report, Size + 1);
  Label2.Caption := Format('%d', [Dial]);

  // Rohdaten-Ausgabe
  S := '';
  for I := 0 to Size - 1 do
    S := S + Format('%.2x ', [Report.Data[I]]);
  ListBox1.Items.Add(S);
end;

end.
  Mit Zitat antworten Zitat