📄 adsmodem.pas
字号:
{ProcessConnectInfo(SModem);}
{Prepare for response but don't set a new timer}
msModemResponse := '';
msCRLFIndex := 0;
end;
{Now we are connected}
SetModemState(smsConnected);
end;
smsConnected :
begin
{We have either just finished waiting for connect information
and are now considered totally connected and ready for the user
to proceed (we will also install a status trigger on DCD to
watch for a line disconnect), or we have entered the state
machine at this point because the status trigger on DCD fired.
}
if (msModemStatusTrigger = 0) then begin
{Just finished connecting...}
msModemStatusTrigger := AddStatusTrigger(stModem);
SetStatusTrigger(msModemStatusTrigger, msDCDDelta, True);
Exit;
end else if (TriggerID = msModemStatusTrigger) and
not(FComPort.DCD) then begin
{We just lost DCD}
SetModemState(smsHangup);
if (msModemStatusTrigger <> 0) then begin
RemoveTrigger(msModemStatusTrigger);
msModemStatusTrigger := 0;
end;
SetModemState(smsReady);
end;
end;
end;
until {Finished}False;
end;
{end;}
end;
{- Dual-purpose code (prop. editor & dialog code) ---------}
procedure GetModemDatabaseEntries(ModemIniName : String;
var ModemList : TStringList; AtDesignTime : Boolean);
{Read the list of modems stored in the modem database (INI file)}
var
IniName : String;
ModemIni : TIniFile;
{$IFDEF Win32}
SearchSource : TRegIniFile;
{$ELSE}
SearchSource : TIniFile;
{$ENDIF}
procedure FindModemDatabase(var IniFileName : String);
var
TmpRegPath: String;
begin
{ Check if the specified modem database exists...if not we can't
select anything except the default modem. The algorithm for finding
AWMODEM.INI (or another named modem database) is different for
run-time and design-time. At run-time we check the WINDOWS directory,
the paramstr(0) directory, and the current directory. At design-time
we check the WINDOWS directory, the current directory, and the compiler
search path (obtained from DELPHI.INI for Delphi 1 and from the
registry for other versions).
}
IniFileName := '';
TmpRegPath := '';
if ModemIniName <> '' then begin
{we have a filename, now check if it already contains a path}
if ExtractFilePath(ModemIniName) <> '' then begin
{already have a path, so check if the file exists}
if FileExists(ModemIniName) then
IniFileName := ModemIniName;
end else begin
{first check the windows directory}
ModemIni := TIniFile.Create(ModemIniName);
if ModemIni.ReadInteger('Defaults','_Entries', 0) <> 0 then
IniFileName := ModemIniName;
ModemIni.Free;
if IniFileName = '' then begin
{not found in windows directory, so continue the search}
if AtDesignTime then begin
{design-time search}
{next check the compiler search path}
{$IFDEF Win32}
{$IFDEF Ver90}
TmpRegPath := 'Software\Borland\Delphi\2.0';
{$ELSE}
{$IFDEF Ver100}
TmpRegPath := 'Software\Borland\Delphi\3.0';
{$ELSE}
{$IFDEF Ver120}
TmpRegPath := 'Software\Borland\Delphi\4.0';
{$ELSE}
{$IFDEF Ver130}
TmpRegPath := 'Software\Borland\Delphi\5.0';
{$ELSE}
{$IFDEF Ver93}
TmpRegPath := 'Software\Borland\C++Builder\1.0';
{$ELSE}
{$IFDEF Ver110}
TmpRegPath := 'Software\Borland\C++Builder\3.0';
{$ELSE}
{$IFDEF Ver125}
TmpRegPath := 'Software\Borland\C++Builder\4.0';
{$ELSE}
{$IFDEF Ver130}
{$IFDEF BCB}
TmpRegPath := 'Software\Borland\C++Builder\5.0';
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$ENDIF}
SearchSource := TRegIniFile.Create(TmpRegPath);
{$ELSE}
SearchSource := TIniFile.Create('DELPHI.INI');
{$ENDIF}
IniFileName :=
FileSearch(ModemIniName,
SearchSource.ReadString('Library', 'SearchPath', ''));
SearchSource.Free;
{if we still have a path, it was in the current directory, so
expand the path}
if (IniFileName = ModemIniName) then
IniFileName := ExpandFileName(ModemIniName);
end else begin
{run-time search}
{check the paramstr(0) directory, then the current directory}
if FileExists(ExtractFilePath(ParamStr(0))+ModemIniName) then
IniFileName := ModemIniName
else if FileExists(ModemIniName) then
IniFileName := ExpandFileName(ModemIniName);
end;
end;
end;
end;
end;
begin
if not assigned(ModemList) then
Exit;
{Create the string list of modem names}
ModemList.Clear;
ModemList.Sorted := False; {keep the names in same order as INI file}
{If we don't have an ini source, we can't need to do the following}
FindModemDatabase(IniName);
if IniName <> '' then begin
{open the database and read the number of entries}
ModemIni := TIniFile.Create(IniName);
ModemIni.ReadSection('Index', ModemList);
ModemIni.Free;
end;
{add the "default" modem to the list}
ModemList.Insert(0, adsmDefaultModemTag);
end;
{- TApdCustomSModem ---------------------------------------}
constructor TApdCustomSModem.Create(AOwner : TComponent);
var
i : Integer;
begin
inherited Create(AOwner);
SetModemState(smsUnknown);
SetAllDefaults;
{Search our owner for a com port}
if Assigned(AOwner) and (AOwner.ComponentCount > 0) then
for I := 0 to Pred(AOwner.ComponentCount) do
if AOwner.Components[I] is TApdCustomComPort then begin
FComPort := TApdCustomComPort(AOwner.Components[I]);
Break;
end;
{Create a modem status display and link this modem instance to it}
FStatusDisplay := TApdSModemStatusDisplay.Create(nil);
with FStatusDisplay do begin
Visible := False;
SModem := Self;
msEraseAllValues;
end;
{Create a status info class}
FStatusInfo := TApdSModemStatusInfo.Create(Self);
end;
destructor TApdCustomSModem.Destroy;
begin
FStatusDisplay.Free;
FStatusDisplay := nil;
FStatusInfo.Free;
FStatusInfo := nil;
inherited Destroy;
end;
procedure TApdCustomSModem.Notification(AComponent : TComponent;
Operation : TOperation);
{Link/unlink comport when dropped or removed from form}
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) then begin
{See if our com port is going away}
if (AComponent = FComPort) then
FComPort := nil;
end else if (Operation = opInsert) then begin
{Check for a com port being installed}
if not Assigned(FComPort) and (AComponent is TApdCustomComPort) then
ComPort := TApdCustomComPort(AComponent);
end;
end;
function TApdCustomSModem.ParseMultiLineCommand(var Remainder : String) : String;
{Return the first part of a multi-line modem command from the string and
update the remainder with the first part removed}
var
DelimPos : Integer;
begin
DelimPos := pos(MultiCmdSeparator, Remainder);
if DelimPos > 0 then begin
Result := copy(Remainder, 1, pred(DelimPos));
Remainder := copy(Remainder, succ(DelimPos), length(Remainder));
end else begin
Result := Remainder;
Remainder := '';
end;
end;
procedure TApdCustomSModem.SetStarted(const StartIt : Boolean);
{Attempt to start (or stop) modem component}
begin
if (csDesigning in ComponentState) or
(csLoading in ComponentState) or
(StartIt = FStarted) then
Exit;
{Validate comport}
if not Assigned(FComPort) then
raise EPortNotAssigned.Create(ecPortNotAssigned, False);
if (FComPort.DeviceLayer = dlWinSock) then
raise ECannotUseWithWinSock.Create(ecCannotUseWithWinSock, False);
with FComPort do
if StartIt then begin
{Open the port if it isn't already}
Open := True;
{Register our trigger handler procedure}
Dispatcher.RegisterEventTriggerHandler(SimpleModemStateMachine);
{Register our data pointer to the comport record}
Dispatcher.SetDataPointer(Self, SModemDataPtrID);
{Install callback for port open/close}
RegisterUserCallback(HostPortClose);
{Set the best port speed for the modem}
Baud := FPreferredPortSpeed;
{Force the trigger length to 1}
Dispatcher.ChangeLengthTrigger(1);
{Set a timer for the status update}
msUpdateStatusTrigger := AddTimerTrigger;
Dispatcher.SetTimerTrigger(msUpdateStatusTrigger,
Secs2Ticks(FUpdateStatusTime), True);
{Define a timer to use for general timeouts}
msTimeoutTrigger := AddTimerTrigger;
end else begin
{Unhook our trigger handler procedure}
Dispatcher.DeregisterEventTriggerHandler(SimpleModemStateMachine);
{Set the comport record data trigger to nil}
Dispatcher.SetDataPointer(nil, SModemDataPtrID);
{Remove port open/close callback}
DeregisterUserCallback(HostPortClose);
{Change the modem status}
SetModemState(smsUnknown);
{Deallocate triggers}
if (msUpdateStatusTrigger <> 0) then begin
RemoveTrigger(msUpdateStatusTrigger);
msUpdateStatusTrigger := 0;
end;
if (msTimeoutTrigger <> 0) then begin
RemoveTrigger(msTimeoutTrigger);
msTimeoutTrigger := 0;
end;
if (msModemStatusTrigger <> 0) then begin
RemoveTrigger(msModemStatusTrigger);
msModemStatusTrigger := 0;
end;
end;
FStarted := StartIt;
end;
procedure TApdCustomSModem.VerifyStarted;
{Make sure modem is connected to valid comport and ready for use}
begin
if not Assigned(FComPort) then
raise EPortNotAssigned.Create(ecPortNotAssigned, False);
if not Started then begin
{attempt to start once}
Started := True;
if not Started then
{if still not started...}
raise EModemNotStarted.Create(ecModemNotStarted, False);
end;
{Check for reentrancy; should apply when AllowYielding = True}
if (FModemStateFlags and smsWaitForInProgress) <> 0 then
raise EModemBusy.Create(ecModemBusy, False);
end;
procedure TApdCustomSModem.HostPortClose(CP : TObject; Opening : Boolean);
{Called when the host port for the modem is opened or closed}
begin
if not Opening then
{ Started := False; }
end;
procedure TApdCustomSModem.SetComPort(const NewPort : TApdCustomComPort);
begin
if NewPort <> FComPort then begin
FComPort := NewPort;
end;
end;
procedure TApdCustomSModem.SetAllDefaults;
begin
FAnswerCmd := adsmDefAnswerCmd;
FDialCmd := adsmDefDialCmd;
FDialCancelCmd := adsmDefDialCancelCmd;
FDialTerminatorCmd := adsmDefDialTerminatorCmd;
FHangupCmd := adsmDefHangupCmd;
FInitializeCmd := adsmDefInitializeCmd;
FBusyMsg := adsmDefBusyMsg;
FConnectMsg := adsmDefConnectMsg;
FDataCompressionMsg := adsmDefDataCompressionMsg;
FErrorCorrectionMsg := adsmDefErrorCorrectionMsg;
FErrorMsg := adsmDefErrorMsg;
FNoCarrierMsg := adsmDefNoCarrierMsg;
FNoDialToneMsg := adsmDefNoDialToneMsg;
FOkMsg := adsmDefOkMsg;
FRingMsg := adsmDefRingMsg;
FAnswerTimeout := adsmDefAnswerTimeout;
FCmdTimeout := adsmDefCmdTimeout;
FConnectInfoTimeout := adsmDefConnectInfoTimeout;
FDialTimeout := adsmDefDialTimeout;
FRingWaitTimeout := adsmDefRingWaitTimeout;
FDTRDropHoldDelay := adsmDefDTRDropHoldDelay;
FInterCharDelay := adsmDefInterCharDelay;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -