📄 frm_main.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 + -