unit fmuDevices;

////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                          //
////////////////////////////////////////////////////////////////////////////////////////////////////

interface

uses
  // VCL
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, ComCtrls, ComObj, ActiveX,
  // This
  untUtil,
  untType,
  xObj;

type

  { TfmDevices }     

  TfmDevices = class(TForm)
    pnlButtons: TPanel;
    Panel3: TPanel;
    Panel2: TPanel;
    pnlDescription: TPanel;
    Shape1: TShape;
    lblResultCode: TLabel;
    lblResultDescription: TLabel;
    edtResultCode: TEdit;
    edtResultDescription: TEdit;
    Panel6: TPanel;
    Panel7: TPanel;
    PageControl: TPageControl;
    tbDevice: TTabSheet;
    lblDeviceName: TLabel;
    lblDeviceDescription: TLabel;
    edtDeviceName: TEdit;
    edtDeviceDescription: TEdit;
    TabSheet1: TTabSheet;
    lblBaudRate: TLabel;
    lblPortNumber: TLabel;
    lblModelID: TLabel;
    lblMachineName: TLabel;
    cmbBaudRate: TComboBox;
    cmbPortNumber: TComboBox;
    cmbModel: TComboBox;
    edtMachineName: TEdit;
    TabSheet2: TTabSheet;
    chbWaitAck: TCheckBox;
    chbBackground: TCheckBox;
    chbExclusive: TCheckBox;
    Panel1: TPanel;
    lblDeviceNumber: TLabel;
    lblDeviceIndex: TLabel;
    Panel4: TPanel;
    Label15: TLabel;
    btnAddDevice: TButton;
    btnDeleteDevice: TButton;
    Panel5: TPanel;
    btnClose: TButton;
    cmbDeviceIndex: TComboBox;
    cmbDeviceNumber: TComboBox;
    lblDeviceCount: TLabel;
    edtDeviceCount: TEdit;
    Label1: TLabel;
    edtPortNumber: TEdit;
    edtModel: TEdit;
    edtBaudRate: TEdit;
    chbDeviceEnabled: TCheckBox;
    chbShowProgress: TCheckBox;
    lblDeviceOwned: TLabel;
    chbUpdatePrinterSettings: TCheckBox;
    chbProgressButtonsVisible: TCheckBox;
    procedure EditorChange(Sender: TObject);
    procedure btnCloseClick(Sender: TObject);
    procedure EditorExit(Sender: TObject);
    procedure EditorClick(Sender: TObject);
    procedure EditorKeyPress(Sender: TObject; var Key: Char);
  private
    function ChangePropertyValue(Sender: TObject): Boolean;
    procedure PerformMethodValue(Sender: TObject);
    procedure UpdateControls;
    procedure Init(ADriver: TObjX; AShowMessage: Boolean; AFont: TFont);
  private
    fDriver: TObjX;
    fShowMessage: Boolean;
    property Driver: TObjX read fDriver;
    function DriverException(E: Exception): Boolean;
  private
    procedure UpdateObject_DeviceEnabled;
    procedure UpdateObject_DeviceName;
    procedure UpdateObject_DeviceIndex;
    procedure UpdateObject_DeviceNumber;
    procedure UpdateObject_MachineName;
    procedure UpdateObject_PortNumber;
    procedure UpdateObject_BaudRate;
    procedure UpdateObject_Model;
    procedure UpdateObject_Exclusive;
    procedure UpdateObject_Background;
    procedure UpdateObject_UpdatePrinterSettings;
    procedure UpdateObject_WaitAck;
    procedure UpdateObject_ShowProgress;
    procedure UpdateObject_ProgressButtonsVisible;
    procedure Perform_AddDevice;
    procedure Perform_DeleteDevice;
  end;

procedure ExecuteDeviceDialog(ADriver: TObjX; AShowMessage: Boolean; AFont: TFont);

implementation

{$R *.DFM}

