Найти HID / PID в интерфейсе DELPHI / ARDUINO - PullRequest
0 голосов
/ 24 августа 2018

(Во-первых, я не уверен, помещен ли этот вопрос в правильный раздел Stack Exchange. Если нет, пожалуйста, сообщите мне об этом и удалите вопрос.)

У меня 8 Ардуино (Ардс). Некоторые Uno и 2650 Mega. В попытке автоматизировать процесс соединения (я использую Delphi D-7 SE в качестве ввода / вывода), я хочу провести различие между UNO и 2650 (в основном из-за аппаратных различий в соответствующем чипе). Способ сделать это (я думаю), это получить PID и VID с платы. Но я не знаю, как это сделать. Код ниже дает мне правильный драйвер, но не PID / VID. Можно ли получить PID / VID для этого фрагмента кода? ЕСЛИ так, КАК?

Большое спасибо.

Код здесь:

unit ArduinoTestU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, JVsetupAPI, Registry, StdCtrls,
  CPortCtl, CPort, Menus, XPMan;

type
  TMainForm = class(TForm)
    ListBox1: TListBox;
    Label1: TLabel;
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    function  SetupEnumAvailableComPorts  :  TstringList;
    procedure ListBox1Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure Button1Click(Sender: TObject);

  private
    { Private declarations }
  public
    ArdType :  Integer;
  end;

var
  MainForm          : TMainForm;
  ComPortStringList : TStringList;
  MyComPort         : String;
  CurDir            : String;

implementation

uses Form1Unit, ArdFormU; (* , ArdFormU;  *)



{$R *.dfm}

procedure TMainForm.Button1Click(Sender: TObject);
begin
   MainForm.FormActivate(NIL);
end;

procedure TMainForm.FormActivate(Sender: TObject);
var
   index : integer;

begin
   ComPortStringList := SetupEnumAvailableComPorts;
   if (ComPortStringList <> nil) and (ComPortStringList.Count > 0) then
      for Index := 0 to ComPortStringList.Count - 1 do
         Listbox1.Items.Add(ComPortStringList[Index]);
   if Listbox1.Items.Count <> 0 then
      BEGIN
         Listbox1.Enabled := True;
         Button1.Enabled := False;
      END;
end;

procedure TMainForm.FormCreate(Sender: TObject);
BEGIN
   Curdir := ExtractFileDir(Application.Exename);
end;

(*
The function below returns a list of available COM-ports
(not open by this or an other process), with friendly names. The list is formatted as follows:

COM1: = Communications Port (COM1)
COM5: = NI Serial Port (Com5)
COM6: = NI Serial Port (Com6)
COM7: = USB Serial Port (COM7)
COM8: = Bluetooth Communications Port (COM8)
COM9: = Bluetooth Communications Port (COM9)

This code originally posted at http://www.delphi3000.com/articles/article_4001.asp?SK=
errors have been fixed so it will work with Delphi 7 and SetupAPI from JVCL
*)


function TMainForm.SetupEnumAvailableComPorts  :  TstringList;
//
// Enumerates all serial communications ports that are available and ready to
// be used.
//
var
  RequiredSize:             Cardinal;
  GUIDSize:                 DWORD;
  Guid:                     TGUID;
  DevInfoHandle:            HDEVINFO;
  DeviceInfoData:           TSPDevInfoData;
  MemberIndex:              Cardinal;
  PropertyRegDataType:      DWord;
  RegProperty:              Cardinal;
  RegTyp:                   Cardinal;
  Key:                      Hkey;
  Info:                     TRegKeyInfo;
  S1,S2:                    string;
  hc:                       THandle;

begin
   Result := Nil;
//
//If we cannot access the setupapi.dll then we return a nil pointer.
//
   if not LoadsetupAPI then
      exit;
   try
//
// get 'Ports' class guid from name
//
      GUIDSize := 1;    // missing from original code - need to tell function that the Guid structure contains a single GUID

      if SetupDiClassGuidsFromName('Ports',@Guid,GUIDSize,RequiredSize) then
         begin
//
//get object handle of 'Ports' class to interate all devices
//
            DevInfoHandle := SetupDiGetClassDevs(@Guid,Nil,0,DIGCF_PRESENT);
            if Cardinal(DevInfoHandle) <> Invalid_Handle_Value then
               begin
                  try
                     MemberIndex := 0;
                     result := TStringList.Create;

//iterate device list

                     repeat
                         FillChar(DeviceInfoData,SizeOf(DeviceInfoData),0);
                         DeviceInfoData.cbSize := SizeOf(DeviceInfoData);

//get device info that corresponds to the next memberindex

                         if Not SetupDiEnumDeviceInfo(DevInfoHandle,MemberIndex,DeviceInfoData) then
                            break;

//query friendly device name LIKE 'BlueTooth Communication Port (COM8)' etc

                         RegProperty := SPDRP_FriendlyName;  {SPDRP_Driver, SPDRP_SERVICE, SPDRP_ENUMERATOR_NAME,SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,SPDRP_FRIENDLYNAME,}
                         SetupDiGetDeviceRegistryProperty(DevInfoHandle, DeviceInfoData,RegProperty, PropertyRegDataType,NIL,0,RequiredSize);
                         SetLength(S1,RequiredSize);
                   //      ShowMessage('TEST:  ' + S1);

                         if SetupDiGetDeviceRegistryProperty(DevInfoHandle,DeviceInfoData,RegProperty,PropertyRegDataType,@S1[1],RequiredSize,RequiredSize) then
                            begin
                               KEY := SetupDiOpenDevRegKey(DevInfoHandle,DeviceInfoData,DICS_FLAG_GLOBAL,0,DIREG_DEV,KEY_READ);
                               if key <> INValid_Handle_Value then
                                  begin
                                     FillChar(Info, SizeOf(Info), 0);

//query the real port name from the registry value 'PortName'

                                     if RegQueryInfoKey(Key, nil, nil, nil, @Info.NumSubKeys,@Info.MaxSubKeyLen, nil, @Info.NumValues, @Info.MaxValueLen,
                                                        @Info.MaxDataLen, nil, @Info.FileTime) = ERROR_SUCCESS then
                                        begin
                                           RequiredSize := Info.MaxValueLen + 1;
                                           SetLength(S2,RequiredSize);




                                           if RegQueryValueEx(KEY,'PortName',Nil,@Regtyp,@s2[1],@RequiredSize) = Error_Success then
                                              begin
                                                 If (Pos('COM',S2) = 1) then
                                                    begin
                                                       //Test if the device can be used

                                                       hc := CreateFile(pchar('\\.\' + S2 + #0), GENERIC_READ or GENERIC_WRITE,
                                                             0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
                                                       if hc <> INVALID_HANDLE_VALUE then
                                                          begin
                                                             Result.Add(Strpas(PChar(S2)) + ' := ' + StrPas(PChar(S1)));
                                                             CloseHandle(hc);
                                                          end;
                                                    end;
                                              end;
                                        end;
                                     RegCloseKey(key);
                                  end;


                            end;
                         Inc(MemberIndex);
                     until False;

//If we did not found any free com. port we return a NIL pointer.

                     if Result.Count = 0 then
                        begin
                           Result.Free;
                           Result := NIL;
                        end
                  finally
                     SetupDiDestroyDeviceInfoList(DevInfoHandle);
                  end;
               end;
         end;
   finally
      UnloadSetupApi;
   end;
end;

procedure TMainForm.ListBox1Click(Sender: TObject);
begin
   Ardtype := Listbox1.ItemIndex;
   MainForm.Hide;
   ArdForm.ShowModal;
   if Ardform.ModalResult <> mrOK  then
      ShowMessage('Der opstod en fejl ')
   ELSE
      BEGIN
         MainForm.Show;
      END;
end;

end.

Kris aka snestrup2016

...