⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adfaxsrv.pas

📁 测试用例
💻 PAS
📖 第 1 页 / 共 5 页
字号:
(***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is TurboPower Async Professional
 *
 * The Initial Developer of the Original Code is
 * TurboPower Software
 *
 * Portions created by the Initial Developer are Copyright (C) 1991-2002
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** *)

{*********************************************************}
{*                   ADFAXSRV.PAS 4.06                   *}
{*********************************************************}

{
Description:
  Implements the fax server components. The idea of the
  fax server components is to create fax job files (APJ)
  which consist of a job header (TApdFaxJobHeader),
  1 or more recipient headers (TApdFaxRecipientHeader),
  a text cover page, and a fax file (APF). The APJ is
  manipulated with the TApdFaxJobHandler class.
  -The TApdFaxClient component wraps the handler class.
  -The TApdFaxServerManager component monitors a dir
   when a server asks for a job to send. The manager
   does this by opening each APJ and checking the job
   header & finds the job with the earliest scheduled
   date.
  -The TApdFaxServer wraps a TApdSendFax, TApdReceiveFax
   and a few supporting components. The Server is the
   only part that talks to the modem. The server
   requests jobs based on the SendQueryInterval
   property. The server can also receive faxes.

Known problems:
  These components were designed to be compatible with D1 Standard/Win16,
  so we couldn't use any built-in DB support or other cool features.

Expansion points:
  -Convert over to require TAPI, and the TAPI passive
   answering with the internal TApdReceiveFax. A lot
   of code is now dedicated to switching back and
   forth between send/recv.
  -Change the manager so it is data-aware (looks in
   a DB instead of a dir)
}

{Global defines potentially affecting this unit}
{$I AWDEFINE.INC}

{Options required for this unit}
{$G+,X+,F-,V-,P-,T-,B-}

unit AdFaxSrv;
  { -Integrated Fax Server }

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, OoMisc, AdFax, AdPort, AdTapi, AdFaxPrn, AdExcept, AdFStat,
  AdFIDlg {used for TShowJobInfoDialog};

const
  adfDefDelayBetweenSends = 18;                  {in ticks}
  adfDefSendQueryInterval = 30;                  {in miliseconds (30 seconds) }
  adfDefJobFileExt = 'APJ';
  apfDefJobHeaderID = 810176577;                 {'APJ0' in hex editor}
  adfDefFaxServerManagerPaused = False;
  ServerManagerLockFileName = 'SRVMGR.LCK';

  { Status byte  for   Job Header            /   Recipient Info }
  stNone     = 0;    { no faxes sent         /   fax job not sent }
  stPartial  = 1;    { some faxes sent       /   fax job being sent }
  stComplete = 2;    { no more faxes to send /   fax job sent }
  stPaused   = 3;    { entire file paused    /   this job is paused }

