{******************************************************************************} { 原始文件名:CnClasses.pas } { 单元作者:周劲羽(与月共舞) } { [email protected]; http://yygw.126.com } { 下载地址:http://cnpack.yeah.net } { 电子邮件:[email protected] } { 备注:该单元定义了开发包用到的公共基础类 } { 最后更新:2002.04.08 V1.0 } { } {******************************************************************************} unit CnClasses; interface {$I CnPack.inc} uses Windows, SysUtils, Classes; type //----------------------------------------------------------------------------// // 带更新通知的持久性类 // //----------------------------------------------------------------------------// { TCnPersistent } TCnPersistent = class(TPersistent) {* 带更新通知的持久性类} private FUpdateCount: Integer; FOnChanging: TNotifyEvent; FOnChange: TNotifyEvent; FOwner: TPersistent; protected function GetOwner: TPersistent; override; function IsUpdating: Boolean; {* 当前更新计数是否大于0(正在更新),只读属性} procedure OnChildChanging(Sender: TObject); virtual; {* 子属性开始更新事件处理过程,可做为参数传递给TCnPersistent.Create过程 |<BR> 默认为产生OnChanging事件,可重载} procedure OnChildChange(Sender: TObject); virtual; {* 子属性已变更事件处理过程,可做为参数传递给TCnPersistent.Create过程 |<BR> 默认为产生OnChange事件,可重载} procedure Changing; virtual; {* 对象内容开始更新,如果更新计数为0,产生OnChanging事件,可重载} procedure Changed; virtual; {* 对象内容已变更,如果更新计数为0,产生OnChange事件,可重载} property Owner: TPersistent read FOwner write FOwner; public constructor Create; overload; virtual; {* 构造器,用于产生一个该类的实例,可重载} constructor Create(ChangeProc: TNotifyEvent); overload; {* 构造器,参数用于给OnChange事件指定一个初始值} constructor Create(ChangingProc, ChangeProc: TNotifyEvent); overload; {* 构造器,参数用于给OnChanging和OnChange事件指定一个初始值} procedure BeginUpdate; virtual; {* 开始更新,如果当前更新计数为0,自动调用Changing方法,可重载 |<BR> 在对成批属性进行修改时请调用该方法,注意必须与EndUpdate成对使用} procedure EndUpdate; virtual; {* 结束更新,如果当前更新计数为0,自动调用Change方法,可重载 |<BR> 在对成批属性修改后请调用该方法,注意必须与BeginUpdate成对使用} published property OnChanging: TNotifyEvent read FOnChanging write FOnChanging; {* 对象开始更新事件} property OnChange: TNotifyEvent read FOnChange write FOnChange; {* 对象属性已变更事件} end; //----------------------------------------------------------------------------// // 线程安全的更新通知持久性类 // //----------------------------------------------------------------------------// { TCnThreadPersistent } TCnThreadPersistent = class(TCnPersistent) {* 线程安全的更新通知持久性类} private FLock: TRTLCriticalSection; FLockCount: Integer; protected property LockCount: Integer read FLockCount; {* 当前Lock计数,只读属性} public constructor Create; override; {* 构造器,用于产生一个该类的实例} destructor Destroy; override; procedure Lock; {* 进入临界区,为保证多线程同步而加锁,必须与Unlock成对使用} function TryLock: Boolean; {* 如果当前Lock计数为零,则加锁返回真,否则返回假 |<BR> 如果返回真,必须在操作完成后调用UnLock释放锁} procedure Unlock; {* 退出临界区,释放同步锁,必须与Lock成对使用} end; //----------------------------------------------------------------------------// // 带Enabled的更新通知持久性类 // //----------------------------------------------------------------------------// { TCnEnabledPersistent } TCnEnabledPersistent = class(TCnPersistent) {* 带Enabled的更新通知持久性类} private FEnabled: Boolean; protected procedure SetEnabled(const Value: Boolean); virtual; procedure Changed; override; public constructor Create; override; {* 构造器,用于产生一个该类的实例} procedure Assign(Source: TPersistent); override; published property Enabled: Boolean read FEnabled write SetEnabled default False; {* Enabled属性,如果为假,对Changed方法的调用将不产生OnChanging事件} end; //----------------------------------------------------------------------------// // 不可视组件基础类 // //----------------------------------------------------------------------------// { TCnComponent } TCnCopyRight = type string; TCnComponent = class(TComponent) {* CnPack不可视组件基类} private FAbout: TCnCopyRight; protected function GetAuthor: string; virtual; {* 取组件作者函数,返回组件作者信息,可重载} function GetComment: string; virtual; {* 取组件注释函数,返回组件注释,可重载} public constructor Create(AOwner: TComponent); override; published property About: TCnCopyRight read FAbout; {* 组件版本属性,仅在设计期使用} end; implementation uses CnConsts; var CounterLock: TRTLCriticalSection; //----------------------------------------------------------------------------// // 带更新通知的持久性类 // //----------------------------------------------------------------------------// { TCnPersistent } // 初始化(供重载) constructor TCnPersistent.Create; begin inherited; FUpdateCount := 0; end; // 初始化,参数为更新通知事件 constructor TCnPersistent.Create(ChangeProc: TNotifyEvent); begin Create; FOnChange := ChangeProc; end; // 初始化,参数为更新通知事件 constructor TCnPersistent.Create(ChangingProc, ChangeProc: TNotifyEvent); begin Create; FOnChanging := ChangingProc; FOnChange := ChangeProc; end; // 开始更新 procedure TCnPersistent.BeginUpdate; begin if not IsUpdating then Changing; // 开始更新 Inc(FUpdateCount); end; // 正在变更 procedure TCnPersistent.Changing; begin if not IsUpdating and Assigned(FOnChanging) then FOnChanging(Self); end; // 变更结束 procedure TCnPersistent.Changed; begin if not IsUpdating and Assigned(FOnChange) then FOnChange(Self); end; // 结束更新 procedure TCnPersistent.EndUpdate; begin // Assert不需要本地化 Assert(FUpdateCount > 0, 'Unpaired TCnPersistent.EndUpdate'); Dec(FUpdateCount); if not IsUpdating then Changed; end; // 取所有者 function TCnPersistent.GetOwner: TPersistent; begin Result := FOwner; end; // 子单位变更 procedure TCnPersistent.OnChildChanging(Sender: TObject); begin if not IsUpdating and Assigned(FOnChanging) then FOnChanging(Sender); end; // 子单位已变更 procedure TCnPersistent.OnChildChange(Sender: TObject); begin if not IsUpdating and Assigned(FOnChange) then FOnChange(Sender); end; // 正在更新 function TCnPersistent.IsUpdating: Boolean; begin Result := FUpdateCount > 0; end; //----------------------------------------------------------------------------// // 线程安全的更新通知持久性类 // //----------------------------------------------------------------------------// { TCnThreadPersistent } // 初始化 constructor TCnThreadPersistent.Create; begin inherited; InitializeCriticalSection(FLock); // 初始化临界区 end; // 释放 destructor TCnThreadPersistent.Destroy; begin DeleteCriticalSection(FLock); inherited; end; // 尝试进入临界区(如果已加锁返回 False) function TCnThreadPersistent.TryLock: Boolean; begin EnterCriticalSection(CounterLock); try Result := FLockCount = 0; if Result then Lock; finally LeaveCriticalSection(CounterLock); end; end; // 加锁 procedure TCnThreadPersistent.Lock; begin EnterCriticalSection(CounterLock); Inc(FLockCount); LeaveCriticalSection(CounterLock); EnterCriticalSection(FLock); end; // 释放锁 procedure TCnThreadPersistent.Unlock; begin LeaveCriticalSection(FLock); EnterCriticalSection(CounterLock); Dec(FLockCount); LeaveCriticalSection(CounterLock); end; //----------------------------------------------------------------------------// // 带Enabled的更新通知持久性类 // //----------------------------------------------------------------------------// { TCnEnabledPersistent } //赋值 procedure TCnEnabledPersistent.Assign(Source: TPersistent); begin if Source is TCnEnabledPersistent then FEnabled := TCnEnabledPersistent(Source).FEnabled else inherited Assign(Source); end; //更新通知 procedure TCnEnabledPersistent.Changed; begin if FEnabled then //如果能用则通知 inherited Changed; end; //创建 constructor TCnEnabledPersistent.Create; begin inherited Create; FEnabled := False; end; //设置参数 procedure TCnEnabledPersistent.SetEnabled(const Value: Boolean); begin if FEnabled <> Value then begin FEnabled := True; // 允许通知 Changed; FEnabled := Value; end; end; //----------------------------------------------------------------------------// // 不可视组件基础类 // //----------------------------------------------------------------------------// { TCnComponent } // 初始化 constructor TCnComponent.Create(AOwner: TComponent); begin inherited; FAbout := SCnPackAbout; end; // 返回组件作者 function TCnComponent.GetAuthor: string; begin Result := SCnPackGroup; end; // 返回组件注释 function TCnComponent.GetComment: string; begin Result := SCnPackUrl; end; initialization InitializeCriticalSection(CounterLock); finalization DeleteCriticalSection(CounterLock); end.