{
 -------------------------------------------------------------------------
 Copyright (C) 1998-2003 Häger+Busch                   / >>>>>>>>> /-----
 Ingenieurbuero fuer Kommunikationslösungen           / <<<<<<<<< /
 ----------------------------------------------------/ >>>>>>>>> /
 All rights reserved.
                                                    http://www.commso.com

 Project     : hbTapi Components
 Modul       : Sample v1.
 Description : This sample shows how use TTapiLine in conjunction with TComPort
               do send and receive binary data.

 History     : [-] Fixed [+] Added [*] Improved

 01/01/03   Creation
}
unit uMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, hbTAPI, hbTapiUtils, hbTapiComm, Tapi, ComCtrls; 

type
  TForm1 = class(TForm)
    TapiLine1: TTapiLine;
    GroupBox1: TGroupBox;
    ComboBoxDevice: TComboBox;
    CheckBoxActive: TCheckBox;
    Label1: TLabel;
    GroupBox2: TGroupBox;
    ButtonDrop: TButton;
    EditCallPhoneNumber: TEdit;
    ButtonDial: TButton;
    ButtonAnswer: TButton;
    ComPort1: TComPort;
    GroupBox3: TGroupBox;
    Edit1: TEdit;
    ButtonSend: TButton;
    Label2: TLabel;
    Label3: TLabel;
    Label_Com: TLabel;
    Label_CallState: TLabel;
    Label9: TLabel;
    Label_Info: TLabel;
    ListBox1: TListBox;
    ListBox2: TListBox;
    CheckBox1: TCheckBox;
    procedure CheckBoxActiveClick(Sender: TObject);
    procedure ComboBoxDeviceChange(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure DoMakeCall(Sender: TObject);
    procedure TapiLine1CallState(Sender: TTapiLine; Call: TTapiCall;
      CallState: Cardinal);
    procedure TapiLine1CallDeallocate(Sender: TTapiLine; Call: TTapiCall);
    procedure TapiLine1NewCall(Sender: TTapiLine; Call: TTapiCall);
    procedure DoDropCall(Sender: TObject);
    procedure ButtonAnswerClick(Sender: TObject);
    procedure ButtonSendClick(Sender: TObject);
    procedure ComPort1IncomingData(Sender: TObject; const Data: String);
    procedure ComPort1OutgoingData(Sender: TObject; const Data: String);
    procedure TapiLine1Offering(Sender: TTapiLine; Call: TTapiCall);
  private
    function GetCall: TTapiCall;
    procedure UpdateCalls;
    procedure UpdateComm;
    procedure Log(Value: String);
  public
    { Public declarations }
  end;

var Form1:        TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var i: integer;
begin
  // Get all line devices which support data communications
  for i := 0 to TapiLine1.DeviceList.Count-1 do
  begin
    TapiLine1.DeviceID := i;
    if TapiLine1.Available and (TapiLine1.Caps.MediaModes and LINEMEDIAMODE_DATAMODEM > 0) then
      ComboBoxDevice.Items.Add(TapiLine1.DeviceList[i]);
  end;

  if ComboBoxDevice.Items.Count > 0 then
    ComboBoxDevice.ItemIndex := 0;

  ComboBoxDevice.ItemIndex := 0;
  ComboBoxDeviceChange(ComboBoxDevice);
  UpdateCalls;
  UpdateComm;
end;

procedure TForm1.Log(Value: String);
begin
  ListBox2.Items.Add(Value);
end;

procedure TForm1.CheckBoxActiveClick(Sender: TObject);
begin
  // To abvoid errors, we only use LINEMEDIAMODE_DATAMODEM
  TapiLine1.MediaModes         := LINEMEDIAMODE_DATAMODEM;
  TapiLine1.Privileges.Owner   := True;
  TapiLine1.Privileges.Monitor := True;

  if not CheckBoxActive.Checked then
  begin
    if TapiLine1.Active then
    begin
      TapiLine1.Active := False;
      Log('Device closed');
    end;
  end
  else
  begin
    if not TapiLine1.Active then
    try
      TapiLine1.Active := True;
      Log('Device opened');
    except
      on E:ETapiError do
      begin
        Log(E.Message);

        // Try it again with not privileges
        TapiLine1.Privileges.None := TRUE;
        try
          TapiLine1.Active := True;
          Log('Device opened, but not 100% TAPI compatible');
        except
          on E:ETapiError do
            Log(E.Message);
        end;
      end;  
    end;
  end;
end;

procedure TForm1.ComboBoxDeviceChange(Sender: TObject);
begin
  if TapiLine1.Active then
  begin
    CheckBoxActive.Checked := False;
    TapiLine1.Active := FALSE;
  end;
  TapiLine1.DeviceID := ComboBoxDevice.ItemIndex;
end;

procedure TForm1.UpdateCalls;
begin
  with TapiLine1 do
  begin
    if Calls.Count > 0 then
    begin
      Label_CallState.Caption := Calls[0].StateText;
      if Calls[0].IsOutgoing then
      begin
        Label_Info.Caption := 'Outgoing Call';
        { CalledID is a feature of the Professional Edition
        if Calls[0].CalledID.AddressAvail then
          Label_Info.Caption := Calls[0].CalledID.Address
        }
      end
      else if Calls[0].IsIncoming and Calls[0].CallerID.AddressAvail then
        Label_Info.Caption := Calls[0].CallerID.Address;
    end
    else
    begin
      Label_CallState.Caption := 'NO CALL';
      Label_Info.Caption      := '';
    end;
  end;
end;

procedure TForm1.UpdateComm;
begin
  if ComPort1.Active then
    Label_Com.Caption := 'ACTIVE'
  else
    Label_Com.Caption := 'NOT ACTIVE';
end;

function TForm1.GetCall: TTapiCall;
begin
  result := nil;
  if TapiLine1.Calls.Count > 0 then
  begin
    result := TapiLine1.Calls[0];
  end;
end;

procedure TForm1.DoMakeCall(Sender: TObject);
var cp: TTapiCallParams;
begin
  // use the TTapiCallParams entead of TTapiLine.CallParams
  cp := TTapiCallParams.Create;
  try
    cp.AddressMode  := LINEADDRESSMODE_ADDRESSID;
    cp.AddressID    := 0;
    cp.MediaMode    := LINEMEDIAMODE_DATAMODEM;
    cp.Flags        := 0;
    cp.NoAnswerTimeout := 3;
    TapiLine1.MakeCall(EditCallPhoneNumber.Text, 0, cp.TapiData);
  finally
    cp.Free;
  end;
end;

procedure TForm1.TapiLine1CallState(Sender: TTapiLine; Call: TTapiCall;
  CallState: Cardinal);
begin
  case Call.State of
    LINECALLSTATE_CONNECTED :
      if Call.Comm.Available and (ComPort1.Active = FALSE) then
      begin
        ComPort1.Handle := Call.Comm.Handle;
        try
          ComPort1.Active := True;
        except
        end;
      end;
  else
    if Comport1.Active then
    begin
      Comport1.Active := False;
      ComPort1.Handle := 0;
    end;
  end;
  UpdateCalls;
  UpdateComm;
end;

procedure TForm1.TapiLine1CallDeallocate(Sender: TTapiLine;
  Call: TTapiCall);
begin
  UpdateCalls;
end;

procedure TForm1.TapiLine1NewCall(Sender: TTapiLine; Call: TTapiCall);
begin
  UpdateCalls;
end;

procedure TForm1.DoDropCall(Sender: TObject);
var c: TTapiCall;
begin
  c := GetCall;
  if c = nil then exit;
  c.Drop;
end;

procedure TForm1.ButtonAnswerClick(Sender: TObject);
var c: TTapiCall;
begin
  c := GetCall;
  if c = nil then exit;
  c.Answer;
end;

procedure TForm1.ButtonSendClick(Sender: TObject);
begin
  ComPort1.Write(Edit1.Text);
end;

procedure TForm1.ComPort1IncomingData(Sender: TObject; const Data: String);
begin
  ListBox1.Items.Text := ListBox1.Items.Text + Data;
end;

procedure TForm1.ComPort1OutgoingData(Sender: TObject; const Data: String);
begin
 ListBox1.Items.Text := ListBox1.Items.Text + Data;
end;

procedure TForm1.TapiLine1Offering(Sender: TTapiLine; Call: TTapiCall);
begin
  if Checkbox1.Checked then
  try
    Call.Answer;
  except
    on E:ETapiError do
      Log(E.Message);
  end;
end;

end.