procedure ExecuteDeviceDialog(ADriver: TObjX; AShowMessage: Boolean; AFont: TFont);
var
  fm: TfmDevices;
begin
  fm := TfmDevices.Create(nil);
  try
    with fm do
    begin
      Init(ADriver, AShowMessage, AFont);
      ShowModal;
    end;
  finally
    fm.Free;
  end;
end;

procedure TfmDevices.Init(ADriver: TobjX; AShowMessage: Boolean; AFont: TFont);

  procedure UpdateView;
  var
    I: Integer;
  begin
    PageControl.ActivePage := tbDevice;


    with cmbBaudRate.Items do
    begin
      BeginUpdate;
      try
        Clear;
        AddObject(Format('%s ', [BaudRateToStr[br1200]]), TObject(ord(br1200)));
        AddObject(Format('%s ', [BaudRateToStr[br2400]]), TObject(ord(br2400)));
        AddObject(Format('%s ', [BaudRateToStr[br4800]]), TObject(ord(br4800)));
        AddObject(Format('%s ', [BaudRateToStr[br9600]]), TObject(ord(br9600)));
        AddObject(Format('%s ', [BaudRateToStr[br19200]]), TObject(ord(br19200)));
        AddObject(Format('%s ', [BaudRateToStr[br38400]]), TObject(ord(br38400)));
        AddObject(Format('%s ', [BaudRateToStr[br56000]]), TObject(ord(br56000)));
        AddObject(Format('%s ', [BaudRateToStr[br57600]]), TObject(ord(br57600)));
        AddObject(Format('%s ', [BaudRateToStr[br115200]]), TObject(ord(br115200)));
      finally
        EndUpdate;
      end;
    end;

    with cmbModel.Items do
    begin
      BeginUpdate;
      try
        Clear;
        for I  := 0 to Ord(High(TPrinterModel)) do
         AddObject(PrinterModelToStr[TPrinterModel(I)], TObject(I + 1));
      finally
        EndUpdate;
      end;
    end;

    with cmbPortNumber.Items do
    begin
      BeginUpdate;
      try
        Clear;
        for I := 1 to 32 do AddObject(format('COM %d', [I]), Pointer(I));
        for I := 33 to 36 do AddObject(format('LPT %d', [I - 32]), Pointer(I));
      finally
        EndUpdate;
      end;
    end;

    with cmbDeviceIndex.Items do
    begin
      BeginUpdate;
      try
        Clear;
        for I := 0 to 98 do AddObject(format('%d', [I]), Pointer(I));
      finally
        EndUpdate;
      end;
    end;

    with cmbDeviceNumber.Items do
    begin
      BeginUpdate;
      try
        Clear;
        for I := 1 to 99 do AddObject(format('%d', [I]), Pointer(I));
      finally
        EndUpdate;
      end;
    end;

  end;

begin
  fShowMessage := AShowMessage;
  fDriver := ADriver;
  Font := AFont;
  UpdateView;
  UpdateControls;
end;

(****************************      ********************************)

function TfmDevices.DriverException(E: Exception): Boolean;
begin
  Result := (E is EOleSysError)
    and (ResultFacility(EOleSysError(E).ErrorCode) = FACILITY_ITF);
  if Result then
  begin
    if fShowMessage then
    begin
      with Application do
        MessageBox(PChar(E.Message), PChar(Title), mb_IconStop or mb_Ok);
    end;
  end
  else
  begin
    if E is EConvertError then
    begin
      E.Message := '    .' + #13 +
        ': ' + E.Message;
      Result := not fShowMessage;
    end;
  end;
end;

function TfmDevices.ChangePropertyValue(Sender: TObject): Boolean;
begin
  Result := True;
  try
    try
      if Sender = chbDeviceEnabled then UpdateObject_DeviceEnabled
      else if Sender = edtDeviceName then UpdateObject_DeviceName
      else if Sender = cmbDeviceIndex then UpdateObject_DeviceIndex
      else if Sender = cmbDeviceNumber then UpdateObject_DeviceNumber
      else if Sender = edtMachineName then UpdateObject_MachineName
      else if Sender = cmbPortNumber then UpdateObject_PortNumber
      else if Sender = cmbBaudRate then UpdateObject_BaudRate
      else if Sender = cmbModel then UpdateObject_Model
      else if Sender = chbExclusive then UpdateObject_Exclusive
      else if Sender = chbBackground then UpdateObject_Background
      else if Sender = chbUpdatePrinterSettings then UpdateObject_UpdatePrinterSettings
      else if Sender = chbShowProgress then UpdateObject_ShowProgress
      else if Sender = chbProgressButtonsVisible then UpdateObject_ProgressButtonsVisible
      else if Sender = chbWaitAck then UpdateObject_WaitAck;
    finally
      UpdateControls;
    end;
  except
    on E: Exception do
    begin
      Result := False;
      if (Sender is TWinControl)
         and (TWinControl(Sender).Visible)
         and (TWinControl(Sender).Enabled) then TWinControl(Sender).SetFocus;
      if not DriverException(E) then raise;
    end;
  end;
end;

procedure TfmDevices.PerformMethodValue(Sender: TObject);
begin
  try
    try
      if Sender = btnAddDevice then Perform_AddDevice
      else if Sender = btnDeleteDevice then Perform_DeleteDevice;
    finally
      UpdateControls;
    end;
   except
    on E: Exception do
    begin
      if (Sender is TWinControl)
         and TWinControl(Sender).Visible
         and (TWinControl(Sender).Enabled) then TWinControl(Sender).SetFocus;
      if not DriverException(E) then raise;
    end;
  end;
end;

procedure TfmDevices.UpdateControls;
var
  V: OleVariant;
begin
  V := Driver.ControlInterface;
  SafeSetEdit(edtResultCode, IntToStr(V.ResultCode));
  SafeSetEdit(edtResultDescription, V.ResultDescription);
  SafeSetChecked(chbDeviceEnabled, V.DeviceEnabled);
  SafeSetEdit(edtDeviceName, V.CurrentDeviceName);
  SafeSetEdit(edtMachineName, V.MachineName);
  SafeSetEdit(edtDeviceDescription, V.DeviceDescription);
  SafeSetEdit(edtDeviceCount, V.DeviceCount);

  SafeSetComboBoxObj(cmbDeviceIndex, TObject(Integer(V.CurrentDeviceIndex)));
  SafeSetComboBoxObj(cmbDeviceNumber, TObject(Integer(V.CurrentDeviceNumber)));
  SafeSetComboBoxObj(cmbPortNumber, TObject(Integer(V.PortNumber)));
  SafeSetEdit(edtPortNumber, V.PortNumber);
  SafeSetComboBoxObj(cmbBaudRate, TObject(IntToEnumBaudRate(V.BaudRate)));
  SafeSetEdit(edtBaudRate, V.BaudRate);
  SafeSetComboBoxObj(cmbModel, TObject(Integer(V.Model)));
  SafeSetEdit(edtModel, V.Model);

  SafeSetChecked(chbExclusive, V.Exclusive);
  SafeSetChecked(chbBackground, V.BackgroundPrint);
  SafeSetChecked(chbUpdatePrinterSettings, V.UpdatePrinterSettings);
  SafeSetChecked(chbWaitAck, V.WaitPrinterAck);
  SafeSetChecked(chbShowProgress, V.ShowProgress);
  SafeSetChecked(chbProgressButtonsVisible, not(V.ProgressButtonsVisible));

  chbShowProgress.Enabled := not chbBackground.Checked;
  chbProgressButtonsVisible.Enabled := chbShowProgress.Enabled and chbShowProgress.Checked;
  cmbBaudRate.Enabled := Integer(GetSelectedComboBoxObject(cmbPortNumber)) <= 32;
  //
  if V.DeviceEnabled and (not V.IsOwnDevice) then
  begin
    lblDeviceOwned.Visible := True;
    lblDeviceOwned.Caption := format('   %s -> %s [%s] ',
      [PortNumberToStr(V.PortNumber),
      PrinterModelToStr[TPrinterModel(V.Model - 1)],
      BaudRateToStr[IntToEnumBaudRate(V.BaudRate)]]);
  end
  else
    lblDeviceOwned.Visible := False;
end;

(*************************************    ******************************************)

procedure TfmDevices.UpdateObject_DeviceEnabled;
begin
  Driver.ControlInterface.DeviceEnabled := chbDeviceEnabled.Checked;
end;

procedure TfmDevices.UpdateObject_DeviceName;
begin
  Driver.ControlInterface.CurrentDeviceName := edtDeviceName.Text;
end;

procedure TfmDevices.UpdateObject_DeviceIndex;
begin
  Driver.ControlInterface.CurrentDeviceIndex := Integer(GetSelectedComboBoxObject(cmbDeviceIndex));
end;

procedure TfmDevices.UpdateObject_DeviceNumber;
begin
  Driver.ControlInterface.CurrentDeviceNumber := Integer(GetSelectedComboBoxObject(cmbDeviceNumber));
end;

procedure TfmDevices.UpdateObject_MachineName;
begin
  Driver.ControlInterface.MachineName := edtMachineName.Text;
end;

procedure TfmDevices.UpdateObject_PortNumber;
begin
  Driver.ControlInterface.PortNumber := Integer(GetSelectedComboBoxObject(cmbPortNumber));
end;

procedure TfmDevices.UpdateObject_BaudRate;
begin
  Driver.ControlInterface.BaudRate := EnumToIntBaudRate(TBaudRate(GetSelectedComboBoxObject(cmbBaudRate)));
end;

procedure TfmDevices.UpdateObject_Model;
begin
  Driver.ControlInterface.Model := Integer(GetSelectedComboBoxObject(cmbModel));
end;

procedure TfmDevices.UpdateObject_Exclusive;
begin
  Driver.ControlInterface.Exclusive := chbExclusive.Checked;
end;

procedure TfmDevices.UpdateObject_Background;
begin
  Driver.ControlInterface.BackgroundPrint := chbBackground.Checked;
end;

procedure TfmDevices.UpdateObject_UpdatePrinterSettings;
begin
  Driver.ControlInterface.UpdatePrinterSettings := chbUpdatePrinterSettings.Checked;
end;

procedure TfmDevices.UpdateObject_WaitAck;
begin
  Driver.ControlInterface.WaitPrinterAck := chbWaitAck.Checked;
end;

procedure TfmDevices.UpdateObject_ShowProgress;
begin
  Driver.ControlInterface.ShowProgress := chbShowProgress.Checked;
end;

procedure TfmDevices.UpdateObject_ProgressButtonsVisible;
begin
  Driver.ControlInterface.ProgressButtonsVisible := not chbProgressButtonsVisible.Checked;
end;

procedure TfmDevices.Perform_AddDevice;
begin
  Driver.ControlInterface.AddDevice;
end;

procedure TfmDevices.Perform_DeleteDevice;
begin
  Driver.ControlInterface.DeleteDevice;
end;

(************************************   *****************************************)

procedure TfmDevices.EditorClick(Sender: TObject);
begin
  PerformMethodValue(Sender);
end;

procedure TfmDevices.EditorChange(Sender: TObject);
begin
  ChangePropertyValue(Sender);
end;

procedure TfmDevices.EditorExit(Sender: TObject);
begin
  if (Sender is TCustomEdit) and TCustomEdit(Sender).Modified
    then ChangePropertyValue(Sender);
end;

procedure TfmDevices.EditorKeyPress(Sender: TObject; var Key: Char);
begin
  case ord(Key) of
    VK_RETURN: ChangePropertyValue(Sender);
    VK_ESCAPE: UpdateControls;
  end;
end;

procedure TfmDevices.btnCloseClick(Sender: TObject);
begin
  Close;
end;

end.