type
  TFaxServerMode = (fsmIdle, fsmSend, fsmReceive);

  { predefine the classes }
  TApdFaxServerManager = class;                                        
  TApdCustomFaxServer = class;                                         

  { event types }
  TFaxServerStatusEvent = procedure(CP : TObject; FaxMode: TFaxServerMode;
    First, Last : Boolean; Status: Word) of object;
  TFaxServerFatalErrorEvent = procedure(CP: TObject; FaxMode: TFaxServerMode;
    ErrorCode, HangupCode: Integer) of object;
  TFaxServerFinishEvent = procedure(CP: TObject; FaxMode: TFaxServerMode;
    ErrorCode: Integer) of object;
  TFaxServerPortOpenCloseEvent = procedure(CP: TObject; Opening: Boolean) of object;
  TFaxServerAcceptEvent = procedure(CP : TObject; var Accept : Boolean) of object;
  TFaxServerNameEvent   = procedure(CP : TObject; var Name : TPassString) of object;
  TFaxServerLogEvent = procedure(CP : TObject; LogCode : TFaxLogCode;
    ServerCode : TFaxServerLogCode) of object;

  { TApdFaxServerManager events }
  TFaxServerManagerQueriedEvent = procedure(Mgr : TApdFaxServerManager;  
    QueryFrom : TApdCustomFaxServer; const JobToSend : string) of object;
  TManagerUpdateRecipientEvent = procedure (Mgr : TApdFaxServerManager;  
    JobFile : string; JobHeader : TFaxJobHeaderRec;                      
    var RecipHeader : TFaxRecipientRec) of object;                       

  TManagerUserGetJobEvent = procedure(Mgr : TApdFaxServerManager;        
    QueryFrom : TApdCustomFaxServer; var JobFile, FaxFile,               
    CoverFile : string; var RecipientNum : Integer) of object;           

  { Object used for ApdFaxServerManager.FFaxList to keep track of job files
    only used in ApdFaxServerManager's GetNextFax and UpdateStatus methods}
  TFaxListObj = class(TObject)
    FileTime: Integer;
    JobHeader: TFaxJobHeaderRec;
  end;

  { - The TApdFaxJobHandler class contains methods to manipulate APJ files, }
  {   the TApdFaxServerManager, and TApdFaxClient components are derived    }
  {   from this class to provide uniform APJ handling }
  TApdFaxJobHandler = class(TApdBaseComponent)
  public
    { - Adds a TFaxRecipientRec for a new recipient }
    procedure AddRecipient(JobFileName: TPassString;
      RecipientInfo: TFaxRecipientRec);
    { - Makes an APJ file from an APF, requires a recipient }
    procedure MakeJob(FaxName, CoverName, JobName, Sender, DestName: TPassString;
      Recipient: TFaxRecipientRec);
    { show dialog displaying information about the APJ }
    function ShowFaxJobInfoDialog(JobFileName, DlgCaption: TPassString): TModalResult;
    { - Extracts APF file from APJ, and saves to FaxName }
    procedure ExtractAPF(JobFileName, FaxName: TPassString);
    { - Extracts CoverPage text from APJ, and saves to CoverName, returns }
    {   true if a cover file is available, false otherwise }
    function ExtractCoverFile(JobFileName, CoverName: TPassString): Boolean;
    { - returns the FaxJobInfoRec for the Count recipient in the Job file }
    function GetRecipient(JobFileName: TPassString; Index: Integer;
      var Recipient: TFaxRecipientRec): Integer;
    { - returns the FaxJobHeaderRec for the specified JobFile }
    procedure GetJobHeader(JobFileName: TPassString;
      var JobHeader: TFaxJobHeaderRec);
    {- returns the status byte for the specified recipient }
    function GetRecipientStatus(JobFileName: TPassString;
      JobNum : Integer) : Integer;
    { - cancels an individual recipient }
    procedure CancelRecipient(JobFileName: TPassString; JobNum : Byte);
    { - Concatenates 2 APF files into 1 }
    procedure ConcatFaxes(DestFaxFile: TPassString; FaxFiles: array of TPassString);
    {- Resets all stPartial status flags to stNone, can set AttemptNum to 0 }
    procedure ResetAPJPartials(JobFileName: TPassString;                 {!!.03}
      ResetAttemptNum : Boolean);                                        {!!.03}
    {- Resets all status flags in an APJ to stNone}
    procedure ResetAPJStatus(JobFileName: TPassString);
    {- Resets individual recipient with new status, updates job header }
    procedure ResetRecipientStatus(JobFileName: TPassString;           
      JobNum, NewStatus: Byte);                                        
    {- Reschedules a recipient, updates job header }
    procedure RescheduleJob(JobFileName : TPassString;                 
      JobNum : Integer; NewSchedDT : TDateTime; ResetStatus: Boolean); 
  end;

  { - the ApdFaxServerManager controls the flow of fax jobs to the ApdFaxServer.
      An ApdFaxClient will deposit pre-composed fax job files (APJ) into the
      MonitorDir folder, and an ApdFaxServer will call the GetNextFax method to
      get the next fax to be sent }

  TApdFaxServerManager = class(TApdFaxJobHandler)
  private
    FMonitorDir: TPassString;
    FFaxList: TStringList;
    FJobFileExt: TPassString;
    FPaused: Boolean;
    FLockFile: TFileStream;
    FDeleteOnComplete: Boolean;                                        
    FFirstGetJob : Boolean;
    FInGetJob : Boolean;                                               
    FFaxServerManagerQueriedEvent: TFaxServerManagerQueriedEvent;      
    FManagerUpdateRecipientEvent: TManagerUpdateRecipientEvent;        
    FManagerUserGetJobEvent: TManagerUserGetJobEvent;                  
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;

    { - returns the file name of the next fax job to send }
    function GetNextFax: TPassString;
    { - returns the scheduled send time of the specified fax job }
    function GetSchedTime(JobFileName: TPassString): TDateTime;
    { - Returns the fax job in Recipient, True if ready, False otherwise }
    function GetJob(var Recipient: TFaxRecipientRec;
      QueryFrom: TApdCustomFaxServer; var JobFileName, FaxFile,        
      CoverFile: TPassString): Boolean;
    { - updates status of individual fax jobs }
    procedure UpdateStatus(JobFileName: TPassString; JobNumber, Result: Word;
      Failed: Boolean);
    { - Resets internal fax list and properties }
    procedure Reset;
    procedure SetMonitorDir(const Value: TPassString);
    property FaxList : TStringList
      read FFaxList;
  published
    {-  Delete the APJ after all jobs are complete }
    property DeleteOnComplete: Boolean                                 
      read FDeleteOnComplete write FDeleteOnComplete;                  
    { - The directory where we will look for APJ files }
    property MonitorDir: TPassString
      read FMonitorDir write SetMonitorDir;
    { - The default extension for APJ Files }
    property JobFileExt: TPassString
      read FJobFileExt write FJobFileExt;
    { - Pauses all fax jobs }
    property Paused: Boolean
      read FPaused write FPaused default adfDefFaxServerManagerPaused;
    { - Event generated when GetJob is called }
    property OnQueried : TFaxServerManagerQueriedEvent                
      read FFaxServerManagerQueriedEvent                              
      write FFaxServerManagerQueriedEvent;                            
    { - Event generated when a recipient is complete (ecOK or failed ) }
    property OnRecipientComplete : TManagerUpdateRecipientEvent       
      read FManagerUpdateRecipientEvent                               
      write FManagerUpdateRecipientEvent;                             
    { - Event generated to provide custom scheduling from app }
    { If this event is defined, this event will be responsible for }
    { feeding the fax jobs, the scheduling and queuing built into }
    { the ApdFaxServerManager will not be used }
    property OnCustomGetJob : TManagerUserGetJobEvent                 
      read FManagerUserGetJobEvent                                    
      write FManagerUserGetJobEvent;                                  
  end;


  { - The ApdFaxClient composes APJ files for use by the ApdFaxServerManager. }
  TApdFaxClient = class(TApdFaxJobHandler)
  private
    FJobName: TPassString;
    FSender: TPassString;
    FCoverFileName: TPassString;
    FJobFileName: TPassString;
    FFaxFileName: TPassString;
    function GetScheduleDateTime: TDateTime;
    procedure SetHeaderLine(const Value: TPassString);
    procedure SetHeaderRecipient(const Value: TPassString);
    procedure SetHeaderTitle(const Value: TPassString);
    procedure SetPhoneNumber(const Value: TPassString);
    procedure SetScheduleDateTime(const Value: TDateTime);
    function GetHeaderLine: TPassString;
    function GetHeaderRecipient: TPassString;
    function GetHeaderTitle: TPassString;
    function GetPhoneNumber: TPassString;
  public
    { - contains info about this job}
    Recipient: TFaxRecipientRec;
    constructor Create(AOwner: TComponent); override;
    { - Generic copying method }
    function CopyJobToServer(SourceJob, DestJob: TPassString;
      OverWrite: Boolean): Integer;
    { - Calls MakeJob with our property values }
    procedure MakeFaxJob;
    { - accepts TDateTime input to schedule job }
    property ScheduleDateTime: TDateTime
      read GetScheduleDateTime write SetScheduleDateTime;
  published
    { properties related to job header }
    property CoverFileName: TPassString
      read FCoverFileName write FCoverFileName;
    property FaxFileName: TPassString
      read FFaxFileName write FFaxFileName;
    property JobFileName: TPassString
      read FJobFileName write FJobFileName;
    property JobName: TPassString
      read FJobName write FJobName;
    property Sender: TPassString
      read FSender write FSender;
    { properties related to recipient, access methods refer to Recipient fields }
    property PhoneNumber: TPassString
      read GetPhoneNumber write SetPhoneNumber;
    property HeaderLine: TPassString
      read GetHeaderLine write SetHeaderLine;
    property HeaderRecipient: TPassString
      read GetHeaderRecipient write SetHeaderRecipient;
    property HeaderTitle: TPassString
      read GetHeaderTitle write SetHeaderTitle;
  end;

  TApdCustomFaxServer = class(TApdCustomAbstractFax)
  private
    { points to other components on the form }
    FComPort: TApdCustomComPort;
    FTapiDevice: TApdCustomTapiDevice;
    FStatusDisplay: TApdAbstractFaxStatus;
    FFaxLog: TApdFaxLog;
    { internal components }
    FSendFax: TApdSendFax;
    FRecvFax: TApdReceiveFax;
    FSendQueryTimer: TTimer;

    FSoftwareFlow: Boolean;
    FSafeMode: Boolean;
    FExitOnError: Boolean;
    FBlindDial: Boolean;
    FToneDial: Boolean;
    FConstantStatus: Boolean;
    FInitBaud: Integer;
    FNormalBaud: Integer;
    FCoverFile: TPassString;
    FHeaderTitle: TPassString;
    FPhoneNumber: TPassString;
    FHeaderLine: TPassString;
    FHeaderRecipient: TPassString;
    FDestinationDir: TPassString;
    FFaxFile: TPassString;
    FFaxFileExt: TPassString;
    FHeaderSender: TPassString;
    FFaxClass: TFaxClass;
    FFaxNameMode: TFaxNameMode;
    FModemInit: TModemString;
    FStationID: TStationID;
    FAnswerOnRing: Word;
    FBufferMinimum: Word;
    FStatusInterval: Word;
    FMaxSendCount: Word;
    FMonitoring: Boolean;
    FOldMonitoring: Boolean;
    FFaxPrinter: TApdCustomFaxPrinter;
    FPrintOnReceive: Boolean;

    FFaxServerMode: TFaxServerMode;
    FFaxInProgress: Boolean;
    FDesiredBPS: Word;
    FDesiredECM: Boolean;
    FDetectBusy: Boolean;
    FPageLength: LongInt;
    FDelayBetweenSends: Word;
    FServerManager: TApdFaxServerManager;
    FSendQueryInterval: Integer;
    FDialAttempts: Word;
    FDialWait: Word;
    FDialRetryWait: Word;                                              
    FDialPrefix: TModemString;
    FEnhFont: TFont;
    FEnhHeaderFont: TFont;
    FEnhTextEnabled: Boolean;
    WaitingOnTapi: Boolean;
    FServerLogCode: TFaxServerLogCode;
    FFaxServerFatalErrorEvent: TFaxServerFatalErrorEvent;
    FFaxServerStatusEvent: TFaxServerStatusEvent;
    FFaxServerFinishEvent: TFaxServerFinishEvent;
    FFaxServerPortOpenCloseEvent: TFaxServerPortOpenCloseEvent;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -