📄 collectionmain.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "CollectionMain.h"
#include "UsagesInfo.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "JvHidControllerClass"
#pragma resource "*.dfm"
TCollectionDemoForm *CollectionDemoForm;
//---------------------------------------------------------------------------
__fastcall TCollectionDemoForm::TCollectionDemoForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TCollectionDemoForm::FormShow(TObject *Sender)
{
// this compensates the possibility that HidCtlDeviceChange
// may not be able to fill the treeview the first time
HidCtlDeviceChange(this);
}
//---------------------------------------------------------------------------
void __fastcall TCollectionDemoForm::HidCtlDeviceChange(TObject *Sender)
{
// HidCtlDeviceChange happens before TCollectionDemoForm.Create completed
// DeviceTree may have not been created yet
if(DeviceTree != NULL)
{
// each time something happens to the HID devices the treeview is filled
DeviceTree->Items->Clear();
Root = DeviceTree->Items->Add(NULL, "HID-Devices");
HidCtl->Enumerate();
}
}
//---------------------------------------------------------------------------
void __fastcall TCollectionDemoForm::EnumerateButtonCaps(TJvHidDevice *HidDev,
TTreeNode *Parent, WORD Idx, THIDPReportType ReportType,
char *ReportText)
{
int I;
int Ret;
WORD N;
AnsiString UsagePageText;
AnsiString UsageText;
AnsiString S;
// 256 Caps entries should be always sufficient
THIDPButtonCaps BtnCaps[256];
N = 255;
// get ALL ButtonCaps of the specified ReportType
HidDev->ReportTypeParam = ReportType;
Ret = HidDev->GetSpecificButtonCaps(BtnCaps, N);
if(Ret == HIDP_STATUS_SUCCESS)
for(I = 0; I < N; I++)
if(BtnCaps[I].LinkCollection == Idx)
{
UsageAndUsagePageText(BtnCaps[I].UsagePage, BtnCaps[I].Usage, &UsagePageText, &UsageText);
if(BtnCaps[I].IsRange)
DeviceTree->Items->AddChild(Parent,
S.sprintf("Button %s Range: UsagePage=%s (0x%04X) %d..%d",
ReportText, UsagePageText, BtnCaps[I].UsagePage, BtnCaps[I].UsageMin, BtnCaps[I].UsageMax));
else
DeviceTree->Items->AddChild(Parent,
S.sprintf("Button %s: UsagePage=%s (0x%04X) Usage=%s (0x%04X)",
ReportText, UsagePageText, BtnCaps[I].UsagePage, UsageText, BtnCaps[I].Usage));
}
}
//---------------------------------------------------------------------------
void __fastcall TCollectionDemoForm::EnumerateValueCaps(TJvHidDevice *HidDev,
TTreeNode *Parent, WORD Idx, THIDPReportType ReportType,
char *ReportText)
{
int I;
int Ret;
WORD N;
AnsiString UsagePageText;
AnsiString UsageText;
AnsiString S;
// 256 Caps entries should be always sufficient
THIDPValueCaps ValCaps[256];
N = 255;
// get ALL ButtonCaps of the specified ReportType
HidDev->ReportTypeParam = ReportType;
Ret = HidDev->GetSpecificValueCaps(ValCaps, N);
if(Ret == HIDP_STATUS_SUCCESS)
for(I = 0; I < N; I++)
if(ValCaps[I].LinkCollection == Idx)
{
UsageAndUsagePageText(ValCaps[I].UsagePage, ValCaps[I].Usage, &UsagePageText, &UsageText);
if(ValCaps[I].IsRange)
DeviceTree->Items->AddChild(Parent,
S.sprintf("Button %s Range: UsagePage=%s (0x%04X) %d..%d",
ReportText, UsagePageText, ValCaps[I].UsagePage, ValCaps[I].UsageMin, ValCaps[I].UsageMax));
else
DeviceTree->Items->AddChild(Parent,
S.sprintf("Button %s: UsagePage=%s (0x%04X) Usage=%s (0x%04X)",
ReportText, UsagePageText, ValCaps[I].UsagePage, UsageText, ValCaps[I].Usage));
}
}
//---------------------------------------------------------------------------
void __fastcall TCollectionDemoForm::EnumerateCaps(TJvHidDevice *HidDev,
TTreeNode *Parent, Word Idx)
{
// set the params to get ALL Caps
HidDev->UsagePageParam = 0;
HidDev->UsageParam = 0;
HidDev->LinkCollectionParam = HIDP_LINK_COLLECTION_UNSPECIFIED;
EnumerateButtonCaps(HidDev, Parent, Idx, HidP_Input, "Input");
EnumerateButtonCaps(HidDev, Parent, Idx, HidP_Output, "Output");
EnumerateButtonCaps(HidDev, Parent, Idx, HidP_Feature, "Feature");
EnumerateValueCaps (HidDev, Parent, Idx, HidP_Input, "Input");
EnumerateValueCaps (HidDev, Parent, Idx, HidP_Output, "Output");
EnumerateValueCaps (HidDev, Parent, Idx, HidP_Feature, "Feature");
}
//---------------------------------------------------------------------------
void __fastcall TCollectionDemoForm::EnumerateNodes(TJvHidDevice *HidDev,
TTreeNode *Parent, Word Idx, Word NumSiblings)
{
Word I;
TTreeNode *Node;
AnsiString UsagePageText;
AnsiString UsageText;
AnsiString CollectionTypeText;
AnsiString NodeText;
// add a list of sibling nodes to the device tree node Parent
for(I = 1; I <= NumSiblings; I++)
{
UsageAndUsagePageText(HidDev->LinkCollectionNodes[Idx].LinkUsagePage,
HidDev->LinkCollectionNodes[Idx].LinkUsage, &UsagePageText, &UsageText);
if(HidDev->LinkCollectionNodes[Idx].CollectionType >= 0x07 &&
HidDev->LinkCollectionNodes[Idx].CollectionType <= 0x7F)
CollectionTypeText.sprintf("Reserved 0x%02X",
Cardinal(HidDev->LinkCollectionNodes[Idx].CollectionType));
else
switch(HidDev->LinkCollectionNodes[Idx].CollectionType)
{
case 0x00:
CollectionTypeText = "Physical";
break;
case 0x01:
CollectionTypeText = "Application";
break;
case 0x02:
CollectionTypeText = "Logical";
break;
case 0x03:
CollectionTypeText = "Report";
break;
case 0x04:
CollectionTypeText = "Named Array";
break;
case 0x05:
CollectionTypeText = "Usage Switch";
break;
case 0x06:
CollectionTypeText = "Usage Modifier";
break;
default:
CollectionTypeText.sprintf("Vendor-defined $%.2x",
Cardinal(HidDev->LinkCollectionNodes[Idx].CollectionType));
break;
}
NodeText.sprintf("UsagePage=%s (0x%04X) Usage=%s (0x%04X) CollectionType=%s (0x%02X)",
UsagePageText, HidDev->LinkCollectionNodes[Idx].LinkUsagePage,
UsageText, HidDev->LinkCollectionNodes[Idx].LinkUsage,
CollectionTypeText, HidDev->LinkCollectionNodes[Idx].CollectionType);
if(HidDev->LinkCollectionNodes[Idx].IsAlias != 0)
NodeText = NodeText + " IsAlias";
Node = DeviceTree->Items->AddChild(Parent, NodeText);
EnumerateCaps(HidDev, Node, Idx);
// recurse to the children nodes
if(HidDev->LinkCollectionNodes[Idx].FirstChild != 0)
EnumerateNodes(HidDev, Node,
HidDev->LinkCollectionNodes[Idx].FirstChild,
HidDev->LinkCollectionNodes[Idx].NumberOfChildren);
// secure against buggy descriptors
if(HidDev->LinkCollectionNodes[Idx].NextSibling != 0)
// follow the link to the next sibling
Idx = HidDev->LinkCollectionNodes[Idx].NextSibling;
else
break;
}
}
//---------------------------------------------------------------------------
bool __fastcall TCollectionDemoForm::HidCtlEnumerate(
TJvHidDevice *HidDev, const int Idx)
{
Word Index;
TTreeNode *Node;
AnsiString Name;
// give the treeview node for the device a descriptive name
if(HidDev->ProductName != NULL)
Name.sprintf("\"%S\" VID=0x%.4X PID=0x%.4X",
HidDev->ProductName, HidDev->Attributes.VendorID, HidDev->Attributes.ProductID);
else
Name.sprintf("VID=0x%.4X PID=0x%.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
Index = 0;
do
{
EnumerateNodes(HidDev, Node, Idx, 1);
Index = HidDev->LinkCollectionNodes[Index].NextSibling;
}
while(Index != 0);
DeviceTree->FullExpand();
return(true);
}
//---------------------------------------------------------------------------
void __fastcall TCollectionDemoForm::SaveClick(TObject *Sender)
{
// write the treeview content to a file to avoid the need
// to send screenshots
if(SaveDialog->Execute())
DeviceTree->SaveToFile(SaveDialog->FileName);
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -