在Delphi 中用程序实现自定义窗体的创建和显示顺序(1)

Delphi 中用程序实现自定义窗体的创建和显示顺序(1)

 

摘要:本文介绍了一种简单而实用的方法用来动态创建和显示窗体,在Project.dpr中编写代码实现窗体的动态选择创建,同时对 Delphi的窗体创建,应用程序的创建,运行和结束的机制作了深入的探讨。

关键字:Delphi 窗体 创建 显示 动态选择

 

一. 问题的提出

Delphi 中我们可以通过两种方法创建多个窗体并设置他们的创建顺序,第一种方法是在新添加了多个窗体后,按Delphi 工具栏上的Project->Options… , 在出现的Forms 一页设置窗体的创建顺序。如下图:

第二中方法是在Delphi的工程文件中修改,在这里假设是Project1.dpr,其代码将显示如下:

 

program Project1;

 

uses

  Forms,

  Unit1 in 'Unit1.pas' {Form1},

  Unit2 in 'Unit2.pas' {Form2},

  Unit3 in 'Unit3.pas' {Form3};

 

{$R *.res}

 

begin

  Application.Initialize;

  Application.CreateForm(TForm1, Form1);

Application.CreateForm(TForm2, Form2);

Application.CreateForm(TForm3, Form3);

  Application.Run;

