Vitor Domingos
Members-
Content Count
5 -
Joined
-
Last visited
Everything posted by Vitor Domingos
-
Difficulty with XKeys PIEHid32.dll in Delphi 10 Seattle
Vitor Domingos posted a topic in General Help
I am having trouble using the XKeys PIEHid32.dll in Delphi 10 Seattle. The issue occurs when trying to send and receive information, and I keep getting the following error: "read of address 0x00000000'. Process Stopped. Use Step or Run to continue." I am not sure what else to try to resolve this. Below is the code I am currently using: delphi """ unit Unit4; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Vcl.ExtCtrls; const PI_VID = $05F3; MAX_XKEY_DEVICES = 128; {$ALIGN 1} type TDevicePath = array[0..255] of AnsiChar; TString128 = array[0..127] of AnsiChar; TEnumHIDInfo = packed record PID: DWORD; Usage: DWORD; UP: DWORD; readSize: LongInt; writeSize: LongInt; DevicePath: TDevicePath; Handle: DWORD; Version: DWORD; ManufacturerString: TString128; ProductString: TString128; SerialNumberString: TString128; end; {$ALIGN ON} type // Declaração das funções TEnumeratePIE = function(VID: LongInt; info: PEnumHIDInfo; var count: LongInt): DWORD; stdcall; TSetupInterfaceEx = function(hnd: LongInt): DWORD; stdcall; TWriteData = function(hnd: LongInt; data: PByte): DWORD; stdcall; TBlockingReadData = function(hnd: LongInt; data: PByte; maxMillis: Integer): DWORD; stdcall; TSetDataCallback = function(hnd: LongInt; pDataEvent: PHIDDataEvent): DWORD; stdcall; TSetErrorCallback = function(hnd: LongInt; pErrorCall: PHIDErrorEvent): DWORD; stdcall; TGetWriteLength = function(hnd: LongInt): DWORD; stdcall; TForm4 = class(TForm) ButtonEnumerate: TButton; Memo2: TMemo; ButtonChangeColor: TButton; procedure ButtonEnumerateClick(Sender: TObject); procedure ButtonChangeColorClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private procedure EnumerateAndSetupDevices; procedure SetCallback; function GetErrorMessage(ErrorCode: DWORD): string; public end; var Form4: TForm4; MainForm: TForm4; // Variáveis globais DLLHandle: THandle; // Funções da DLL EnumeratePIE: TEnumeratePIE; SetupInterfaceEx: TSetupInterfaceEx; WriteData: TWriteData; BlockingReadData: TBlockingReadData; SetDataCallback: TSetDataCallback; SetErrorCallback: TSetErrorCallback; GetWriteLength: TGetWriteLength; DeviceHandle: LongInt; CurrentColor: Integer = 6; implementation {$R *.dfm} // Callback de dados function HandleDataEvent(pData: PByte; deviceID: DWORD; error: DWORD): DWORD; stdcall; begin Result := 0; // Retorna 0 indicando sucesso if Assigned(MainForm) then begin TThread.Synchronize(nil, procedure var DataStr: string; i: Integer; KeyStates: array[0..31] of Byte; KeyIndex: Integer; begin if error = 0 then begin // Copiar os dados recebidos para um array Move(pData^, KeyStates, 32); // Analisar as teclas pressionadas for i := 0 to 31 do begin if KeyStates <> 0 then begin for KeyIndex := 0 to 7 do begin if (KeyStates and (1 shl KeyIndex)) <> 0 then begin // Uma tecla foi pressionada DataStr := Format('Tecla %d pressionada', [(i * 😎 + KeyIndex + 1]); MainForm.Memo2.Lines.Add(DataStr); end; end; end; end; end else begin MainForm.Memo2.Lines.Add('Error occurred: ' + MainForm.GetErrorMessage(error)); end; end); end; end; // Callback de erro function HandleErrorEvent(deviceID: DWORD; status: DWORD): DWORD; stdcall; begin Result := 0; // Retorna 0 indicando sucesso if Assigned(MainForm) then begin TThread.Synchronize(nil, procedure begin MainForm.Memo2.Lines.Add('Error callback from device ' + IntToStr(deviceID) + ' with status ' + MainForm.GetErrorMessage(status)); end); end; end; procedure TForm4.FormCreate(Sender: TObject); begin MainForm := Self; // Carregar a DLL DLLHandle := LoadLibrary('PIEHid.dll'); if DLLHandle = 0 then begin Memo2.Lines.Add('Não foi possível carregar a DLL PIEHid.dll.'); Exit; end else begin Memo2.Lines.Add('DLL PIEHid.dll carregada com sucesso.'); end; // Obter as funções da DLL @EnumeratePIE := GetProcAddress(DLLHandle, 'EnumeratePIE'); @SetupInterfaceEx := GetProcAddress(DLLHandle, 'SetupInterfaceEx'); @WriteData := GetProcAddress(DLLHandle, 'WriteData'); @BlockingReadData := GetProcAddress(DLLHandle, 'BlockingReadData'); @SetDataCallback := GetProcAddress(DLLHandle, 'SetDataCallback'); @SetErrorCallback := GetProcAddress(DLLHandle, 'SetErrorCallback'); @GetWriteLength := GetProcAddress(DLLHandle, 'GetWriteLength'); // Verificar se todas as funções foram carregadas corretamente if not Assigned(EnumeratePIE) or not Assigned(SetupInterfaceEx) or not Assigned(WriteData) or not Assigned(BlockingReadData) or not Assigned(SetDataCallback) or not Assigned(SetErrorCallback) or not Assigned(GetWriteLength) then begin Memo2.Lines.Add('Erro ao carregar funções da DLL.'); Exit; end; end; procedure TForm4.FormDestroy(Sender: TObject); begin // Liberar a DLL if DLLHandle <> 0 then begin FreeLibrary(DLLHandle); DLLHandle := 0; end; MainForm := nil; end; procedure TForm4.ButtonEnumerateClick(Sender: TObject); begin EnumerateAndSetupDevices; end; procedure TForm4.EnumerateAndSetupDevices; var Info: array[0..MAX_XKEY_DEVICES - 1] of TEnumHIDInfo; Count: LongInt; VID: Word; ResultCode, SetupResult: DWORD; I: Integer; WriteLength: DWORD; begin if DLLHandle = 0 then begin Memo2.Lines.Add('A DLL não foi carregada. Não é possível continuar.'); Exit; end; Memo2.Lines.Add('Chamando EnumeratePIE...'); VID := PI_VID; Count := 0; ResultCode := EnumeratePIE(VID, @Info[0], Count); Memo2.Lines.Add('ResultCode de EnumeratePIE: ' + IntToStr(ResultCode)); Memo2.Lines.Add('Count de dispositivos encontrados: ' + IntToStr(Count)); if ResultCode = 0 then begin if Count > 0 then begin for I := 0 to Count - 1 do begin // Obter o Write Length WriteLength := GetWriteLength(Info.Handle); Memo2.Lines.Add(Format('Dispositivo %d - PID: %d, Handle: %d, Versão: %d, UsagePage: %d, WriteLength: %d', [I, Info.PID, Info.Handle, Info.Version, Info.UP, WriteLength])); if Info.PID = $0419 then begin Memo2.Lines.Add('Tentando configurar dispositivo com Handle: ' + IntToStr(Info.Handle)); SetupResult := SetupInterfaceEx(Info.Handle); Memo2.Lines.Add('Resultado de SetupInterfaceEx: ' + IntToStr(SetupResult)); if SetupResult = 0 then begin DeviceHandle := Info.Handle; Memo2.Lines.Add('DeviceHandle atribuído: ' + IntToStr(DeviceHandle)); SetCallback; Break; // Sair do loop após configurar o dispositivo end else begin Memo2.Lines.Add('Falha ao configurar o dispositivo. SetupResult: ' + IntToStr(SetupResult)); end; end else begin Memo2.Lines.Add('Dispositivo ignorado (PID não corresponde).'); end; end; end else begin Memo2.Lines.Add('Nenhum dispositivo encontrado.'); end; end else begin Memo2.Lines.Add('Erro ao enumerar dispositivos. Código de erro: ' + IntToStr(ResultCode)); end; end; procedure TForm4.SetCallback; var ResultCode: DWORD; begin if DeviceHandle = 0 then begin Memo2.Lines.Add('DeviceHandle é zero. Não é possível configurar callbacks.'); Exit; end; ResultCode := SetDataCallback(DeviceHandle, @HandleDataEvent); if ResultCode = 0 then Memo2.Lines.Add('Callback de dados configurado com sucesso.') else Memo2.Lines.Add('Erro ao configurar o callback de dados. Código de erro: ' + IntToStr(ResultCode)); ResultCode := SetErrorCallback(DeviceHandle, @HandleErrorEvent); if ResultCode = 0 then Memo2.Lines.Add('Callback de erro configurado com sucesso.') else Memo2.Lines.Add('Erro ao configurar o callback de erro. Código de erro: ' + IntToStr(ResultCode)); end; function TForm4.GetErrorMessage(ErrorCode: DWORD): string; begin case ErrorCode of 0: Result := 'Success'; // Adicione outros códigos de erro conforme necessário else Result := 'Unknown error (' + IntToStr(ErrorCode) + ')'; end; end; procedure TForm4.ButtonChangeColorClick(Sender: TObject); var Buffer: array[0..35] of Byte; ResultWriteData: DWORD; begin if DeviceHandle = 0 then begin Memo2.Lines.Add('DeviceHandle é zero. O dispositivo não foi configurado corretamente.'); Exit; end; FillChar(Buffer, SizeOf(Buffer), 0); Buffer[0] := 0; // Report ID Buffer[1] := $B3; // Comando para controlar o LED // Alternar entre verde (6) e vermelho (7) if CurrentColor = 6 then CurrentColor := 7 else CurrentColor := 6; Buffer[2] := CurrentColor; // 6 = verde, 7 = vermelho Buffer[3] := 1; // 0 = desligado, 1 = ligado, 2 = piscar ResultWriteData := WriteData(DeviceHandle, @Buffer[0]); if ResultWriteData = 0 then begin if CurrentColor = 6 then Memo2.Lines.Add('Cor alterada para verde com sucesso.') else Memo2.Lines.Add('Cor alterada para vermelho com sucesso.'); end else begin Memo2.Lines.Add('Erro ao alterar a cor. Código de erro: ' + IntToStr(ResultWriteData) + ' - ' + GetErrorMessage(ResultWriteData)); end; end; end. """ I would greatly appreciate any help or guidance on how to fix this error and get the communication working properly. Thank you in advance for your attention. -
Difficulty with XKeys PIEHid32.dll in Delphi 10 Seattle
Vitor Domingos replied to Vitor Domingos's topic in General Help
Thank you very much, I've been at this for a long time, I've already done this code 5 times and I don't understand why it doesn't work -
Difficulty with XKeys PIEHid32.dll in Delphi 10 Seattle
Vitor Domingos replied to Vitor Domingos's topic in General Help
I have already tried both methods, and the result was the same. I noticed that you have done something similar before. Would you mind sharing it with me? -
Difficulty with XKeys PIEHid32.dll in Delphi 10 Seattle
Vitor Domingos replied to Vitor Domingos's topic in General Help
I will share a new code, as the one I previously sent was an old version. Here is the updated code: ---- cod.txt ----. Here’s what’s happening: In the "EnumeratePIE" function, it returns the values correctly, but when trying to connect using "SetupInterface" with the handle, the connection doesn’t happen. I noticed that the Usage Page (UP) value was 0, so I changed it, and then the connection worked. I was able to make the X-Keys switch between red and green, but when I tried to receive information using "BlockingReadData", it didn’t work at all. cod.txt -
Difficulty with XKeys PIEHid32.dll in Delphi 10 Seattle
Vitor Domingos replied to Vitor Domingos's topic in General Help
The error occurs after exiting the procedure "EnumerateAndSetupDevices". I got the function information from the XKeys documentation and the open-source C++ code. There is a file called PIEHid32.h, from which I copied the functions and adapted them to Delphi.