unit fmuMain;

interface

uses
  // VCL
  Windows, ActiveX, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, ComCtrls, ComObj,
  // This
  cuUtils,
  cuWindows,
  untTypes,
  fmuDevice,
  fmuDrawer,
  LineX,
  Line1C_TLB,
  fmuWindows,
  fmuDemo,
  fmuDeviceCaps;

const
  WM_SHOWDEMO = WM_USER + 200;
  
type
  { TfmMain }

  TfmMain = class(TForm)
    Bevel2: TBevel;
    btnClose: TButton;
    btnProperties: TButton;
    btnFont: TButton;
    btnDeviceTest: TButton;
    chkDeviceEnabled: TCheckBox;
    chkLockDevices: TCheckBox;
    Label5: TLabel;
    Label6: TLabel;
    Shape1: TShape;
    edtResultCode: TEdit;
    edtResultDescription: TEdit;
    btnDrawer: TButton;
    FontDialog: TFontDialog;
    btnDisplayText: TButton;
    btnClearText: TButton;
    btnClearDisplay: TButton;
    btnShowDemo: TButton;
    Label1: TLabel;
    Label11: TLabel;
    Label8: TLabel;
    Label16: TLabel;
    Label18: TLabel;
    edtText: TMemo;
    cboMarqueeType: TComboBox;
    cboMarqueeFormat: TComboBox;
    cboCurrentWindow: TComboBox;
    cboLineDirection: TComboBox;
    btnClear: TButton;
    cboBlinkType: TComboBox;
    Label9: TLabel;
    Label10: TLabel;
    edtCursorColumn: TEdit;
    edtCursorRow: TEdit;
    tbBrightness: TTrackBar;
    Label19: TLabel;
    chkDisplayTextAt: TCheckBox;
    chkCursorUpdate: TCheckBox;
    Label17: TLabel;
    edtScrollUnits: TEdit;
    Label15: TLabel;
    edtBlinkInterval: TEdit;
    Label14: TLabel;
    edtMarqueeUnitWait: TEdit;
    Label13: TLabel;
    edtMarqueeRepeatWait: TEdit;
    btnWindows: TButton;
    btnDeviceCaps: TButton;
    Label12: TLabel;
    btnRefreshWindow: TButton;
    btnScrollText: TButton;
    Label2: TLabel;
    cboCharacterSet: TComboBox;
    procedure btnFontClick(Sender: TObject);
    procedure btnCloseClick(Sender: TObject);
    procedure btnClearClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure btnTestClick(Sender: TObject);
    procedure ControlChanged(Sender: TObject);
  private
    FLineX: TLineX;
    FWindowList: TWindowList;
    FShowDemoOnStart: Boolean;
    procedure Initialize(ALineX: TLineX);
    procedure CreateWindow;
    procedure UpdateWindowList;
    procedure UpdatePage;
    procedure HandleException(E: Exception);
    procedure DoneWindowList;
    procedure WMShowDemo(var Msg: TMessage); message WM_SHOWDEMO;
  public
    destructor Destroy; override;
  end;

procedure ExecuteWinMain;

implementation

{$R *.DFM}

procedure ExecuteWinMain;
var
  fmMain: TfmMain;
  LineX: TLineX;
  RegResult: Integer;
begin
  try
    Application.Title := ':   ';
    Application.Initialize;
    Application.ProcessMessages;
    RegResult := RegisterServerObject(Class_LineLS5X, 'LineLS.exe');
    if RegResult = IDCancel then Exit;
    RegResult := RegisterDriverObject(Class_Line45, 'Line1C.dll');
    if RegResult = IDCancel then Exit;
    LineX := TLineX.Create(CreateComObject(Class_Line45) as ILine1C5X);
    try
      Application.CreateForm(TfmMain, fmMain);
      try
        fmMain.Initialize(LineX);
        Application.Run;
      finally
        fmMain.Free;
      end;
    finally
      LineX.Free;
    end;
  except
    Application.HandleException(nil);
  end;
end;

{ TfmMain }

procedure TfmMain.Initialize(ALineX: TLineX);

  procedure UpdateFont;
  var
    F: TFont;
  begin
    F := TFont.Create;
    try
      RegReadFont(F);
      Font := F;
    finally
      F.Free;
    end;
  end;

begin
  FShowDemoOnStart := GetRegistryShowDemoOnStart;
  if FShowDemoOnStart then
    PostMessage(Handle, WM_SHOWDEMO, 0, 0);
  FLineX := ALineX;
  // FillMarqueeType;
  StringsAssignEntries(cboMarqueeType.Items, LineX_MarqueeTypes,
    @LineX_Enabled_MarqueeTypes);
  // FillMarqueeFormat;
  StringsAssignEntries(cboMarqueeFormat.Items, LineX_MarqueeFormats, nil);
  // FillLineDirection;
  StringsAssignEntries(cboLineDirection.Items, LineX_Directions,
    @LineX_Enabled_Directions);
  cboLineDirection.ItemIndex := 0;
  // FillBlinkType;
  StringsAssignEntries(cboBlinkType.Items, LineX_BlinkTypes,
    @LineX_Enabled_BlinkTypes);
  cboBlinkType.ItemIndex := 0;
  // FillCharacterSet;
  StringsAssignEntries(cboCharacterSet.Items, LineX_CharacterSets, nil);
  cboCharacterSet.ItemIndex := 0;
  UpdateFont;
  if FLineX.ServerLoaded then CreateWindow;
  UpdateWindowList;
  UpdatePage;
