Componentes.Terceros.jvcl/official/3.32/examples/JvHIDController/CollectionDemo/CollectionMain.pas

261 lines
9.0 KiB
ObjectPascal

{******************************************************************
JEDI-VCL Demo
Copyright (C) 2002 Project JEDI
Original author:
Contributor(s):
You may retrieve the latest version of this file at the JEDI-JVCL
home page, located at http://jvcl.sourceforge.net
The contents of this file are used with permission, subject to
the Mozilla Public License Version 1.1 (the "License"); you may
not use this file except in compliance with the License. You may
obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1_1Final.html
Software distributed under the License is distributed on an
"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
******************************************************************}
unit CollectionMain;
interface
uses
Windows, SysUtils, Classes, Controls, Forms, ComCtrls,
JvHidControllerClass, Dialogs, StdCtrls;
type
TCollectionDemoForm = class(TForm)
HidCtl: TJvHidDeviceController;
DeviceTree: TTreeView;
Save: TButton;
SaveDialog: TSaveDialog;
Description: TLabel;
procedure FormShow(Sender: TObject);
procedure HidCtlDeviceChange(Sender: TObject);
function HidCtlEnumerate(HidDev: TJvHidDevice;
Index: Integer): Boolean;
procedure SaveClick(Sender: TObject);
public
Root: TTreeNode;
procedure EnumerateCaps(HidDev: TJvHidDevice;
Parent: TTreeNode; Idx: Word);
procedure EnumerateNodes(HidDev: TJvHidDevice;
Parent: TTreeNode; Idx: Word; NumSiblings: Word);
end;
var
CollectionDemoForm: TCollectionDemoForm;
implementation
uses
UsagesInfo, Hid;
{$R *.DFM}
procedure TCollectionDemoForm.FormShow(Sender: TObject);
begin
// this compensates the possibility that HidCtlDeviceChange
// may not be able to fill the treeview the first time
HidCtlDeviceChange(Self);
end;
procedure TCollectionDemoForm.HidCtlDeviceChange(Sender: TObject);
begin
// HidCtlDeviceChange happens before TCollectionDemoForm.Create completed
// DeviceTree may have not been created yet
if Assigned(DeviceTree) then
begin
// each time something happens to the HID devices the treeview is filled
DeviceTree.Items.Clear;
Root := DeviceTree.Items.Add(nil, 'HID-Devices');
HidCtl.Enumerate;
end;
end;
procedure TCollectionDemoForm.EnumerateCaps(HidDev: TJvHidDevice; Parent: TTreeNode; Idx: Word);
procedure EnumerateButtonCaps(HidDev: TJvHidDevice; Parent: TTreeNode;
ReportType: THIDPReportType; ReportText: string);
var
I: Integer;
Ret: Integer;
N: WORD;
UsagePageText: string;
UsageText: string;
// 256 Caps entries should be always sufficient
BtnCaps: array [0..255] of THIDPButtonCaps;
begin
N := 255;
// get ALL ButtonCaps of the specified ReportType
HidDev.ReportTypeParam := ReportType;
Ret := HidDev.GetSpecificButtonCaps(@BtnCaps[0], N);
if Ret = HIDP_STATUS_SUCCESS then
for I := 0 to N-1 do
if BtnCaps[I].LinkCollection = Idx then
begin
UsageAndUsagePageText(BtnCaps[I].UsagePage, BtnCaps[I].Usage, UsagePageText, UsageText);
if BtnCaps[I].IsRange then
DeviceTree.Items.AddChild(Parent,
Format('Button %s Range: UsagePage=%s ($%.4x) %d..%d',
[ReportText, UsagePageText, BtnCaps[I].UsagePage, BtnCaps[I].UsageMin, BtnCaps[I].UsageMax]))
else
DeviceTree.Items.AddChild(Parent,
Format('Button %s: UsagePage=%s ($%.4x) Usage=%s ($%.4x)',
[ReportText, UsagePageText, BtnCaps[I].UsagePage, UsageText, BtnCaps[I].Usage]));
end;
end;
procedure EnumerateValueCaps(HidDev: TJvHidDevice; Parent: TTreeNode;
ReportType: THIDPReportType; ReportText: string);
var
I: Integer;
Ret: Integer;
N: WORD;
UsagePageText: string;
UsageText: string;
// 256 Caps entries should be always sufficient
ValCaps: array [0..255] of THIDPValueCaps;
begin
N := 255;
// get ALL ValueCaps of the specified ReportType
HidDev.ReportTypeParam := ReportType;
Ret := HidDev.GetSpecificValueCaps(@ValCaps[0], N);
if Ret = HIDP_STATUS_SUCCESS then
for I := 0 to N-1 do
if ValCaps[I].LinkCollection = Idx then
begin
UsageAndUsagePageText(ValCaps[I].UsagePage, ValCaps[I].Usage, UsagePageText, UsageText);
if ValCaps[I].IsRange then
DeviceTree.Items.AddChild(Parent,
Format('Value %s Range: UsagePage=%s ($%.4x) %d..%d',
[ReportText, UsagePageText, ValCaps[I].UsagePage, ValCaps[I].UsageMin, ValCaps[I].UsageMax]))
else
DeviceTree.Items.AddChild(Parent,
Format('Value %s: UsagePage=%s ($%.4x) Usage=%s ($%.4x)',
[ReportText, UsagePageText, ValCaps[I].UsagePage, UsageText, ValCaps[I].Usage]));
end;
end;
begin
// set the params to get ALL Caps
HidDev.UsagePageParam := 0;
HidDev.UsageParam := 0;
HidDev.LinkCollectionParam := HIDP_LINK_COLLECTION_UNSPECIFIED;
EnumerateButtonCaps(HidDev, Parent, HidP_Input, 'Input');
EnumerateButtonCaps(HidDev, Parent, HidP_Output, 'Output');
EnumerateButtonCaps(HidDev, Parent, HidP_Feature, 'Feature');
EnumerateValueCaps (HidDev, Parent, HidP_Input, 'Input');
EnumerateValueCaps (HidDev, Parent, HidP_Output, 'Output');
EnumerateValueCaps (HidDev, Parent, HidP_Feature, 'Feature');
end;
procedure TCollectionDemoForm.EnumerateNodes(HidDev: TJvHidDevice;
Parent: TTreeNode; Idx: Word; NumSiblings: Word);
var
I: Word;
Node: TTreeNode;
UsagePageText: string;
UsageText: string;
CollectionTypeText: string;
NodeText: string;
begin
// add a list of sibling nodes to the device tree node Parent
for I := 1 to NumSiblings do
begin
UsageAndUsagePageText(HidDev.LinkCollectionNodes[Idx].LinkUsagePage,
HidDev.LinkCollectionNodes[Idx].LinkUsage, UsagePageText, UsageText);
case HidDev.LinkCollectionNodes[Idx].CollectionType of
$00:
CollectionTypeText := 'Physical';
$01:
CollectionTypeText := 'Application';
$02:
CollectionTypeText := 'Logical';
$03:
CollectionTypeText := 'Report';
$04:
CollectionTypeText := 'Named Array';
$05:
CollectionTypeText := 'Usage Switch';
$06:
CollectionTypeText := 'Usage Modifier';
$07..$7F:
CollectionTypeText := Format('Reserved $%.2x',
[Cardinal(HidDev.LinkCollectionNodes[Idx].CollectionType)]);
$80..$FF:
CollectionTypeText := Format('Vendor-defined $%.2x',
[Cardinal(HidDev.LinkCollectionNodes[Idx].CollectionType)]);
end;
NodeText :=
'UsagePage=' + UsagePageText + Format(' ($%.4x) ', [HidDev.LinkCollectionNodes[Idx].LinkUsagePage]) +
'Usage=' + UsageText + Format(' ($%.4x) ', [HidDev.LinkCollectionNodes[Idx].LinkUsage]) +
'CollectionType=' + CollectionTypeText + Format(' ($%.2x)', [HidDev.LinkCollectionNodes[Idx].CollectionType]);
if HidDev.LinkCollectionNodes[Idx].IsAlias <> 0 then
NodeText := NodeText + ' IsAlias';
Node := DeviceTree.Items.AddChild(Parent, NodeText);
EnumerateCaps(HidDev, Node, Idx);
// recurse to the children nodes
if HidDev.LinkCollectionNodes[Idx].FirstChild <> 0 then
EnumerateNodes(HidDev, Node,
HidDev.LinkCollectionNodes[Idx].FirstChild,
HidDev.LinkCollectionNodes[Idx].NumberOfChildren);
// secure against buggy descriptors
if HidDev.LinkCollectionNodes[Idx].NextSibling <> 0 then
// follow the link to the next sibling
Idx := HidDev.LinkCollectionNodes[Idx].NextSibling
else
Break;
end;
end;
function TCollectionDemoForm.HidCtlEnumerate(HidDev: TJvHidDevice;
Index: Integer): Boolean;
var
Idx: Word;
Node: TTreeNode;
Name: string;
begin
// give the treeview node for the device a descriptive name
if HidDev.ProductName <> '' then
Name := Format('"%s" VID=$%.4x PID=$%.4x',
[HidDev.ProductName, HidDev.Attributes.VendorID, HidDev.Attributes.ProductID])
else
Name := Format('VID=$%.4x PID=$%.4x',
[HidDev.Attributes.VendorID, HidDev.Attributes.ProductID]);
Node := DeviceTree.Items.AddChild(Root, Name);
// there is only one root node, but we try to enumerate siblings anyway
// in case there is a bad descriptor
Idx := 0;
repeat
EnumerateNodes(HidDev, Node, Idx, 1);
Idx := HidDev.LinkCollectionNodes[Idx].NextSibling;
until Idx = 0;
DeviceTree.FullExpand;
Result := True;
end;
procedure TCollectionDemoForm.SaveClick(Sender: TObject);
begin
// write the treeview content to a file to avoid the need
// to send screenshots
if SaveDialog.Execute then
DeviceTree.SaveToFile(SaveDialog.FileName);
end;
end.