📄 jvhidcontrollerclass.pas
字号:
end;
Result := FPhysicalDescriptor;
end;
function TJvHidDevice.GetLanguageStrings: TStrings;
var
I: Integer;
Len: Integer;
IDs: array [0..253] of WORD;
Name: array [0..255] of Char;
begin
if FLanguageStrings.Count = 0 then
if OpenFile then
begin
// calculate length of StringDescriptor 0
FillChar(IDs, SizeOf(IDs), $FF);
Len := 0;
if HidD_GetIndexedString(HidFileHandle, 0, PWideChar(@IDs), SizeOf(IDs)) then
for I := High(IDs) downto 0 do
if IDs[I] <> $FFFF then
begin
if IDs[I] = 0 then
Len := I
else
Len := I + 1;
Break;
end;
// transform id into localized language name
for I := 0 to Len - 1 do
begin
Name[0] := #0;
if GetLocaleInfo(WORD(IDs[I]), LOCALE_SLANGUAGE, Name, SizeOf(Name)) <> 0 then
FLanguageStrings.Add(Name)
else
FLanguageStrings.Add(Format(RsUnknownLocaleIDFmt, [WORD(IDs[I])]));
end;
CloseFile;
end;
Result := FLanguageStrings;
end;
function TJvHidDevice.GetOverlappedReadResult: DWORD;
begin
Result := 0;
if HidOverlappedRead <> INVALID_HANDLE_VALUE then
if not GetOverlappedResult(HidOverlappedRead, FOvlRead, Result, False) then
Result := 0;
end;
function TJvHidDevice.GetOverlappedWriteResult: DWORD;
begin
Result := 0;
if HidOverlappedWrite <> INVALID_HANDLE_VALUE then
if not GetOverlappedResult(HidOverlappedWrite, FOvlWrite, Result, False) then
Result := 0;
end;
procedure TJvHidDevice.SetConfiguration(const Config: THIDDConfiguration);
begin
if OpenFile then
HidD_SetConfiguration(HidFileHandle, Config, SizeOf(THIDDConfiguration));
end;
procedure TJvHidDevice.SetDataEvent(const DataEvent: TJvHidDataEvent);
begin
// this assignment is a bit tricky because a thread may be running
// kill the thread with the old event still in effect
if not Assigned(DataEvent) then
StopThread;
// assign the new event and start the thread if needed
FData := DataEvent;
StartThread;
end;
procedure TJvHidDevice.StartThread;
begin
if Assigned(FData) and IsPluggedIn and IsCheckedOut and
HasReadWriteAccess and not Assigned(FDataThread) then
begin
FDataThread := TJvHidDeviceReadThread.CtlCreate(Self);
FDataThread.FreeOnTerminate := False;
FDataThread.Resume;
end;
end;
procedure TJvHidDevice.StopThread;
begin
if Assigned(FDataThread) then
begin
FDataThread.Terminate;
FDataThread.WaitFor;
FDataThread.Free;
FDataThread := nil;
end;
end;
// TJvHidDevice methods:
// generally the parameter count of the methods is reduced with the Param properties
// first assign the Param properties the desired value then call a method
// normally you will address the same Usage, UsagePage, ReportType or LinkCollection
// with more than one method
//
// the methods will open the device file when needed
// this file is not closed until unplug or destruction to speed up access
// cancel asynchronous operations on either HidOverlappedRead or HidOverlappedWrite
function TJvHidDevice.CancelIO(const Mode: TJvHidOpenExMode): Boolean;
function CallCancelIO(Handle: THandle): Boolean;
type
TCancelIOFunc = function(hFile: THandle): BOOL; stdcall;
var
hKernel: TModuleHandle;
CancelIOFunc: TCancelIOFunc;
begin
hKernel := INVALID_HANDLE_VALUE;
Result := LoadModule(hKernel, Kernel32DllName);
if Result then
begin
@CancelIOFunc := GetModuleSymbol(hKernel, 'CancelIO');
if Assigned(CancelIOFunc) then
Result := CancelIOFunc(Handle)
else
Result := False;
UnloadModule(hKernel);
end;
end;
begin
Result := False;
if (Mode = omhRead) and (HidOverlappedRead <> INVALID_HANDLE_VALUE) then
Result := CallCancelIO(HidOverlappedRead)
else
if (Mode = omhWrite) and (HidOverlappedWrite <> INVALID_HANDLE_VALUE) then
Result := CallCancelIO(HidOverlappedWrite);
end;
// close the device "file"
// if you want to open the file directly close this
// to get undisturbed access
procedure TJvHidDevice.CloseFile;
begin
if HidFileHandle <> INVALID_HANDLE_VALUE then
CloseHandle(HidFileHandle);
FNumInputBuffers := 0;
FHidFileHandle := INVALID_HANDLE_VALUE;
end;
// same for the other device "file"
procedure TJvHidDevice.CloseFileEx(const Mode: TJvHidOpenExMode);
begin
if Mode = omhRead then
begin
if HidOverlappedRead <> INVALID_HANDLE_VALUE then
CloseHandle(HidOverlappedRead);
FNumOverlappedBuffers := 0;
FHidOverlappedRead := INVALID_HANDLE_VALUE;
end
else
begin
if HidOverlappedWrite <> INVALID_HANDLE_VALUE then
CloseHandle(HidOverlappedWrite);
FHidOverlappedWrite := INVALID_HANDLE_VALUE;
end;
end;
// all the methods which directly map to a HID-function
function TJvHidDevice.FlushQueue: Boolean;
begin
Result := False;
if OpenFile then
Result := HidD_FlushQueue(HidFileHandle);
end;
function TJvHidDevice.GetFeature(var Report; const Size: Integer): Boolean;
begin
Result := False;
if OpenFile then
Result := HidD_GetFeature(HidFileHandle, Report, Size);
end;
function TJvHidDevice.SetFeature(var Report; const Size: Integer): Boolean;
begin
Result := False;
if OpenFile then
Result := HidD_SetFeature(HidFileHandle, Report, Size);
end;
function TJvHidDevice.GetSpecificButtonCaps(ButtonCaps: PHIDPButtonCaps; var Count: WORD): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetSpecificButtonCaps(ReportTypeParam, UsagePageParam,
LinkCollectionParam, UsageParam, ButtonCaps, Count, PreparsedData);
end;
function TJvHidDevice.GetButtonCaps(ButtonCaps: PHIDPButtonCaps; var Count: WORD): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetButtonCaps_(ReportTypeParam, ButtonCaps, Count, PreparsedData);
end;
function TJvHidDevice.GetSpecificValueCaps(ValueCaps: PHIDPValueCaps; var Count: WORD): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetSpecificValueCaps(ReportTypeParam, UsagePageParam,
LinkCollectionParam, UsageParam, ValueCaps, Count, PreparsedData);
end;
function TJvHidDevice.GetValueCaps(ValueCaps: PHIDPValueCaps; var Count: WORD): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetValueCaps_(ReportTypeParam, ValueCaps, Count, PreparsedData);
end;
function TJvHidDevice.GetData(DataList: PHIDPData; var DataLength: ULONG;
var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetData(ReportTypeParam, DataList, DataLength, PreparsedData,
Report, ReportLength);
end;
function TJvHidDevice.SetData(DataList: PHIDPData; var DataLength: ULONG;
var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_SetData(ReportTypeParam, DataList, DataLength, PreparsedData,
Report, ReportLength);
end;
function TJvHidDevice.GetUsages(UsageList: PUsage; var UsageLength: ULONG;
var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetUsages(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageList, UsageLength, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.GetButtons(UsageList: PUsage; var UsageLength: ULONG;
var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetButtons(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageList, UsageLength, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.GetUsagesEx(UsageList: PUsageAndPage; var UsageLength: ULONG;
var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetUsagesEx(ReportTypeParam, LinkCollectionParam, UsageList,
UsageLength, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.GetButtonsEx(UsageList: PUsageAndPage; var UsageLength: ULONG;
var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetButtonsEx(ReportTypeParam, LinkCollectionParam, UsageList,
UsageLength, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.SetUsages(UsageList: PUsage; var UsageLength: ULONG;
var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_SetUsages(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageList, UsageLength, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.SetButtons(UsageList: PUsage; var UsageLength: ULONG;
var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_SetButtons(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageList, UsageLength, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.UnsetUsages(UsageList: PUsage; var UsageLength: ULONG;
var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_UnsetUsages(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageList, UsageLength, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.UnsetButtons(UsageList: PUsage; var UsageLength: ULONG;
var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_UnsetButtons(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageList, UsageLength, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.GetUsageValue(var UsageValue: ULONG; var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetUsageValue(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageParam, UsageValue, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.GetScaledUsageValue(var UsageValue: Integer;
var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetScaledUsageValue(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageParam, UsageValue, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.GetUsageValueArray(UsageValue: PChar;
UsageValueByteLength: WORD; var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_GetUsageValueArray(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageParam, UsageValue, UsageValueByteLength, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.SetUsageValue(UsageValue: ULONG; var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_SetUsageValue(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageParam, UsageValue, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.SetScaledUsageValue(UsageValue: Integer; var Report;
ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_SetScaledUsageValue(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageParam, UsageValue, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.SetUsageValueArray(UsageValue: PChar;
UsageValueByteLength: WORD; var Report; ReportLength: ULONG): NTSTATUS;
begin
Result := HIDP_STATUS_NULL; // for not plugged in
if IsAccessible then
Result := HidP_SetUsageValueArray(ReportTypeParam, UsagePageParam, LinkCollectionParam,
UsageParam, UsageValue, UsageValueByteLength, PreparsedData, Report, ReportLength);
end;
function TJvHidDevice.DeviceIoControl(IoControlCode: DWORD; InBuffer: Pointer; InSize: DWORD;
OutBuffer: Pointer; OutSize: DWORD; var BytesReturned: DWORD): Boolean;
begin
Result := False;
if OpenFile then
Result := Windows.DeviceIoControl(HidFileHandle, IoControlCode, InBuffer, InSize,
OutBuffer, OutSize, BytesReturned, nil);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -