终于搞定 FormCont,现贴出以共享。希望多提建议(0分)

  • 主题发起人 主题发起人 ddev
  • 开始时间 开始时间
D

ddev

Unregistered / Unconfirmed
GUEST, unregistred user!
{
-----------------------------------------------------------------------------

Delphi Developer's Kit

Copyright (C) 2002 by ddev(china)

-----------------------------------------------------------------------------
Components:
TddkFormcont: A containter to accept forms as child
TddkActionForm: A form process action handle

-----------------------------------------------------------------------------
}
unit ddkforms;

interface

uses
Windows, SysUtils, Classes, Controls, Forms;

type
{ TddkFormcont: A containter to accept forms as child
This component profer a simple interface to accept form as a child-win,
no effects, no form-list, etc.
}
TddkFormChangeEvent = procedure(Sender: TObject; OldForm, NewForm: TCustomForm; var Accept: Boolean) of object;
TddkFormNotifyEvent = procedure(Sender: TObject; AForm: TCustomForm; var Accept: Boolean) of object;

TddkFormCont = class(TCustomControl)
private
FChildForm: TCustomForm;
FOnFormChange: TddkFormChangeEvent;
FOnFormClose: TddkFormNotifyEvent;
FBorderStyle: TBorderStyle;
procedure SetBorderStyle(const Value: TBorderStyle);
protected
procedure DoShowChildForm(AForm: TCustomForm); dynamic;
function DoCloseChildForm(const ForceClose: Boolean = False): Boolean; dynamic;
procedure CreateParams(var Params: TCreateParams); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure ShowForm(AForm: TCustomForm); overload;
procedure ShowForm(AFormClass: TFormClass); overload;
procedure CloseForm;
published
property OnFormChange: TddkFormChangeEvent read FOnFormChange write FOnFormChange;
property OnFormClose: TddkFormNotifyEvent read FOnFormClose write FOnFormClose;
property BorderStyle: TBorderStyle read FBorderStyle write SetBorderStyle default bsNone;
property Anchors;
property Align;
property Color;
end;

{ TddkActionForm }

TddkActionForm = class(TForm)
protected

public
function QueryActions(const dwActionID: Longint; var dwActionFlag: Longint): Boolean; virtual; abstract;
function PerformActions(const dwActionID, dwActionFlag: Longint): Boolean; virtual; abstract;
end;

implementation

{ TddkFormCont }

constructor TddkFormCont.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FBorderStyle := bsNone;
FChildForm := nil;
end;

procedure TddkFormCont.CreateParams(var Params: TCreateParams);
const
BorderStyles: array[TBorderStyle] of DWORD = (0, WS_BORDER);
begin
inherited CreateParams(Params);
with Params do
begin
Style := Style or BorderStyles[FBorderStyle];
if NewStyleControls and Ctl3D and (FBorderStyle = bsSingle) then
begin
Style := Style and not WS_BORDER;
ExStyle := ExStyle or WS_EX_CLIENTEDGE;
end;
WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
end;
end;

destructor TddkFormCont.Destroy;
begin
DoCloseChildForm(True);
inherited Destroy;
end;

procedure TddkFormCont.ShowForm(AForm: TCustomForm);
begin
DoShowChildForm(AForm);
end;

procedure TddkFormCont.ShowForm(AFormClass: TFormClass);
var
AForm: TCustomForm;
begin
AForm := AFormClass.Create(Self);
DoShowChildForm(AForm);
end;

procedure TddkFormCont.CloseForm;
begin
DoCloseChildForm;
end;

procedure TddkFormCont.DoShowChildForm(AForm: TCustomForm);
var
Accept: Boolean;
begin
// Close the Last contained form
Accept := True;
if Assigned(FChildForm) then
begin
if Assigned(FOnFormChange) then
FOnFormChange(Self, FChildForm, AForm, Accept);

if Accept then
Accept := DoCloseChildForm;
end;
if not Accept then Exit;

// Accept the new form
FChildForm := AForm;
FChildForm.BorderStyle := bsNone;
FChildForm.Parent := Self;
FChildForm.WindowState := wsMaximized;
FChildForm.Show ;
end;

function TddkFormCont.DoCloseChildForm(const ForceClose: Boolean): Boolean;
begin
// Close current contained ChildForm
Result := True;
if Assigned(FChildForm) then
begin
if Assigned(FOnFormClose) then
FOnFormClose(Self, FChildForm, Result);

if Result or ForceClose then
FChildForm.Close else Exit;
end;

// Forbitten FChildForm to nil
FChildForm := nil ;
end;

procedure TddkFormCont.SetBorderStyle(const Value: TBorderStyle);
begin
if FBorderStyle <> Value then
begin
FBorderStyle := Value;
RecreateWnd;
end;
end;

end.
 
给个DEMO 说服力更强
 
关于 FormCont,其实质是让一个 TWinControl 类的子类作为
窗口的“父”。这就是一个窗口容器的全部精义。

这个组件从 TCustomControl 派生是因为:用户可以不必要设
AChildForm.WindowState = wsMaximized,可以用 Anchors
控制子窗口的排列。并且可以在 Paint() 中覆盖绘制,比如
加个窗口标题,显示什么信息等等,可以避免再加入一个新的
组件。

还有就是:在 TddkFormCont 的宿主窗口关闭时,必须执行一
次 ddkFormCont.CloseForm,这样子窗口才能接受到关闭消息。
切记切记!

至于 Demo,作为一个 Delphi 开发者,也不用我来提供了吧,
这个组件并不复杂,用户可以自行任意扩展。

==问题==:记得那个在 D5 下的 FormContainter 吗?它必须
接受一个 BorderStyle = bsNone 的窗口,而且提供了大量的
组件效果,如:滑入、卷入等等。这就不知道为什么了?难道
这些效果的演示必须是一个 bsNone 的窗口吗?
 
考察一哈
 
还没想通。
 
接受答案了.
 
后退
顶部