end;

destructor TfmMain.Destroy;
begin
  FWindowList.Free;
  inherited Destroy;
end;

procedure TfmMain.WMShowDemo(var Msg: TMessage);
begin
  ControlChanged(btnShowDemo);
end;

procedure TfmMain.CreateWindow;
var
  I: Integer;
  ViewW: Integer;
  ViewH: Integer;
  WinH: Integer;
  WinW: Integer;
begin
  ViewW := FLineX.DeviceColumns;
  ViewH := 1;
  WinH := 12;
  WinW := 20;
  FLineX.CreateWindow(0, 0, 1, ViewW, WinH, WinW);
  FWindowList := TWindowList.CreateDirect(Self, 0, 0, ViewH, ViewW, WinH, WinW);
  for I := 1 to FLineX.DeviceRows - 1 do
  begin
    ViewW := FLineX.GetDeviceColumns(I);
    FLineX.AddViewPort(I, 0, ViewH, ViewW);
    FWindowList.Items[0].AddViewPort(I, 0, ViewH, ViewW);
  end;
  FLineX.CurrentWindow := 0;
  FLineX.DestroyWindow;
end;

procedure TfmMain.DoneWindowList;
var
  I: Integer;
begin
  if FWindowList <> nil then
  begin
    if FLineX.ServerLoaded then
      for I := FWindowList.Count - 1 downto 1 do //   
      begin
        FLineX.CurrentWindow := I;
        FLineX.DestroyWindow;
      end;
    FWindowList.Free;
    FWindowList := nil;
  end;
end;

procedure TfmMain.UpdatePage;
begin
  edtResultCode.Text := IntToStr(FLineX.ResultCode);
  edtResultDescription.Text := FLineX.ResultDescription;
  SafeSetComboBox(cboCurrentWindow, FLineX.CurrentWindow);
  with cboMarqueeType.Items do
   SafeSetComboBox(cboMarqueeType,
    IndexOfObject(TObject(FLineX.MarqueeType)));
  with cboMarqueeFormat.Items do
   SafeSetComboBox(cboMarqueeFormat,
     IndexOfObject(TObject(FLineX.MarqueeFormat)));
  with cboCharacterSet.Items do
   SafeSetComboBox(cboCharacterSet,
     IndexOfObject(TObject(FLineX.CharacterSet)));
  SafeSetEdit(edtMarqueeRepeatWait, IntToStr(FLineX.MarqueeRepeatWait));
  SafeSetEdit(edtMarqueeUnitWait, IntToStr(FLineX.MarqueeUnitWait));
  SafeSetEdit(edtBlinkInterval, IntToStr(FLineX.BlinkInterval));
  SafeSetEdit(edtCursorColumn, IntToStr(FLineX.CursorColumn));
  SafeSetEdit(edtCursorRow, IntToStr(FLineX.CursorRow));
  SafeSetChecked(chkCursorUpdate, FLineX.CursorUpdate);
  SafeSetTrackBar(tbBrightness, FLineX.DeviceBrightness);
  SafeSetChecked(chkLockDevices, FLineX.LockDevices);
  SafeSetChecked(chkDeviceEnabled, FLineX.DeviceEnabled);
end;

procedure TfmMain.HandleException(E: Exception);
begin
  if E is EDisplayError then
    edtResultCode.Text := IntToStr(EDisplayError(E).ErrorCode)
  else
    edtResultCode.Text := '-6'; //  
  edtResultDescription.Text := E.Message;
end;

procedure TfmMain.UpdateWindowList;
var
  I: integer;
  LineWindow: TLineWindow;
begin
  cboCurrentWindow.Items.BeginUpdate;
  try
    cboCurrentWindow.Items.Clear;
    if FWindowList <> nil then
      for I := 0 to FWindowList.Count-1 do
      begin
        LineWindow := FWindowList[I];
        cboCurrentWindow.Items.Add(LineWindow.Caption);
      end;
    cboCurrentWindow.Enabled := FWindowList <> nil;  
  finally
    cboCurrentWindow.Items.EndUpdate;
  end;
end;

procedure TfmMain.btnFontClick(Sender: TObject);
begin
  FontDialog.Font.Assign(Font);
  if FontDialog.Execute then
  begin
    Font.Assign(FontDialog.Font);
    RegSaveFont(Font);
  end;  
end;

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

procedure TfmMain.btnClearClick(Sender: TObject);
begin
  edtText.Lines.Clear;
end;

procedure TfmMain.ControlChanged(Sender: TObject);

  function GetMarqueeType: Integer;
  begin
    with cboMarqueeType do
      Result := Integer(Items.Objects[ItemIndex]);
  end;

  function GetMarqueeFormat: Integer;
  begin
    with cboMarqueeFormat do
     Result := Integer(Items.Objects[ItemIndex]);
  end;

  function GetDirection: Integer;
  begin
    with cboLineDirection do
     Result := Integer(Items.Objects[ItemIndex]);
  end;

  function GetCharacterSet: Integer;
  begin
    with cboCharacterSet do
     Result := Integer(Items.Objects[ItemIndex]);
  end;

  function GetMarqueeRepeatWait: Integer;
  begin
    Result := StrToIntRus(edtMarqueeRepeatWait.Text);
  end;

  function GetMarqueeUnitWait: Integer;
  begin
    Result := StrToIntRus(edtMarqueeUnitWait.Text);
  end;

  function GetInterCharacterWait: Integer;
  begin
    Result := 0; //     
  end;

  function GetBlinkInterval: Integer;
  begin
    Result := StrToIntRus(edtBlinkInterval.Text);
  end;

  function GetTextToDisplay: string;
  begin
    Result := edtText.Text;
    //      #13#10,   
    while (Result <> '') and (Result[Length(Result)] in [#13, #10]) do
      Delete(Result, Length(Result), 1);
  end;

  function GetTextAttribute: Integer;
  begin
    with cboBlinkType do
      Result := Integer(Items.Objects[ItemIndex]);
  end;

  procedure DisplayText;
  begin
    FLineX.MarqueeType := GetMarqueeType;
    FLineX.MarqueeFormat := GetMarqueeFormat;
    FLineX.MarqueeRepeatWait := GetMarqueeRepeatWait;
    FLineX.MarqueeUnitWait := GetMarqueeUnitWait;
    FLineX.InterCharacterWait := GetInterCharacterWait;
    FLineX.BlinkInterval := GetBlinkInterval;
    FLineX.CursorUpdate := chkCursorUpdate.Checked;
    if chkDisplayTextAT.Checked then
      FLineX.DisplayTextAT(StrToIntRus(edtCursorRow.Text),
        StrToIntRus(edtCursorColumn.Text), GetTextToDisplay, GetTextAttribute)
    else
      FLineX.DisplayText(GetTextToDisplay, GetTextAttribute);
  end;

  procedure ChangeCurrentWindow;
  begin
    FLineX.CurrentWindow := cboCurrentWindow.ItemIndex;
  end;

  procedure ShowWindowsDialog;
  begin
    ShowWindowManager(FLineX, FWindowList, Font);
    UpdateWindowList;
  end;

  procedure ShowDemoDialog;
  begin
    DoneWindowList;
    ExecuteDemo(FLineX, Font, FShowDemoOnStart);
    SetRegistryShowDemoOnStart(FShowDemoOnStart);
    CreateWindow;
    UpdateWindowList;
  end;

  procedure ShowProperties;
  begin
    DoneWindowList;
    FLineX.ShowProperties;
    CreateWindow;
    UpdateWindowList;
  end;  

begin
  try
    try
      if Sender = cboCurrentWindow then
        ChangeCurrentWindow
      else if Sender = tbBrightness then
        FLineX.DeviceBrightness := tbBrightness.Position
      else if Sender = cboCharacterSet then
        FLineX.CharacterSet := GetCharacterSet
      else if Sender = btnDrawer then
        ShowDrawerDialog(FLineX, Font)
      else if Sender = btnWindows then ShowWindowsDialog
      else if Sender = btnDeviceCaps then ShowDeviceCapsDialog(FLineX, Font)
      else if Sender = btnDisplayText then DisplayText
      else if Sender = btnClearText then FLineX.ClearText
      else if Sender = btnScrollText then
        FLineX.ScrollText(GetDirection, StrToIntRus(edtScrollUnits.Text))
      else if Sender = btnClearDisplay then FLineX.Clear
      else if Sender = btnRefreshWindow then
        FLineX.RefreshWindow(FLineX.CurrentWindow)
      else if Sender = btnShowDemo then ShowDemoDialog
      else if Sender = chkLockDevices then
        FLineX.LockDevices := chkLockDevices.Checked
      else if Sender = btnDeviceTest then
        ShowDevicesProperties(FLineX, Font)
      else if Sender = chkDeviceEnabled then
        FLineX.DeviceEnabled := chkDeviceEnabled.Checked
      else if Sender = btnProperties then ShowProperties
    finally
      UpdatePage;
    end;
  except
    on E: Exception do HandleException(E);
  end;
end;

procedure TfmMain.FormActivate(Sender: TObject);
begin
  UpdatePage;
end;

procedure TfmMain.btnTestClick(Sender: TObject);
begin
  FLineX.CreateWindow(0, 3, 2, 3, 2, 5);
  FLineX.DisplayText('0123456789', 0);
  FLineX.MarqueeType := 5;
  FLineX.MarqueeUnitWait := 1000;
  FLineX.MarqueeFormat := 1;
  FLineX.DisplayTextAt(0, 4, 'AB', 0);
  FLineX.MarqueeType := 3;
end;

end.
