⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frm_main.pas

📁 delphi的源代码:查找通信设备的mac地址
💻 PAS
字号:
unit Frm_Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ActnList, ActnMan, HercLib, XPStyleActnCtrls;

type
  TFrmMain = class(TForm)
    GroupBoxDevice: TGroupBox;
    GroupBoxPassword: TGroupBox;
    GroupBoxPowerDownTimeout: TGroupBox;
    BtnScanDevice: TButton;
    EdtPassword: TEdit;
    ChkApplyToRemoteDevice: TCheckBox;
    LblRemoteDEK: TLabel;
    EdtRemoteDEK: TEdit;
    BtnApplyPassword: TButton;
    BtnSetDefaultPassword: TButton;
    CboPowerDownTimeout: TComboBox;
    BtnSetDefaultPowerDownTimeout: TButton;
    BtnApplyPowerDownTimeout: TButton;
    TreeViewDevice: TTreeView;
    ActionManager: TActionManager;
    ActApplyPowerDownTimeout: TAction;
    ActSetDefaultPowerDownTimeout: TAction;
    ActApplyPassword: TAction;
    ActSetDefaultPassword: TAction;
    ActScanDevice: TAction;
    BtnUpdateSpeed: TButton;
    ActUpdateSpeed: TAction;
    procedure ChkApplyToRemoteDeviceClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ActSetDefaultPowerDownTimeoutExecute(Sender: TObject);
    procedure ActSetDefaultPasswordExecute(Sender: TObject);
    procedure ActApplyPowerDownTimeoutExecute(Sender: TObject);
    procedure ActApplyPasswordExecute(Sender: TObject);
    procedure ActApplyPowerDownTimeoutUpdate(Sender: TObject);
    procedure ActApplyPasswordUpdate(Sender: TObject);
    procedure ActScanDeviceExecute(Sender: TObject);
    procedure TreeViewDeviceChange(Sender: TObject; Node: TTreeNode);
    procedure ActUpdateSpeedExecute(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FrmMain: TFrmMain;
  SelectedDeviceIndex: Integer;
  Devices: array[0..99] of TDeviceRec;
  DeviceCount: Integer;

  procedure ScanProgressCallback(Percentage: LongWord; Abort: PLongWord); stdcall;

implementation

{$R *.dfm}

uses
  SplitFns;

procedure TFrmMain.ChkApplyToRemoteDeviceClick(Sender: TObject);
begin
  EdtRemoteDEK.Enabled := ChkApplyToRemoteDevice.Checked;
  LblRemoteDEK.Enabled := ChkApplyToRemoteDevice.Checked;
end;

procedure TFrmMain.FormCreate(Sender: TObject);
begin
  Application.Title := 'Powerline Configuration Utility';

  ChkApplyToRemoteDevice.Checked := False;
  EdtRemoteDEK.Enabled := False;
  LblRemoteDEK.Enabled := False;

  SelectedDeviceIndex := -1;
  DeviceCount := 0;
end;

procedure TFrmMain.ActSetDefaultPowerDownTimeoutExecute(Sender: TObject);
begin
  CboPowerDownTimeout.ItemIndex := 0;
end;

procedure TFrmMain.ActApplyPowerDownTimeoutExecute(Sender: TObject);
var
  PowerDownTimeout: Integer;
  Code: Integer;
begin
  PowerDownTimeout := -1;
  case CboPowerDownTimeout.ItemIndex of
    -1: Exit;
    0: PowerDownTimeout := 0;
    1: PowerDownTimeout := 30;
    2: PowerDownTimeout := 60;
    3: PowerDownTimeout := 120;
    4: PowerDownTimeout := 180;
  end;

  if (PowerDownTimeout < 0) or (PowerDownTimeout > 255) then
  begin
    MessageDlg('Error: The value should between 0 to 255', mtError, [mbOk], 0);
    Exit;
  end;

  Code := SetPowerdownTimeout(SelectedDeviceIndex, Byte(PowerDownTimeout));
  if TReturnCode(Code) <> AFA_OK then
  begin
    MessageDlg('Error: SetPowerdownTimeout() =' + IntToStr(Code), mtError,
        [mbOk], 0);
    Exit;
  end;
end;

procedure TFrmMain.ActSetDefaultPasswordExecute(Sender: TObject);
begin
  EdtPassword.Text := 'HomePlug';
end;

procedure TFrmMain.ActApplyPasswordExecute(Sender: TObject);
var
  MACBuf: PByte;
  Code: Integer;
begin
  Code := SetLocalKey(SelectedDeviceIndex, PChar(Trim(EdtPassword.Text)));
  if TReturnCode(Code) = AFA_OK then
  begin
    if ChkApplyToRemoteDevice.Checked then
    begin
      GetMem(MACBuf, 6);

      Code := SetRemoteKey(SelectedDeviceIndex, PChar(Trim(EdtPassword.Text)),
          PChar(Trim(EdtRemoteDEK.Text)), MACBuf);
      FreeMem(MACBuf);
      if TReturnCode(Code) <> AFA_OK then
      begin
        MessageDlg('Error: SetRemoteKey() =' + IntToStr(Code), mtError,
            [mbOk], 0);
        Exit;
      end;
    end;
    ShowMessage('Change Password Success');
  end else
  begin
    ShowMessage('Error: SetLocalKey() =' + IntToStr(Code));
    Exit;
  end;
end;

procedure TFrmMain.ActApplyPowerDownTimeoutUpdate(Sender: TObject);
begin
  ActApplyPowerDownTimeout.Enabled := SelectedDeviceIndex <> -1;
end;

procedure TFrmMain.ActApplyPasswordUpdate(Sender: TObject);
begin
  ActApplyPassword.Enabled := SelectedDeviceIndex <> -1;
end;

procedure ScanProgressCallback(Percentage: LongWord; Abort: PLongWord); stdcall;
begin
  FrmMain.Caption := Application.Title + ' - Scaning... '
      + IntToStr(Percentage);
end;

procedure TFrmMain.ActScanDeviceExecute(Sender: TObject);
var
  DeviceListBuf: PChar;
  Count: Integer;
  Code: Integer;

  procedure ParseDeviceListStr(DeviceListStr: string);
  var
    DeviceList: TStringList;
    FieldList: TStringList;
    MACByteList: TStringList;
    I: Integer;
    J: Integer;
  begin
    DeviceList := TStringList.Create;
    DeviceCount := 0;

    Split(DeviceListStr, ';', DeviceList);
    if DeviceList.Count > 0 then
    begin
      for I := 0 to (DeviceList.Count - 1) do
      begin
        FieldList := TStringList.Create;
        Split(DeviceList.Strings[I], ',', FieldList);

        // MAC Address
        MACByteList := TStringList.Create;
        Split(FieldList.Strings[0], ' ', MACByteList);
        for J := 0 to 5 do
        begin
          Devices[I].MACAddress[J] := StrToInt('$' + Trim(MACByteList.Strings[J]));
        end;

        // Local/Remote:  0 = Local; 1 = Remote
        if UpperCase(Trim(FieldList.Strings[1])) = 'L' then
        begin
          Devices[I].DevType := 0;
        end else if UpperCase(Trim(FieldList.Strings[1])) = 'R' then
        begin
          Devices[I].DevType := 1;
        end;

        // Group ID
        Devices[I].DevGroup := StrToInt(Trim(FieldList.Strings[2]));

        // IsActive
        if UpperCase(Trim(FieldList.Strings[3])) = 'A' then
        begin
          Devices[I].IsActive := True;
        end else if UpperCase(Trim(FieldList.Strings[3])) = 'N' then
        begin
          Devices[I].IsActive := False;
        end;

        FreeAndNil(FieldList);
        FreeAndNil(MACByteList);
      end;
    end;

    DeviceCount := DeviceList.Count;
    FreeAndNil(DeviceList);
  end;

  procedure DisplayDeviceList;
  var
    I: Integer;
    LocalNode: TTreeNode;
    RemoteNode: TTreeNode;
    IsLookForNextLocalNode: Boolean;
  begin
    if DeviceCount = 0 then
      Exit;

    TreeViewDevice.Items.Clear;

    LocalNode := nil;
    IsLookForNextLocalNode := False;
    for I := 0 to (DeviceCount - 1) do
    begin
      if Devices[I].DevType = 0 {local device} then
      begin
        if Devices[I].IsActive then
        begin
          IsLookForNextLocalNode := False;
          LocalNode := TreeViewDevice.Items.Add(nil, '');
          LocalNode.Text := 'Local Device [' + IntToStr(I) + '] => ';
          LocalNode.Text := LocalNode.Text + Format('%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x',
            [Devices[I].MACAddress[0], Devices[I].MACAddress[1], Devices[I].MACAddress[2],
             Devices[I].MACAddress[3], Devices[I].MACAddress[4], Devices[I].MACAddress[5]]);
          LocalNode.Data := Pointer(I); // save the device index in Data property
        end else
        begin
          IsLookForNextLocalNode := True;
          Continue;
        end;
      end else if Devices[I].DevType = 1 {remote device} then
      begin
        if IsLookForNextLocalNode then
        begin
          Continue;
        end;

        Assert(Assigned(LocalNode));

        if Devices[I].IsActive then
        begin
          RemoteNode := TreeViewDevice.Items.AddChild(LocalNode, '');
          RemoteNode.Text := 'Remote Device [' + IntToStr(I) + '] => ';
          RemoteNode.Text := RemoteNode.Text + Format('%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x',
            [Devices[I].MACAddress[0], Devices[I].MACAddress[1], Devices[I].MACAddress[2],
             Devices[I].MACAddress[3], Devices[I].MACAddress[4], Devices[I].MACAddress[5]]);
          RemoteNode.Data := Pointer(I); // save the device index in Data property
          LocalNode.Expand(True);
        end else
        begin
          Continue;
        end;
      end;
    end;
  end;

begin
  Count := 1024;
  DeviceListBuf := StrAlloc(Count);
  StrCopy(DeviceListBuf, PChar(''));
  SetScanProgressCallback(@ScanProgressCallback);

  Code := ScanDeviceEx(1, 1, DeviceListBuf, @Count);
  if TReturnCode(Code) <> AFA_OK then
  begin
    MessageDlg('Error: ScanDeviceEx() =' + IntToStr(Code), mtError,
        [mbOk], 0);
    StrDispose(DeviceListBuf);
    Exit;
  end;

  Self.Caption := Application.Title;

  ParseDeviceListStr(DeviceListBuf);
  DisplayDeviceList;

  // Always selected the first device if any device is found.

  if DeviceCount = 0 then
  begin
    SelectedDeviceIndex := -1;
    Self.Caption := Application.Title + ' - Please select a device';
  end else
  begin
    TreeViewDevice.SetFocus;
    TreeViewDevice.Select([TreeViewDevice.Items[0]]);
    Self.Caption := Application.Title + ' - ' + TreeViewDevice.Selections[0].Text;
    SelectedDeviceIndex := Integer(TreeViewDevice.Items[0].Data);

    if Devices[SelectedDeviceIndex].DevType = 0 {local} then
    begin
      GroupBoxPassword.Visible := True;
      GroupBoxPowerDownTimeout.Visible := True;
    end else if Devices[SelectedDeviceIndex].DevType = 1 {remote} then
    begin
      GroupBoxPassword.Visible := False;
      GroupBoxPowerDownTimeout.Visible := False;
    end;
  end;

  StrDispose(DeviceListBuf);

  ActUpdateSpeed.Execute;
end;

procedure TFrmMain.TreeViewDeviceChange(Sender: TObject; Node: TTreeNode);
begin
  if TreeViewDevice.SelectionCount = 0 then
  begin
    Exit;
  end;

  SelectedDeviceIndex := Integer(TreeViewDevice.Selections[0].Data);
  Self.Caption := Application.Title + ' - ' + TreeViewDevice.Selections[0].Text;

  if Devices[SelectedDeviceIndex].DevType = 0 {local} then
  begin
    GroupBoxPassword.Visible := True;
    GroupBoxPowerDownTimeout.Visible := True;
  end else if Devices[SelectedDeviceIndex].DevType = 1 {remote} then
  begin
    GroupBoxPassword.Visible := False;
    GroupBoxPowerDownTimeout.Visible := False;
  end;
end;

procedure TFrmMain.ActUpdateSpeedExecute(Sender: TObject);
var
  Code: LongWord;
  I: Integer;
  J: Integer;
  Buffer: PByte;
  BufSize: LongWord;
  ToneMapEntryList: PChar;
  Len: LongWord;
  ToneMapEntries: TStringList;
  Speed: LongWord;
  LocalNode: TTreeNode;
  RemoteNode: TTreeNode;
  Timeout: LongWord;
  TimerStart: LongWord;
  DeviceIndex: Integer;
  RemoteDeviceIndex: Integer;

  function CompareMAC(Device: TDeviceRec; MACStr: string): Boolean;
  var
    TmpMACStr: string;
  begin
    TmpMACStr := Format('%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x', [
        Device.MACAddress[0], Device.MACAddress[1], Device.MACAddress[2],
        Device.MACAddress[3], Device.MACAddress[4], Device.MACAddress[5]]);

    if TmpMACStr = UpperCase(Trim(MACStr)) then
    begin
      Result := True;
    end else
    begin
      Result := False;
    end;
  end;
begin
  for I := 0 to (TreeViewDevice.Items.Count - 1) do
  begin
    DeviceIndex := Integer(TreeViewDevice.Items[I].Data);
    if Devices[DeviceIndex].DevType = 0 {local} then
    begin
      // Get the tone map table.

      Buffer := nil;
      BufSize := 0;
      Timeout := 3000;
      TimerStart := GetTickCount;
      while True do
      begin
        if (GetTickCount - TimerStart) > Timeout then
        begin
          Exit;
        end;

        Code := GetToneMapTable(DeviceIndex, nil, @BufSize);
        if TReturnCode(Code) <> AFA_OK then
        begin
          Continue;
        end;

        GetMem(Buffer, BufSize);
        Code := GetToneMapTable(DeviceIndex, Buffer, @BufSize);
        if TReturnCode(Code) <> AFA_OK then
        begin
          FreeMem(Buffer);
          Continue;
        end else
        begin
          Break;
        end;
      end;

      // Get tone map entry data and speed from the tone map table.

      Assert(Assigned(Buffer));
      Code := GetToneMapEntryList(Buffer, BufSize, nil, @Len);
      if TReturnCode(Code) <> AFA_OK then
      begin
        FreeMem(Buffer);
        Continue;
      end;

      ToneMapEntryList := StrAlloc(Len);
      Code := GetToneMapEntryList(Buffer, BufSize, ToneMapEntryList, @Len);
      if TReturnCode(Code) <> AFA_OK then
      begin
        StrDispose(ToneMapEntryList);
        FreeMem(Buffer);
        Continue;
      end;

      ToneMapEntries := TStringList.Create;
      Split(ToneMapEntryList, ';', ToneMapEntries);
      StrDispose(ToneMapEntryList);

      if ToneMapEntries.Count = 0 then
      begin
        FreeAndNil(ToneMapEntries);
        FreeMem(Buffer);
        Continue;
      end;

      LocalNode := TreeViewDevice.Items[I];
      RemoteNode := LocalNode.GetFirstChild;
      while Assigned(RemoteNode) do
      begin
        for J := 0 to (ToneMapEntries.Count - 1) do
        begin
          if CompareMAC(Devices[Integer(RemoteNode.Data)],
              ToneMapEntries.Strings[J]) then
          begin
            GetSpeed(Buffer, BufSize, J, @Speed);
            RemoteDeviceIndex := Integer(RemoteNode.Data);
            RemoteNode.Text := 'Remote Device [' + IntToStr(RemoteDeviceIndex) + '] => ';
            RemoteNode.Text := RemoteNode.Text + Format('%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x',
              [Devices[RemoteDeviceIndex].MACAddress[0],
               Devices[RemoteDeviceIndex].MACAddress[1],
               Devices[RemoteDeviceIndex].MACAddress[2],
               Devices[RemoteDeviceIndex].MACAddress[3],
               Devices[RemoteDeviceIndex].MACAddress[4],
               Devices[RemoteDeviceIndex].MACAddress[5]]);
            RemoteNode.Text := RemoteNode.Text + ' (' + FloatToStr(Speed / 1000) + ' Mbps)';
          end;
        end;
        RemoteNode := LocalNode.GetNextChild(RemoteNode);
      end;

      FreeAndNil(ToneMapEntries);
      FreeMem(Buffer);
    end;
  end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -