📄 collectionmain.pas
字号:
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 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.HidCtlDeviceChange(Sender: TObject);
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;
DeviceTree.FullExpand;
DeviceTree.Select(Root, []);
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;
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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -