Search the Community
Showing results for tags 'p.i. engineering xkeys keyboards'.
Found 1 result
-
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.