end.

         (代码1

可以通过调整上面代码中语句的顺序来调整创建3个窗体的顺序,效果跟第一种方法一样。

但是上面这两种方法都存在一个缺陷,就是Delphi编译器默认会把排在第一位创建的窗体作为主窗体,每次程序启动都会首先显示主窗体,并且窗体的加载顺序是不变的。

如何做成可以根据需要动态改变程序加载顺序呢?

 

二.  Delphi窗体创建大揭密

1.  窗体权限的转移实验

新建3Form , Project->Options… 中的Forms 一页把Form2Form3 放置在 Available forms中,保留Form1Auto-create forms中,让Form1在程序一开始运行就创建。

Form1(主窗体)中的OnCreate()事件函数中加入以下代码:

procedure TForm1.FormCreate(Sender: TObject);

begin

  Label1.Caption:='Form1 Create Completed!';

  Form1.Show;

  Application.CreateForm(TForm2, Form2);

end;

    (代码2

Form2OnCreate()事件函数中加入以下代码:

procedure TForm2.FormCreate(Sender: TObject);

begin

  Label1.Caption:='Form2 Create Completed!';

  Form2.Show;

  Application.CreateForm(TForm3,Form3);

end;

          (代码3

Form3OnCreate()事件函数中加入以下代码:

procedure TForm2.FormCreate(Sender: TObject);

begin

  Label1.Caption:='Form3 Create Completed!';

  Form3.Show;

end;

       (代码4

   这个程序在运行后将显示三个窗体,分别是Form1,Form2,Form3。你可能在想,如果要关闭程序,只要关闭Form1这个主窗体就可以了。然而你错了,应该是关闭Form3才能将整个程序关闭。为什么呢?关键在CreateForm()这个窗体创建函数,查一下Delphi的随机帮助文件就清楚了。帮助文件有关CreateForm()函数的说明如下:

 

Call CreateForm to dynamically create a form at runtime. Developers do not need to add code for creating most forms, because typically one or more calls to CreateForm are added automatically to the project's main source when using the form designer.

 

CreateForm creates a new form of the type specified by the FormClass parameter and assigns it to the variable given by the Reference parameter. The owner of the new form is the Application object.

 

Note:      By default, the form created by the first call to CreateForm in a project becomes the application’s main form.

 

特别注意最后一句,默认地,在一个Project中第一个由CreateForm调用创建的窗体就成为应用程序的主窗体。这样就不难解释为什么需要关闭Form3才能关闭应用程序了。因为程序中第一个使用CreateForm的是在Project1.dpr中的一段代码:

begin

  Application.Initialize;

  Application.CreateForm(TForm1, Form1);

  Application.Run;

end.

这段代码是在Project.dpr中自动生成的,然后我们在Form1中的OnCreate()事件函数第二次使用CreateForm,这时Form1的创建还没结束( 因为OnCreate事件还没完成 ),程序的主窗体就已经改变了,变成了Form2 , 然后我们又在Form2中的OnCreate()事件函数第三次使用CreateForm,这时程序的主窗体变成了Form3 ,也就是说程序的生杀大权已经掌握在Form3手中。绝对不要再在Form3OnCreate()事件函数中加入Application.CreateForm(TForm1,Form1),否则,程序将进入一个资源创建的死循环,一点一点地耗尽你的机器的内存。

从这里也可以看出Delphi并不是完全的面向对象,它不像Java那样可以随时随地创建一个窗体。

 

2.窗体权限的保留

   如果我们想在Form1中保留程序的权限,则需要新建一个Button,然后把Form1中的OnCreate()事件函数的代码放在Button OnClick()事件中。这时则只有关闭Form1,才能关闭整个程序。

 

3.动态选择创建窗体

回到我们一开始提出的问题,如何动态的有选择地创建窗体呢?我们用一个随机数模拟实际可能出现的动态情况,实际情况可能是程序在初始化时动态判断一个文件或数据库的一个值,由这个值决定是先显示Form2还是先显示Form3,还是只显示Form1 。代码如下:

 

procedure TForm1.FormCreate(Sender: TObject);

var

  randomnum:Integer;

begin

  Label1.Caption:='Form1 Create Complete!';

  Randomize;//设置随机器

  randomnum:=Random(10);//010之间取随机值

  if (randomnum>0)and (randomnum<=) then //如果随机值在0到4之间

  Begin

    Form1.Show;

    Application.CreateForm(TForm2, Form2);

  End

  else if (randomnum>)and (randomnum<=) then //如果随机数在4到8之间

  Begin

    Form1.Show;

    Application.CreateForm(TForm3, Form3);

  End

  Else     //如果随机数在8到10之间

  Form1.Show;

end;

    (代码 5
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi中,可以使用TColorDialog组件实现颜色选择对话。如果想要自定义颜色选择对话,可以继承TColorDialog并重写其中的一些方法。 下面是一个简单的示例代码,演示如何实现自定义颜色选择对话: ```delphi unit CustomColorDialog; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls; type TCustomColorDialog = class(TColorDialog) private FCustomColors: array[0..15] of TColor; protected procedure DoShow; override; procedure PaintRect(Canvas: TCanvas; Rect: TRect; Color: TColor); virtual; public constructor Create(AOwner: TComponent); override; published property CustomColors: array[0..15] of TColor read FCustomColors write FCustomColors; end; procedure Register; implementation {$R *.dfm} constructor TCustomColorDialog.Create(AOwner: TComponent); begin inherited; FCustomColors[0] := clBlack; FCustomColors[1] := clMaroon; FCustomColors[2] := clGreen; FCustomColors[3] := clOlive; FCustomColors[4] := clNavy; FCustomColors[5] := clPurple; FCustomColors[6] := clTeal; FCustomColors[7] := clGray; FCustomColors[8] := clSilver; FCustomColors[9] := clRed; FCustomColors[10] := clLime; FCustomColors[11] := clYellow; FCustomColors[12] := clBlue; FCustomColors[13] := clFuchsia; FCustomColors[14] := clAqua; FCustomColors[15] := clWhite; end; procedure TCustomColorDialog.DoShow; var I: Integer; BtnRect, ColorRect: TRect; BtnWidth, BtnHeight, ColorWidth, ColorHeight: Integer; BtnTop, ColorTop, ColorLeft: Integer; BtnCaption: string; BtnFont: TFont; BtnColor: TColor; Canvas: TCanvas; begin inherited; Canvas := TCanvas.Create; try Canvas.Handle := GetDC(Handle); BtnWidth := 50; BtnHeight := 20; ColorWidth := 15; ColorHeight := 15; BtnTop := ClientHeight - BtnHeight - 10; ColorTop := 10; ColorLeft := ClientWidth - 20 - (4 * ColorWidth); BtnFont := TFont.Create; try BtnFont.Assign(Font); BtnFont.Style := [fsBold]; for I := 0 to 3 do begin BtnRect := Rect(20 + (I * BtnWidth), BtnTop, 20 + ((I + 1) * BtnWidth), BtnTop + BtnHeight); BtnColor := CustomColors[I]; PaintRect(Canvas, BtnRect, BtnColor); BtnCaption := 'Color ' + IntToStr(I + 1); Canvas.Font := BtnFont; Canvas.Brush.Style := bsClear; DrawText(Canvas.Handle, PChar(BtnCaption), -1, BtnRect, DT_SINGLELINE or DT_CENTER or DT_VCENTER); for J := 0 to 3 do begin ColorRect := Rect(ColorLeft + (J * ColorWidth), ColorTop + (I * ColorHeight), ColorLeft + ((J + 1) * ColorWidth), ColorTop + ((I + 1) * ColorHeight)); PaintRect(Canvas, ColorRect, CustomColors[(I * 4) + J]); end; end; finally BtnFont.Free; end; finally ReleaseDC(Handle, Canvas.Handle); Canvas.Free; end; end; procedure TCustomColorDialog.PaintRect(Canvas: TCanvas; Rect: TRect; Color: TColor); begin Canvas.Brush.Color := Color; Canvas.Pen.Color := Color; Canvas.Rectangle(Rect); end; procedure Register; begin RegisterComponents('Samples', [TCustomColorDialog]); end; end. ``` 以上代码中,我们创建了一个名为TCustomColorDialog的自定义颜色选择对话。在DoShow方法中,我们使用TCanvas绘制了自定义颜色区域和按钮区域。在PaintRect方法中,我们绘制了矩形,并填充了指定的颜色。 要使用自定义颜色选择对话,只需将TCustomColorDialog组件放置在窗体中,并将其Execute方法调用即可:CustomColorDialog1.Execute。 希望这个示例对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值