{******************************************************************************} { CnPack For Delphi/C++Builder } { 中国人自己的开放源码第三方开发包 } { (C)Copyright 2001-2018 CnPack 开发组 } { ------------------------------------ } { } { 本开发包是开源的自由软件,您可以遵照 CnPack 的发布协议来修 } { 改和重新发布这一程序。 } { } { 发布这一开发包的目的是希望它有用,但没有任何担保。甚至没有 } { 适合特定目的而隐含的担保。更详细的情况请参阅 CnPack 发布协议。 } { } { 您应该已经和开发包一起收到一份 CnPack 发布协议的副本。如果 } { 还没有,可访问我们的网站: } { } { 网站地址:http://www.cnpack.org } { 电子邮件:master@cnpack.org } { } {******************************************************************************} unit CnRS232Dialog; {* |
================================================================================
* 软件名称:网络通讯组件包
* 单元名称:CnRS232Dialog 串口设置对话框组件及窗体单元
* 单元作者:周劲羽 (zjy@cnpack.org)
* 备    注:
* 开发平台:PWin98SE + Delphi 5.0
* 兼容测试:PWin9X/2000/XP + Delphi 5/6
* 本 地 化:该单元代码中的字符串符合本地化处理方式
*           该单元窗体中的字符串还不符合本地化处理方式
* 单元标识:$Id$
* 修改记录:2002.04.18 V1.1
*                重申明CommConfig和Timeouts为发布属性
*           2002.04.08 V1.0
*                创建单元
*                增加注释
================================================================================
|
} interface {$I CnPack.inc} uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, Buttons, CnClasses, CnConsts, CnRS232, CnNetConsts, CnSpin; type //------------------------------------------------------------------------------ // 串口设置对话框窗体 //------------------------------------------------------------------------------ { TCnRS232Dlg } TCnRS232Dlg = class(TForm) pcCommConfig: TPageControl; tsNormal: TTabSheet; tsXonXoff: TTabSheet; bbtnOk: TBitBtn; bbtnCancel: TBitBtn; cbbBaudRate: TComboBox; lblBaudRate: TLabel; cbTxContinueOnXoff: TCheckBox; cbOutx_XonXoffFlow: TCheckBox; cbInx_XonXoffFlow: TCheckBox; lblByteSize: TLabel; cbbByteSize: TComboBox; lblParity: TLabel; cbbParity: TComboBox; lblStopBits: TLabel; cbbStopBits: TComboBox; lblXonLimit: TLabel; lblXoffLimit: TLabel; lblXonChar: TLabel; lblXoffChar: TLabel; tsHardware: TTabSheet; lblDtrControl: TLabel; lblRtsControl: TLabel; cbOutx_CtsFlow: TCheckBox; cbOutx_DsrFlow: TCheckBox; cbDsrSensitivity: TCheckBox; cbbDtrControl: TComboBox; cbbRtsControl: TComboBox; cbReplaceWhenParityError: TCheckBox; cbIgnoreNullChar: TCheckBox; lblInCtrl: TLabel; lblOutCtrl: TLabel; tsTimeouts: TTabSheet; lblReadIntervalTimeout: TLabel; lblReadTotalTimeoutMultiplier: TLabel; lblMSec1: TLabel; lblMSec2: TLabel; lblReadTotalTimeoutConstant: TLabel; lblMSec3: TLabel; lblWriteTotalTimeoutMultiplier: TLabel; lblMSec4: TLabel; lblWriteTotalTimeoutConstant: TLabel; lblMSec5: TLabel; cbShowHint: TCheckBox; seReplacedChar: TCnSpinEdit; seXonLimit: TCnSpinEdit; seXonChar: TCnSpinEdit; seXoffChar: TCnSpinEdit; seXoffLimit: TCnSpinEdit; seReadIntervalTimeout: TCnSpinEdit; seReadTotalTimeoutMultiplier: TCnSpinEdit; seReadTotalTimeoutConstant: TCnSpinEdit; seWriteTotalTimeoutMultiplier: TCnSpinEdit; seWriteTotalTimeoutConstant: TCnSpinEdit; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure cbbBaudRateExit(Sender: TObject); procedure bbtnOkClick(Sender: TObject); procedure seReplacedCharExit(Sender: TObject); procedure FormShow(Sender: TObject); procedure seXonLimitExit(Sender: TObject); procedure ControlChanged(Sender: TObject); procedure cbShowHintClick(Sender: TObject); private { Private declarations } FCommConfig: TCnRS232Config; FTimeouts: TCnRS232Timeouts; procedure SetCommConfig(const Value: TCnRS232Config); procedure SetCommTimeouts(const Value: TCnRS232Timeouts); procedure ReadCommConfig; procedure WriteCommConfig; procedure ReadCommTimeouts; procedure WriteCommTimeouts; public { Public declarations } property CommConfig: TCnRS232Config read FCommConfig write SetCommConfig; property CommTimeouts: TCnRS232Timeouts read FTimeouts write SetCommTimeouts; end; //------------------------------------------------------------------------------ // 串口设置对话框组件 //------------------------------------------------------------------------------ { TCnRS232Dialog } TCnRS232DialogKind = (ckWin32, ckExtended); {* 串口设置对话框风格 |
     ckWin32:           - Win32标准风格
     ckExtended:        - 扩展对话框风格
   |
} TCnRS232DialogPages = set of (cpNormal, cpXonXoff, cpHardware, cpTimeouts); {* 串口设置对话框显示页面集合 |
     cpNormal:          - 常规设置页面
     cpXonXoff:         - 软件流量控制页面
     cpHardware:        - 硬件流量控制页面
     cpTimeouts:        - 超时设置页面
   |
} TCnRS232DialogShowHint = (csHint, csNoHint, csCheckHint, csCheckNoHint); {* 串口设置对话框工具提示信息显示方式 |
     csHint:            - 显示工具提示
     csNoHint:          - 不显示工具提示
     csCheckHint:       - 由单选框决定,默认为显示
     csCheckNoHint:     - 由单选框决定,默认为不显示
   |
} TCnRS232Dialog = class(TCnComponent) {* RS232串口设置对话框组件。 |
     * 组件用于显示串口设置对话框,一般搭配TCnRS232组件使用。
     * 使用方式类似于VCL中的常规对话框组件。
   |
} private FCommConfig: TCnRS232Config; FTimeouts: TCnRS232Timeouts; FKind: TCnRS232DialogKind; FPages: TCnRS232DialogPages; FCommName: string; FTitle: string; FBaudRateList: Boolean; FShowHint: TCnRS232DialogShowHint; FOnClose: TNotifyEvent; FOnShow: TNotifyEvent; procedure SetCommConfig(const Value: TCnRS232Config); procedure SetTimeouts(const Value: TCnRS232Timeouts); function GetHandle: THandle; protected procedure GetComponentInfo(var AName, Author, Email, Comment: string); override; procedure AssignTo(Dest: TPersistent); override; procedure DoShow; virtual; procedure DoClose; virtual; public procedure Assign(Source: TPersistent); override; {* 对象赋值方法,允许从TCnRS232中赋值} constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Execute: Boolean; {* 显示对话框,如果用户点击了“确认”按钮,返回为真} property CommName: string read FCommName write FCommName; {* 串口端口名} published property Title: string read FTitle write FTitle; {* 对话框标题,仅当 Kind 属性为 ckExtended 扩展风格时有效} property Kind: TCnRS232DialogKind read FKind write FKind default ckExtended; {* 对话框风格} property Pages: TCnRS232DialogPages read FPages write FPages default [cpNormal, cpXonXoff, cpHardware]; {* 对话框可显示的页面集合,仅当 Kind 属性为 ckExtended 扩展风格时有效} property BaudRateList: Boolean read FBaudRateList write FBaudRateList default True; {* 对话框中的波特率参数是否只允许从下拉列表中选择。如果为假,用户可自定义 非标准的小特率。仅当 Kind 属性为 ckExtended 扩展风格时有效} property ShowHint: TCnRS232DialogShowHint read FShowHint write FShowHint default csNoHint; {* 显示对话框中工具提示的方式,仅当 Kind 属性为 ckExtended 扩展风格时有效} property CommConfig: TCnRS232Config read FCommConfig write SetCommConfig; {* 串口通讯设置} property Timeouts: TCnRS232Timeouts read FTimeouts write SetTimeouts; {* 串口通讯超时设置} property OnClose: TNotifyEvent read FOnClose write FOnClose; {* 对话框关闭事件} property OnShow: TNotifyEvent read FOnShow write FOnShow; {* 对话框显示事件} end; implementation {$R *.DFM} //------------------------------------------------------------------------------ // 串口设置对话框窗体 //------------------------------------------------------------------------------ { TCnRS232Dlg } // 窗体创建 procedure TCnRS232Dlg.FormCreate(Sender: TObject); begin FCommConfig := TCnRS232Config.Create; FTimeouts := TCnRS232Timeouts.Create; WriteCommConfig; WriteCommTimeouts; end; // 窗体释放 procedure TCnRS232Dlg.FormDestroy(Sender: TObject); begin FCommConfig.Free; FTimeouts.Free; end; // 窗体显示 procedure TCnRS232Dlg.FormShow(Sender: TObject); begin WriteCommConfig; WriteCommTimeouts; ControlChanged(Self); end; // 确定 procedure TCnRS232Dlg.bbtnOkClick(Sender: TObject); begin ReadCommConfig; ReadCommTimeouts; ModalResult := mrOK; end; // 从控件中取串口设置 procedure TCnRS232Dlg.ReadCommConfig; begin with FCommConfig do begin XoffChar := Char(seXoffChar.Value); ReplacedChar := Char(seReplacedChar.Value); XonChar := Char(seXonChar.Value); Outx_CtsFlow := cbOutx_CtsFlow.Checked; Outx_DsrFlow := cbOutx_DsrFlow.Checked; ParityCheck := cbbParity.ItemIndex <> 0; IgnoreNullChar := cbIgnoreNullChar.Checked; Inx_XonXoffFlow := cbInx_XonXoffFlow.Checked; TxContinueOnXoff := cbTxContinueOnXoff.Checked; ReplaceWhenParityError := cbReplaceWhenParityError.Checked; Outx_XonXoffFlow := cbOutx_XonXoffFlow.Checked; DsrSensitivity := cbDsrSensitivity.Checked; BaudRate := StrToInt(cbbBaudRate.Text); ByteSize := TByteSize(cbbByteSize.ItemIndex); DtrControl := TDtrControl(cbbDtrControl.ItemIndex); Parity := TParity(cbbParity.ItemIndex); RtsControl := TRtsControl(cbbRtsControl.ItemIndex); StopBits := TStopBits(cbbStopBits.ItemIndex); XoffLimit := seXoffLimit.Value; XonLimit := seXonLimit.Value; end; end; // 从控件中取超时设置 procedure TCnRS232Dlg.ReadCommTimeouts; begin with FTimeouts do begin ReadTotalTimeoutConstant := seReadTotalTimeoutConstant.Value; ReadIntervalTimeout := seReadIntervalTimeout.Value; ReadTotalTimeoutMultiplier := seReadTotalTimeoutMultiplier.Value; WriteTotalTimeoutConstant := seWriteTotalTimeoutConstant.Value; WriteTotalTimeoutMultiplier := seWriteTotalTimeoutMultiplier.Value; end; end; // 根据参数设置控件 procedure TCnRS232Dlg.WriteCommConfig; begin with FCommConfig do begin seXoffChar.Value := Byte(XoffChar); seReplacedChar.Value := Byte(ReplacedChar); seXonChar.Value := Byte(XonChar); cbOutx_CtsFlow.Checked := Outx_CtsFlow; cbOutx_DsrFlow.Checked := Outx_DsrFlow; cbIgnoreNullChar.Checked := IgnoreNullChar; cbInx_XonXoffFlow.Checked := Inx_XonXoffFlow; cbTxContinueOnXoff.Checked := TxContinueOnXoff; cbReplaceWhenParityError.Checked := ReplaceWhenParityError; cbOutx_XonXoffFlow.Checked := Outx_XonXoffFlow; cbDsrSensitivity.Checked := DsrSensitivity; if cbbBaudRate.Style = csDropDown then cbbBaudRate.Text := IntToStr(BaudRate) else begin cbbBaudRate.ItemIndex := cbbBaudRate.Items.IndexOf(IntToStr(BaudRate)); if cbbBaudRate.ItemIndex < 0 then cbbBaudRate.ItemIndex := cbbBaudRate.Items.Add(IntToStr(BaudRate)); end; cbbByteSize.ItemIndex := Ord(ByteSize); cbbDtrControl.ItemIndex := Ord(DtrControl); cbbParity.ItemIndex := Ord(Parity); cbbRtsControl.ItemIndex := Ord(RtsControl); cbbStopBits.ItemIndex := Ord(StopBits); seXoffLimit.Value := XoffLimit; seXonLimit.Value := XonLimit; end; end; // 根据超时参数设置控件 procedure TCnRS232Dlg.WriteCommTimeouts; begin with FTimeouts do begin seReadTotalTimeoutConstant.Value := ReadTotalTimeoutConstant; seReadIntervalTimeout.Value := ReadIntervalTimeout; seReadTotalTimeoutMultiplier.Value := ReadTotalTimeoutMultiplier; seWriteTotalTimeoutConstant.Value := WriteTotalTimeoutConstant; seWriteTotalTimeoutMultiplier.Value := WriteTotalTimeoutMultiplier; end; end; // 设置参数 procedure TCnRS232Dlg.SetCommConfig(const Value: TCnRS232Config); begin FCommConfig.Assign(Value); WriteCommConfig; end; // 设置超时 procedure TCnRS232Dlg.SetCommTimeouts(const Value: TCnRS232Timeouts); begin FTimeouts.Assign(Value); WriteCommTimeouts; end; // 约束波特率 procedure TCnRS232Dlg.cbbBaudRateExit(Sender: TObject); begin try StrToInt(cbbBaudRate.Text); except MessageBox(Handle, PChar(SBaudRateError), PChar(SCnError), MB_OK + MB_ICONSTOP); cbbBaudRate.SetFocus; end; end; // 约束字符编辑控件 procedure TCnRS232Dlg.seReplacedCharExit(Sender: TObject); var i: Integer; begin if Sender is TCnSpinEdit then try i := StrToInt(TCnSpinEdit(Sender).Text); if (i > 255) or (i < 0) then raise Exception.Create(SCnError); if seXonChar.Text = seXoffChar.Text then begin MessageBox(Handle, PChar(SInvalidXonXoffChar), PChar(SCnError), MB_OK + MB_ICONSTOP); TCnSpinEdit(Sender).SetFocus; end; except MessageBox(Handle, PChar(SInputASCIICode), PChar(SCnError), MB_OK + MB_ICONSTOP); TCnSpinEdit(Sender).SetFocus; end; end; // 约束整数编辑控件 procedure TCnRS232Dlg.seXonLimitExit(Sender: TObject); var i: Integer; begin if Sender is TCnSpinEdit then try i := StrToInt(TCnSpinEdit(Sender).Text); if (i > MaxWord) or (i < 0) then raise Exception.Create(SCnError); except MessageBox(Handle, PChar(SInputInteger), PChar(SCnError), MB_OK + MB_ICONSTOP); TCnSpinEdit(Sender).SetFocus; end; end; // 设置控件状态 procedure TCnRS232Dlg.ControlChanged(Sender: TObject); begin cbReplaceWhenParityError.Enabled := cbbParity.ItemIndex > 0; seReplacedChar.Enabled := cbReplaceWhenParityError.Enabled and cbReplaceWhenParityError.Checked; end; // 设置工具提示 procedure TCnRS232Dlg.cbShowHintClick(Sender: TObject); begin ShowHint := cbShowHint.Checked; end; //------------------------------------------------------------------------------ // 串口设置对话框组件 //------------------------------------------------------------------------------ { TCnRS232Dialog } // 对象赋值方法 procedure TCnRS232Dialog.Assign(Source: TPersistent); begin if Source is TCnRS232 then begin FCommConfig.Assign(TCnRS232(Source).CommConfig); FTimeouts.Assign(TCnRS232(Source).Timeouts); FCommName := TCnRS232(Source).CommName; end else if Source is TCnRS232Dialog then begin TCnRS232Dialog(Source).AssignTo(Self); end else inherited; end; // 目标对象赋值方法 procedure TCnRS232Dialog.AssignTo(Dest: TPersistent); begin if Dest is TCnRS232 then begin TCnRS232(Dest).CommConfig := FCommConfig; TCnRS232(Dest).Timeouts := FTimeouts; end else if Dest is TCnRS232Dialog then begin TCnRS232Dialog(Dest).FCommConfig.Assign(FCommConfig); TCnRS232Dialog(Dest).FTimeouts.Assign(FTimeouts); TCnRS232Dialog(Dest).FCommName := FCommName; end else inherited; end; // 初始化 constructor TCnRS232Dialog.Create(AOwner: TComponent); begin inherited; FCommConfig := TCnRS232Config.Create; FTimeouts := TCnRS232Timeouts.Create; FKind := ckExtended; FPages := [cpNormal, cpXonXoff, cpHardware]; FBaudRateList := True; FShowHint := csNoHint; end; // 释放 destructor TCnRS232Dialog.Destroy; begin FCommConfig.Free; FTimeouts.Free; inherited; end; // 对话框关闭 procedure TCnRS232Dialog.DoClose; begin if Assigned(FOnClose) then FOnClose(Self); end; // 对话框显示 procedure TCnRS232Dialog.DoShow; begin if Assigned(FOnShow) then FOnShow(Self); end; // 显示对话框 function TCnRS232Dialog.Execute: Boolean; var CnRS232Dlg: TCnRS232Dlg; lpCC: TCommConfig; begin if FKind = ckExtended then // 扩展风格 begin CnRS232Dlg := TCnRS232Dlg.Create(Owner); try CnRS232Dlg.FCommConfig.Assign(FCommConfig); CnRS232Dlg.FTimeouts.Assign(FTimeouts); if FTitle <> '' then CnRS232Dlg.Caption := FTitle else if FCommName <> '' then CnRS232Dlg.Caption := Format('%s (%s)', [CnRS232Dlg.Caption, FCommName]); if FBaudRateList then CnRS232Dlg.cbbBaudRate.Style := csDropDownList else CnRS232Dlg.cbbBaudRate.Style := csDropDown; CnRS232Dlg.cbShowHint.Visible := FShowHint in [csCheckHint, csCheckNoHint]; CnRS232Dlg.cbShowHint.Checked := FShowHint in [csHint, csCheckHint]; CnRS232Dlg.ShowHint := CnRS232Dlg.cbShowHint.Checked; CnRS232Dlg.tsNormal.TabVisible := cpNormal in FPages; CnRS232Dlg.tsXonXoff.TabVisible := cpXonXoff in FPages; CnRS232Dlg.tsHardware.TabVisible := cpHardware in FPages; CnRS232Dlg.tsTimeouts.TabVisible := cpTimeouts in FPages; if FPages = [] then CnRS232Dlg.tsNormal.TabVisible := True; DoShow; Result := CnRS232Dlg.ShowModal = mrOK; if Result then begin FCommConfig.Assign(CnRS232Dlg.FCommConfig); FTimeouts.Assign(CnRS232Dlg.FTimeouts); end; DoClose; finally CnRS232Dlg.Free; end; end else begin FillChar(lpCC, SizeOf(lpCC), 0); lpCC.dwSize := SizeOf(lpCC); FCommConfig.GetDCB(lpCC.DCB); DoShow; Result := CommConfigDialog(PChar(FCommName), GetHandle, lpCC); if Result then FCommConfig.SetDCB(lpCC.DCB); DoClose; end; end; procedure TCnRS232Dialog.GetComponentInfo(var AName, Author, Email, Comment: string); begin AName := SCnRS232DialogName; Author := SCnPack_Zjy; Email := SCnPack_ZjyEmail; Comment := SCnRS232DialogComment; end; // 取父窗体句柄 function TCnRS232Dialog.GetHandle: THandle; begin if Owner is TForm then Result := TForm(Owner).Handle else Result := 0; end; // 设置参数 procedure TCnRS232Dialog.SetCommConfig(const Value: TCnRS232Config); begin FCommConfig.Assign(Value); end; // 设置超时 procedure TCnRS232Dialog.SetTimeouts(const Value: TCnRS232Timeouts); begin FTimeouts.Assign(Value); end; end.