<iframe align="center" marginwidth="0" marginheight="0" src="http://www.zealware.com/csdnblog336280.html" frameborder="0" width="336" scrolling="no" height="280"></iframe>
Delphi之三汇模拟语音卡(SHT-8B/PCI/FAX)可复用源码
作者:成晓旭
设计简介:
1、 设计思路请参考本站Blog的另一篇文章:“Delphi之东进模拟语音卡(D160A)可复用源码”;链接http://blog.csdn.net/CXXSoft/archive/2006/08/23/1108211.aspx。
2、 其实,仔细对比,你会发现这两种卡的代码类方法签名几乎99%是一样的,也就是说,这两都之间,还需要更进一步的抽象,以解决“重复代码”或者“相似代码”的问题。
3、 更高层次的抽象,请参考我的设计文档。
4、 类图(以后补上):
5、 卡类源码:
//
------------------------------------------------------------------------------
//
// 产品名称:成晓旭的个人软件Delphi源码库
// 产品版本:CXXSoftdelphicodesourcelib2.0
// 模块名称:Delphi之三汇模拟语音卡类
// 模块描述:
// 单元文件:unSHCard8B.pas
// 开发作者:成晓旭
// 备注:任何人使用此文件时,请保留此段自述文件,谢谢!
// 开发时间:2003-12-03
// 修改历史:
// 修改描述:
// ------------------------------------------------------------------------------
unitunSHCard8B;
interface
uses
Windows,
// unDJTC08a32,unDJNewSig,
unBaseDefine,
// unDJ160ADefine,unDJChanne160A,
unShpa3api,unSHChanne18B,unSH8BDefine;
type
TCXXCommCard8B = class (TObject)
private
ChannelNumber:Word;
channelObject:arrayofTCXXSHChannel8B;
OnCardChannelState:TTrunkStatusEvent;
procedureReleaseCommDevice();
functionGetChannelObjectOrder( const aChannelID:Word):Word;
functionInitChannel(): boolean ;
public
constructorCreate( const trunkEvent:TTrunkStatusEvent);
destructorDestroy();override;
functionLoadCommDevice( const loadAll: boolean = false ): boolean ;
functionStartup(): boolean ;
functionGetAFreeChannel():Word;
functionGetChannelNumber():Word;
functionDialPhone( const aChannelID:Word; const DialPhoneNumber:PChar): boolean ;
functionHangUp( const aChannelID:Word): boolean ;
end;
implementation
const
SH_ConfigFile = ' C:ShCtiShConfig.ini ' ;
SH_IndexFile = ' C:ShCtiShIndex.ini ' ;
... {TCXXCommCard8B}
constructorTCXXCommCard8B.Create( const trunkEvent:TTrunkStatusEvent);
begin
ChannelNumber: = 0 ;
Self.OnCardChannelState: = trunkEvent;
end;
destructorTCXXCommCard8B.Destroy;
var
Loop:Word;
begin
if (Length(channelObject) > 0 )and(channelNumber > 0 )then
begin
for Loop: = 0 toChannelNumber - 1 do
begin
if Assigned(channelObject[Loop])then
begin
channelObject[Loop].Free();
channelObject[Loop]: = nil;
end;
end;
end;
ReleaseCommDevice();
end;
functionTCXXCommCard8B.DialPhone( const aChannelID:Word;
const DialPhoneNumber:PChar): boolean ;
var
K:Word;
begin
Result: = false ;
K: = GetChannelObjectOrder(aChannelID);
if (K ErrorTrunkNumber)and(Assigned(channelObject[K]))then
begin
Result: = channelObject[K].DialPhone(DialPhoneNumber);
end;
end;
procedureTCXXCommCard8B.ReleaseCommDevice();
begin
SsmCloseCti();
end;
functionTCXXCommCard8B.GetAFreeChannel():Word;
var
Loop:Word;
begin
Result: = ErrorTrunkNumber;
for Loop: = Low(channelObject)toHigh(channelObject) do
begin
if NOTchannelObject[Loop].CheckDialOutEnabled()then continue ;
if (channelObject[Loop].GetChannelStatus() = atsFree)then
begin
Result: = channelObject[Loop].GetChannelID();
break ;
end;
end;
end;
functionTCXXCommCard8B.GetChannelNumber():Word;
begin
Result: = channelNumber;
end;
functionTCXXCommCard8B.GetChannelObjectOrder(
const aChannelID:Word):Word;
var
Loop:Word;
begin
Result: = ErrorTrunkNumber;
for Loop: = Low(channelObject)toHigh(channelObject) do
begin
if (channelObject[Loop].GetChannelID = aChannelID)then
begin
Result: = Loop;
break ;
end;
end;
end;
functionTCXXCommCard8B.HangUp( const aChannelID:Word): boolean ;
var
K:Word;
begin
Result: = false ;
K: = GetChannelObjectOrder(aChannelID);
if (K ErrorTrunkNumber)and(Assigned(channelObject[K]))then
begin
channelObject[K].ChannelHangUp();
Result: = true ;
end;
end;
functionTCXXCommCard8B.LoadCommDevice( const loadAll: boolean ): boolean ;
const
loadEmpty = true ;
begin
Result: = false ;
if SsmStartCti(SH_ConfigFile,SH_IndexFile) 0 then
begin
TCXXSHChannel8B.InformInvodeError();
Exit;
end;
if (SsmGetMaxUsableBoard() SsmGetMaxCfgBoard())then
begin // 部分板卡初始化失败,取出失败原因
TCXXSHChannel8B.InformInvodeError();
Exit;
end;
Result: = InitChannel();
end;
functionTCXXCommCard8B.Startup(): boolean ;
var
Loop:integer;
begin
for Loop: = 0 tochannelNumber - 1 do
begin
channelObject[Loop].Startup();
end;
Result: = true ;
end;
functionTCXXCommCard8B.InitChannel(): boolean ;
var
number,Loop:integer;
begin
Result: = false ;
number: = SsmGetMaxCh();
if (number 0)thenExit;
ChannelNumber:=number;
SetLength(channelObject,channelNumber);
forLoop:=0tochannelNumber-1do
begin
channelObject[Loop]:=TCXXSHChannel8B.Create(OnCardChannelState);
channelObject[Loop].CreateCommChannel(Loop);
end;
Result:=true;
end;
end.
//
// 产品名称:成晓旭的个人软件Delphi源码库
// 产品版本:CXXSoftdelphicodesourcelib2.0
// 模块名称:Delphi之三汇模拟语音卡类
// 模块描述:
// 单元文件:unSHCard8B.pas
// 开发作者:成晓旭
// 备注:任何人使用此文件时,请保留此段自述文件,谢谢!
// 开发时间:2003-12-03
// 修改历史:
// 修改描述:
// ------------------------------------------------------------------------------
unitunSHCard8B;
interface
uses
Windows,
// unDJTC08a32,unDJNewSig,
unBaseDefine,
// unDJ160ADefine,unDJChanne160A,
unShpa3api,unSHChanne18B,unSH8BDefine;
type
TCXXCommCard8B = class (TObject)
private
ChannelNumber:Word;
channelObject:arrayofTCXXSHChannel8B;
OnCardChannelState:TTrunkStatusEvent;
procedureReleaseCommDevice();
functionGetChannelObjectOrder( const aChannelID:Word):Word;
functionInitChannel(): boolean ;
public
constructorCreate( const trunkEvent:TTrunkStatusEvent);
destructorDestroy();override;
functionLoadCommDevice( const loadAll: boolean = false ): boolean ;
functionStartup(): boolean ;
functionGetAFreeChannel():Word;
functionGetChannelNumber():Word;
functionDialPhone( const aChannelID:Word; const DialPhoneNumber:PChar): boolean ;
functionHangUp( const aChannelID:Word): boolean ;
end;
implementation
const
SH_ConfigFile = ' C:ShCtiShConfig.ini ' ;
SH_IndexFile = ' C:ShCtiShIndex.ini ' ;
... {TCXXCommCard8B}
constructorTCXXCommCard8B.Create( const trunkEvent:TTrunkStatusEvent);
begin
ChannelNumber: = 0 ;
Self.OnCardChannelState: = trunkEvent;
end;
destructorTCXXCommCard8B.Destroy;
var
Loop:Word;
begin
if (Length(channelObject) > 0 )and(channelNumber > 0 )then
begin
for Loop: = 0 toChannelNumber - 1 do
begin
if Assigned(channelObject[Loop])then
begin
channelObject[Loop].Free();
channelObject[Loop]: = nil;
end;
end;
end;
ReleaseCommDevice();
end;
functionTCXXCommCard8B.DialPhone( const aChannelID:Word;
const DialPhoneNumber:PChar): boolean ;
var
K:Word;
begin
Result: = false ;
K: = GetChannelObjectOrder(aChannelID);
if (K ErrorTrunkNumber)and(Assigned(channelObject[K]))then
begin
Result: = channelObject[K].DialPhone(DialPhoneNumber);
end;
end;
procedureTCXXCommCard8B.ReleaseCommDevice();
begin
SsmCloseCti();
end;
functionTCXXCommCard8B.GetAFreeChannel():Word;
var
Loop:Word;
begin
Result: = ErrorTrunkNumber;
for Loop: = Low(channelObject)toHigh(channelObject) do
begin
if NOTchannelObject[Loop].CheckDialOutEnabled()then continue ;
if (channelObject[Loop].GetChannelStatus() = atsFree)then
begin
Result: = channelObject[Loop].GetChannelID();
break ;
end;
end;
end;
functionTCXXCommCard8B.GetChannelNumber():Word;
begin
Result: = channelNumber;
end;
functionTCXXCommCard8B.GetChannelObjectOrder(
const aChannelID:Word):Word;
var
Loop:Word;
begin
Result: = ErrorTrunkNumber;
for Loop: = Low(channelObject)toHigh(channelObject) do
begin
if (channelObject[Loop].GetChannelID = aChannelID)then
begin
Result: = Loop;
break ;
end;
end;
end;
functionTCXXCommCard8B.HangUp( const aChannelID:Word): boolean ;
var
K:Word;
begin
Result: = false ;
K: = GetChannelObjectOrder(aChannelID);
if (K ErrorTrunkNumber)and(Assigned(channelObject[K]))then
begin
channelObject[K].ChannelHangUp();
Result: = true ;
end;
end;
functionTCXXCommCard8B.LoadCommDevice( const loadAll: boolean ): boolean ;
const
loadEmpty = true ;
begin
Result: = false ;
if SsmStartCti(SH_ConfigFile,SH_IndexFile) 0 then
begin
TCXXSHChannel8B.InformInvodeError();
Exit;
end;
if (SsmGetMaxUsableBoard() SsmGetMaxCfgBoard())then
begin // 部分板卡初始化失败,取出失败原因
TCXXSHChannel8B.InformInvodeError();
Exit;
end;
Result: = InitChannel();
end;
functionTCXXCommCard8B.Startup(): boolean ;
var
Loop:integer;
begin
for Loop: = 0 tochannelNumber - 1 do
begin
channelObject[Loop].Startup();
end;
Result: = true ;
end;
functionTCXXCommCard8B.InitChannel(): boolean ;
var
number,Loop:integer;
begin
Result: = false ;
number: = SsmGetMaxCh();
if (number 0)thenExit;
ChannelNumber:=number;
SetLength(channelObject,channelNumber);
forLoop:=0tochannelNumber-1do
begin
channelObject[Loop]:=TCXXSHChannel8B.Create(OnCardChannelState);
channelObject[Loop].CreateCommChannel(Loop);
end;
Result:=true;
end;
end.
6、 通道类源码:
//
------------------------------------------------------------------------------
//
// 产品名称:成晓旭的个人软件Delphi源码库
// 产品版本:CXXSoftdelphicodesourcelib2.0
// 模块名称:Delphi之三汇模拟语音卡通道类
// 模块描述:
// 单元文件:unSHChanne18B.pas
// 开发作者:成晓旭
// 备注:任何人使用此文件时,请保留此段自述文件,谢谢!
// 开发时间:2003-12-01
// 修改历史:
// 修改描述:
// ------------------------------------------------------------------------------
unitunSHChanne18B;
... {$DEFINEThreadChannel}
interface
uses
Windows,Classes,SysUtils,
unBaseDefine,unShpa3api,unSH8BDefine,
// unDJ160ADefine,
unDJTC08a32,unDJNewSig;
Type
... {$IFDEFThreadChannel}
TCXXSHChannel8B = class (TThread)
... {$ELSE}
TCXXSHChannel8B = class (TObject)
... {$ENDIF}
private
channelType:TChannelType;
oldChannelState,channelState:TTrunkState;
channelID:Word;
phoneNumber:string;
dtmfString:string;
aCallerId:PAnsiChar;
isConntectd: boolean ;
isDialOut: boolean ;
aTrunkState:TTrunkStatus;
procedureChannelProcessor();
procedureInformTrunkStatus( const aMsgFlag:TLVOperateFlag);
procedureClearTrunkStatus();
procedureClearChannelBuffer();
functionCheckSigHangup(): boolean ;
functionCheckCallIn(): boolean ;
functionSwitchOnCallIn(): boolean ;
procedureProcessCallInSuccess();
procedureProcessDialSuccess();
procedureProcessCheckDialSend();
procedureProcessDialOut();
procedureStop();
// 三汇卡专用方法
functionGetTrunkStateBySsm( const ssmState:integer):TTrunkState;
protected
... {$IFDEFThreadChannel}
procedureExecute();override;
... {$ENDIF}
public
strMessage:string;
OnChannelState:TTrunkStatusEvent;
constructorCreate( const trunkEvent:TTrunkStatusEvent);
destructorDestroy();override;
procedureCreateCommChannel( const aChennelID:Word);
procedureStartup();
functionGetChannelID():Word;
functionGetChannelStatus():TTrunkState;
functionGetChannelType():TChannelType;
functionDialPhone( const DialPhoneNumber:PChar): boolean ;overload;
functionDialPhone( const DialPhoneNumber:PChar; const PreDialNumber:PChar): boolean ;overload;
procedureChannelHangUp();
functionGetDialOut(): boolean ;
// 三汇卡特性方法
functionCheckDialOutEnabled(): boolean ;
class procedureInformInvodeError();
end;
implementation
... {TCXXSHChannel8B}
procedureTCXXSHChannel8B.ChannelHangUp();
begin
isDialOut: = false ;
SsmHangUp(channelID);
ClearChannelBuffer();
ClearTrunkStatus();
InformTrunkStatus(lvofUpdate);
end;
procedureTCXXSHChannel8B.ChannelProcessor();
var
ssmState:integer;
begin
// ssmState:=SsmGetChState(channelID);
// channelState:=GetTrunkStateBySsm(ssmState);
CheckCallIn();
case channelStateof
atsFree:
begin
//
end;
atsCallIning:
begin
SwitchOnCallIn();
end;
atsCallInSuccess:
begin
if CheckSigHangup()thenExit;
ProcessCallInSuccess();
end;
atsCheckSendDial:
begin
ProcessCheckDialSend();
end;
atsDialing:
begin
ProcessDialOut();
end;
atsDialSuccess:
begin
if CheckSigHangup()thenExit;
ProcessDialSuccess();
strMessage: =
//
// 产品名称:成晓旭的个人软件Delphi源码库
// 产品版本:CXXSoftdelphicodesourcelib2.0
// 模块名称:Delphi之三汇模拟语音卡通道类
// 模块描述:
// 单元文件:unSHChanne18B.pas
// 开发作者:成晓旭
// 备注:任何人使用此文件时,请保留此段自述文件,谢谢!
// 开发时间:2003-12-01
// 修改历史:
// 修改描述:
// ------------------------------------------------------------------------------
unitunSHChanne18B;
... {$DEFINEThreadChannel}
interface
uses
Windows,Classes,SysUtils,
unBaseDefine,unShpa3api,unSH8BDefine,
// unDJ160ADefine,
unDJTC08a32,unDJNewSig;
Type
... {$IFDEFThreadChannel}
TCXXSHChannel8B = class (TThread)
... {$ELSE}
TCXXSHChannel8B = class (TObject)
... {$ENDIF}
private
channelType:TChannelType;
oldChannelState,channelState:TTrunkState;
channelID:Word;
phoneNumber:string;
dtmfString:string;
aCallerId:PAnsiChar;
isConntectd: boolean ;
isDialOut: boolean ;
aTrunkState:TTrunkStatus;
procedureChannelProcessor();
procedureInformTrunkStatus( const aMsgFlag:TLVOperateFlag);
procedureClearTrunkStatus();
procedureClearChannelBuffer();
functionCheckSigHangup(): boolean ;
functionCheckCallIn(): boolean ;
functionSwitchOnCallIn(): boolean ;
procedureProcessCallInSuccess();
procedureProcessDialSuccess();
procedureProcessCheckDialSend();
procedureProcessDialOut();
procedureStop();
// 三汇卡专用方法
functionGetTrunkStateBySsm( const ssmState:integer):TTrunkState;
protected
... {$IFDEFThreadChannel}
procedureExecute();override;
... {$ENDIF}
public
strMessage:string;
OnChannelState:TTrunkStatusEvent;
constructorCreate( const trunkEvent:TTrunkStatusEvent);
destructorDestroy();override;
procedureCreateCommChannel( const aChennelID:Word);
procedureStartup();
functionGetChannelID():Word;
functionGetChannelStatus():TTrunkState;
functionGetChannelType():TChannelType;
functionDialPhone( const DialPhoneNumber:PChar): boolean ;overload;
functionDialPhone( const DialPhoneNumber:PChar; const PreDialNumber:PChar): boolean ;overload;
procedureChannelHangUp();
functionGetDialOut(): boolean ;
// 三汇卡特性方法
functionCheckDialOutEnabled(): boolean ;
class procedureInformInvodeError();
end;
implementation
... {TCXXSHChannel8B}
procedureTCXXSHChannel8B.ChannelHangUp();
begin
isDialOut: = false ;
SsmHangUp(channelID);
ClearChannelBuffer();
ClearTrunkStatus();
InformTrunkStatus(lvofUpdate);
end;
procedureTCXXSHChannel8B.ChannelProcessor();
var
ssmState:integer;
begin
// ssmState:=SsmGetChState(channelID);
// channelState:=GetTrunkStateBySsm(ssmState);
CheckCallIn();
case channelStateof
atsFree:
begin
//
end;
atsCallIning:
begin
SwitchOnCallIn();
end;
atsCallInSuccess:
begin
if CheckSigHangup()thenExit;
ProcessCallInSuccess();
end;
atsCheckSendDial:
begin
ProcessCheckDialSend();
end;
atsDialing:
begin
ProcessDialOut();
end;
atsDialSuccess:
begin
if CheckSigHangup()thenExit;
ProcessDialSuccess();
strMessage: =