📄 frmtapi.pas
字号:
unit frmTapi;
{
Program name: Demo Phone
Version: V1.0
Date: Sepember 18th 2001
Requirements: amTapi Lite control, VOICE modem or TAPI compliant telephony device
Operating System: Windows 98, Windows ME, Windows NT 4, Windows 2000, Windows XP
Note: Under Windows NT 4 voice modems are not supported because of the lack of a
voice capable TAPI universal modem driver. #
Program Purpose: To demonstate how simple it is to add telephony functions to your
application using the Allen-Martin amTapi control. The supported features of this
demonstration program are:
(1) Enumerates the installed TAPI compliant telephony devices or modems.
(2) Translation of the subscriber telephone number to be called using the dialing
rules for the currently selected Location and telephony line device.
(3) Placing outgoing voice calls.
(4) Answering incoming voice calls
(5) Monitoring call progress
(6) Monitoring Caller ID for incoming calls.
(7) Monitoring remote DTMF touch key tones
This demonstration program does not show how to use all of the feature supported
by amTapi but should be sufficient to get you started. Further information can be
found in the help file. Additional sample demo programs may be found on our web
site www.allen-martin-inc.com
If you need to handle data calls or need to play and record wave files to\from
the telephone line you should consider using our amComm and amWave controls.
Professional and Enterprise versions of amTapi offering additional features are
also available, again see our web site for details.
}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, OleCtrls, AMITAPILib_TLB, reg;
type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
ComboLineName: TComboBox;
CommandCaps: TButton;
GroupBox2: TGroupBox;
TextSubscriberNumber: TEdit;
CommandTranslate: TButton;
CommandLocation: TButton;
Label1: TLabel;
LabelDisplayableNumber: TLabel;
GroupBox3: TGroupBox;
TextDialableNumber: TEdit;
CommandMakeCall: TButton;
GroupBox4: TGroupBox;
amTapi1: TamTapi;
Label2: TLabel;
LabelCallState: TLabel;
TextCallState: TMemo;
CommandClearStatus: TButton;
Label3: TLabel;
TextCallerID: TMemo;
CommandClearCallerID: TButton;
CommandAnswer: TButton;
CommandHangUp: TButton;
CheckAutoAnswer: TCheckBox;
LabelTAPIVersion: TLabel;
Memo1: TMemo;
Memo2: TMemo;
Memo3: TMemo;
GroupBox5: TGroupBox;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure CommandCapsClick(Sender: TObject);
procedure ComboLineNameChange(Sender: TObject);
procedure CommandClearStatusClick(Sender: TObject);
procedure CommandClearCallerIDClick(Sender: TObject);
procedure CommandTranslateClick(Sender: TObject);
procedure CommandLocationClick(Sender: TObject);
procedure CommandMakeCallClick(Sender: TObject);
procedure CommandAnswerClick(Sender: TObject);
procedure CommandHangUpClick(Sender: TObject);
procedure amTapi1Connected(Sender: TObject);
procedure amTapi1DigitReceived(Sender: TObject;
const Digit: WideString);
procedure amTapi1Disconnected(Sender: TObject);
procedure amTapi1Idle(Sender: TObject);
procedure amTapi1CallerID(Sender: TObject; const Number,
Name: WideString; Flags: Integer);
procedure amTapi1DelayedError(Sender: TObject; decType: Integer;
const Description: WideString);
procedure amTapi1CallState(Sender: TObject; const State: WideString);
procedure amTapi1IncomingCall(Sender: TObject; RingNumber: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;
function Iif(expr1:integer; expr2:integer; truepart:string; falsepart:string):string;
const OWNERCONST = 4;
MONITORCONST = 2;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
var
i : integer;
LineName : String;
SavedLineName : String;
SavedIndex : integer;
begin
LabelCallState.Caption:='Idle';
//The first time this app is run, the telephony line device to be used, will not have been
//saved in the registry, so display the following message to the user
ComboLineName.Text :='Select telephony line device';
//retrieve from the registry the name of the telephony line device to be used
SavedLineName := GetSetting('PhoneDemo', 'Settings', 'Line Device', 'Any impossible line name');
SavedIndex := -1;
//Enumerate TAPI Line devices, devices are numbered starting at 0
for i := 0 to amTapi1.NumberOfLines - 1 do
//Get the line name numbered i, this will also set the TapiNegotiatedVersion and
//the DevCaps properties to valid values for the line device numbered i
begin
LineName := amTapi1.GetLineName(i);
if (amTapi1.TapiNegotiatedVersion > 0) then
//If amTapi was able to negotiate a TAPI version then add the line device name to the combo
begin
ComboLineName.Items.add(LineName);
//If this is the line name saved in the registry save the line number
if (LineName = SavedLineName) then SavedIndex := ComboLineName.Items.Count - 1;
end;
end;
//If we found the line name the SavedIndex allows us to set the combo to the saved line name.
if not(SavedIndex = -1) then
begin
ComboLineName.ItemIndex := SavedIndex;
ComboLineNameChange(self);
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//Save in the registry the telephony line device name being used
SaveSetting('PhoneDemo', 'Settings', 'Line Device', ComboLineName.Text);
end;
procedure TForm1.CommandCapsClick(Sender: TObject);
var strCaps : string;
cps:integer;
begin
// Display the capabilities of the telephony line device seclected by the LineName property
cps:= amTapi1.DevCaps;
strCaps := 'Media Mode Capabilities:' + #9 + ' Supported' + #13#10 + #13#10;
strCaps := strCaps + #9 + 'Automated Voice ' + #9 + IIf(cps, AUTOMATEDVOICE, 'Yes', 'No') + #13#10;
strCaps := strCaps + #9 + 'Interactive Voice ' + #9 +IIf(cps, INTERACTIVEVOICE, 'Yes', 'No') + #13#10;
strCaps := strCaps + #9 + 'Data Modem ' + #9 + #9 + IIf(cps, DATAMODEM, 'Yes', 'No') + #13#10;
strCaps := strCaps + #9 + 'G3 Fax ' + #9 + #9 + #9 + IIf(cps, G3FAX, 'Yes', 'No') + #13#10;
strCaps := strCaps + #9 + 'G4 Fax ' + #9 + #9 + #9 + IIf(cps, G4FAX, 'Yes', 'No') + #13#10;
strCaps := strCaps + #13#10 + 'General Capabilities:' + #9 + ' Supported' + #13#10;
strCaps := strCaps + #9 + 'Caller ID ' + #9 + #9 + IIf(cps, CID, 'Yes', 'No') + #13#10;
strCaps := strCaps + #9 + 'Monitor DTMF Digits ' + #9 + IIf(cps, MONDIGITS, 'Yes', 'No') + #13#10;
strCaps := strCaps + #9 + 'Generate DTMF Digits ' + #9 + IIf(cps, GENDIGITS, 'Yes', 'No') + #13#10;
Showmessage(amTapi1.LineName + ' Capabilities' + #13#10 + strCaps);
end;
function Iif(expr1:integer; expr2:integer; truepart:string; falsepart:string):string;
begin
if ((expr1 and expr2)>0) then result:=truepart else result:=falsepart;
end;
procedure TForm1.amTapi1CallState(Sender: TObject; const State: WideString);
begin
TextCallState.lines.add(State);
if state='IDLE' then CommandAnswer.Enabled := False;
end;
procedure TForm1.ComboLineNameChange(Sender: TObject);
begin
//If the line is already open then close it
if amTapi1.LineOpen then amTapi1.LineOpen := False;
//Set the line name we want to use
amTapi1.LineName := ComboLineName.Text;
CommandCaps.Enabled := True;
//Display negotiated version
LabelTAPIVersion.Caption := 'TAPI V ' + inttostr((amTapi1.TapiNegotiatedVersion and 4294901760) div 65536) + '.' + inttostr(amTapi1.TapiNegotiatedVersion and 255);
//Test to make sure the telephony line device supports automated voice calls
if ((amTapi1.DevCaps And AUTOMATEDVOICE) > 0) then
begin
//Set the required media mode
amTapi1.MediaMode := AUTOMATEDVOICE;
//Set the call privilage for incoming calls to owner so that
//we can see and answer incoming calls
amTapi1.CallPrivilege := OWNERCONST;
//Open the line so that we can receive incoming calls or make outgoing calls
//you can leave the line open between calls, no need to close and re-open the line at the end of a call
amTapi1.LineOpen := True;
end
else
if ((amTapi1.DevCaps And INTERACTIVEVOICE) > 0) then
begin
//you can use INTERACTIVEVOICE (set in MediaMode) for data modems but you may get reduced call progress detection
amTapi1.MediaMode := INTERACTIVEVOICE;
//Set the call privilage for incoming calls to monitor
//we can't answer incoming calls
amTapi1.CallPrivilege := MONITORCONST;
//Open the line so that we can receive incoming calls or make outgoing calls
//you can leave the line open between calls, no need to close and re-open the line at the end of a call
amTapi1.LineOpen := True;
ShowMessage('Device does not support automated voice calls.' + #13#10 +
'DemoPhone is making the assumption that you are using a data only modem.' + #13#10 +
'Opening in INTERACTIVEVOICE mode.' + #13#10 +
'You will only be able to make outgoing calls.');
end
else
ShowMessage('Device does not support interactive or automated voice calls');
end;
procedure TForm1.CommandClearStatusClick(Sender: TObject);
begin
TextCallState.text:='';
end;
procedure TForm1.CommandClearCallerIDClick(Sender: TObject);
begin
TextCallerID.text:='';
end;
procedure TForm1.CommandTranslateClick(Sender: TObject);
var number:Widestring;
begin
if not(TextSubscriberNumber.text='') then
begin
//Number is in canonical format
Number := TextSubscriberNumber.Text;
//Translate the number, will return displayable number
LabelDisplayableNumber.Caption := amTapi1.TranslateNumber(Number);
//Number is now a dialable number
TextDialableNumber.Text := Number;
end;
end;
procedure TForm1.CommandLocationClick(Sender: TObject);
var NumberToDisplay : WideString;
begin
NumberToDisplay := TextSubscriberNumber.Text;
//NumberToDisplay is in canonical format, can be a null string but if we pass in a telephone
//number the user will see the effects of any changes made to the dialing rules in the Location Dialog
if not(NumberToDisplay='') then
amTapi1.ShowLocationDialog (self.handle, NumberToDisplay)
else
ShowMessage('Enter a valid phone number');
end;
procedure TForm1.CommandMakeCallClick(Sender: TObject);
begin
amTapi1.MakeCall (TextDialableNumber.Text);
LabelCallState.Caption := 'Dialing';
end;
procedure TForm1.CommandAnswerClick(Sender: TObject);
begin
amTapi1.Answer;
CommandAnswer.Enabled := False;
end;
procedure TForm1.CommandHangUpClick(Sender: TObject);
begin
amTapi1.HangUp;
CommandAnswer.Enabled:=true;
end;
procedure TForm1.amTapi1Connected(Sender: TObject);
begin
LabelCallState.Caption:='Connected';
end;
procedure TForm1.amTapi1DigitReceived(Sender: TObject;
const Digit: WideString);
begin
TextCallState.Lines.Add('Digit received ' + Digit);
end;
procedure TForm1.amTapi1Disconnected(Sender: TObject);
begin
LabelCallState.Caption := 'Disconnected';
amTapi1.HangUp;
CommandAnswer.Enabled:=true;
end;
procedure TForm1.amTapi1Idle(Sender: TObject);
begin
LabelCallState.Caption := 'Idle';
end;
procedure TForm1.amTapi1CallerID(Sender: TObject; const Number,
Name: WideString; Flags: Integer);
begin
//This event will fire when ever Caller ID info is availble for an incoming call
//the event may fire more than once for a call, each time giving further information as it becomes available
if (Flags And LINECALLPARTYID_PARTIAL) > 0 then TextCallerID.SelText := 'Partial info only' + #13#10;
if (Flags And LINECALLPARTYID_NAME) > 0 then TextCallerID.SelText := 'Name: ' + Name + #13#10;
if (Flags And LINECALLPARTYID_NUMBER) > 0 then TextCallerID.SelText := 'Number: ' + Number + #13#10;
if (Flags And LINECALLPARTYID_BLOCKED) > 0 then TextCallerID.SelText := 'Caller ID blocked' + #13#10;
if (Flags And LINECALLPARTYID_OUTOFAREA) > 0 then TextCallerID.SelText := 'Caller out of area' + #13#10;
if (Flags And LINECALLPARTYID_UNKNOWN) > 0 then TextCallerID.SelText := 'Caller ID unknown' + #13#10;
if (Flags And LINECALLPARTYID_PARTIAL) > 0 then TextCallerID.SelText := 'Partial info only' + #13#10;
end;
procedure TForm1.amTapi1DelayedError(Sender: TObject; decType: Integer;
const Description: WideString);
begin
case decType of
ANSWER_ERROR: ShowMessage('Answer error. ' + Description);
DIAL_ERROR: ShowMessage('Dialing error. ' + Description);
GENERATE_DIGITS_ERROR: ShowMessage('Generate digits error. ' + Description);
HANGUP_ERROR: ShowMessage('Hangup error. ' + Description);
MAKE_CALL_ERROR: ShowMessage('Make call error. ' + Description);
end;
end;
procedure TForm1.amTapi1IncomingCall(Sender: TObject; RingNumber: Integer);
begin
//this event will fire on an incoming call as long as we opened the line with owner or monitor CallPrivilege
LabelCallState.Caption := 'Ringing ' + Inttostr(RingNumber);
if CheckAutoAnswer.Checked then
//If auto answer selected answer the call after 2 rings
if RingNumber > 2 then amTapi1.Answer
else
//allow the user to manually answer the call if auto answer not selected
CommandAnswer.Enabled := True;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -