Delphi在应用程序运行时更改主窗体 [英] Delphi Change main form while application is running

查看:267
本文介绍了Delphi在应用程序运行时更改主窗体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个问题。当我隐藏我的主窗体时,我的应用程序的任务栏图标也被隐藏。我也看到一个关于这个问题的新问题,答案并没有真正的帮助。他们建议将其最小化,但是我不想将应用程序最小化。



在应用程序已经运行时是否可以更改主窗体?

例如

。我有两种形式当我想隐藏一个表单并显示另一个表单时,任务栏图标应该保留在任务栏上,主窗体应该切换到另一个窗体。



I我正在使用Delphi XE6,它是一个VCL Forms应用程序。



我也看到一个不同的旧问题,关于在运行时更改主窗体,但它是非常老,仍然基于在Delphi 6上。

解决方案

正如David Heffernan已经难过,改变已经运行的应用程序的主窗体不太可行。这是Windows本身的限制。



你可以做的是作弊,从来没有实际改变主窗体,但只能使它看起来像你一样。

您如何实现?



步骤1:将代码添加到第二个窗体以创建自己的任务栏按钮

 程序TWorkForm.CreateParams(var Params:TCreateParams); 
开始
继承;
Params.ExStyle:= Params.ExStyle或WS_EX_APPWINDOW;
结束

步骤2:在切换到之前动态创建第二个表单。创建之前添加的代码将为您的第二个表单创建一个新的任务栏按钮。



步骤3:现在隐藏实际的主窗体。隐藏它也会隐藏属于它的任务栏按钮。所以你最终仍然有一个任务栏按钮显示,它是属于你的第二个表单的一个。



步骤4:为了降低您的第二个表单在其关闭时终止您的应用程序从第二个Forms OnClose或OnFormCloseQuery事件中关闭您的真实主窗体的方法。

如果您想要切换回您的真实主窗体调用Show方法的主窗体,而不是关闭方法。



这种方法使我们很快地转换表单,所以只有最敏锐的用户会注意到任务栏按钮的短动画。

注意:如果你的第二个是一个复杂的,因为它需要一些时间来创建你可能想创建它隐藏,然后一旦它的创建过程完成显示它并进行交换。其他的你可能会在同一时间显示两个Taksbar按钮,我相信你想要避免。



这是一个简短的例子:

- LoginForm是一个真正的主窗体,在应用程序启动时创建
- WorkForm是登录后用户将花费大部分时间的窗体,并且在登录过程中创建了此窗体。



登录表单代码:

  unit ULoginForm; 

接口

使用
Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,
Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls;

type
TLoginForm = class(TForm)
BLogIn:TButton;
procedure BLogInClick(Sender:TObject);
private
{私人声明}
public
{公开声明}
end;

var
LoginForm:TLoginForm;

//全局变量告诉我们我们是否只注销或关闭我们的程序
LoggingOut:Boolean;

实现

使用Unit2;

{$ R * .dfm}

程序TLoginForm.BLogInClick(Sender:TObject);
begin
//创建第二个表单
Application.CreateForm(TWorkForm,WorkForm);
//隐藏主窗体
自我隐藏;
//不要忘记清除登录字段
end;

结束。

Woork表单代码:

  unit UWorkForm; 

接口

使用
Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,
Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.StdCtrls;

type
TWorkForm = class(TForm)
BLogOut:TButton;
//用于覆盖表单创建参数,以便我们可以添加自己的任务栏按钮
procedure CreateParams(var Params:TCreateParams);覆盖
procedure FormCloseQuery(Sender:TObject; var CanClose:Boolean);
procedure BLogOutClick(Sender:TObject);
private
{私人声明}
public
{公开声明}
end;

var
WorkForm:TWorkForm;

实现

使用Unit1;

{$ R * .dfm}

程序TWorkForm.BLogOutClick(发件人:TObject);
begin
//设置为true,所以我们知道我们正在简单地注销
LoggingOut:= True;
//调用close方法来关闭当前窗体
关闭;
结束

程序TWorkForm.CreateParams(var Params:TCreateParams);
开始
继承;
Params.ExStyle:= Params.ExStyle或WS_EX_APPWINDOW;
结束

程序TWorkForm.FormCloseQuery(发件人:TObject; var CanClose:Boolean);
begin
//检查我们是否正在简单地注销
如果不是LoggingOut然后
begin
//如果我们不在进程中关闭主窗体
LoginForm.Close;
//然后alow关闭当前窗体
CanClose:= True;
end
else
begin
//但是如果我们正在简单地注销显示主窗体
LoginForm.Show;
//将LoggingOut重置为false
LoggingOut:= False;
//然后alow关闭当前窗体
CanClose:= True;
结束
结束

结束。


I have this problem. When I hide my main form, then the taskbar icon of my application is also hidden. I saw a new question about this problem as well and the answers didn't really help. They suggested to minimize it, but I do not want to minimize the application.

Is it possible to change the main form while the application is already running?

for instance. I have two forms. when I want to hide the one form and show the other form, then the taskbar icon should stay at the taskbar and the main form should switch to the other form.

I am using Delphi XE6 and it is a VCL Forms application.

I have also seen a different old question about changing main form while runtime, but it is very old and still based on Delphi 6.

解决方案

As David Heffernan already sad it is not posible to change the Main Form of an already running application. This is the limitation of the windows itself.

What you can do is cheat and never actually change the Main Form but only make it look like you did.
How do you achieve that?

Step 1: Add code to the second Form to make its own Taskbar button

procedure TWorkForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;

Step 2: Dynamically create the second Form just before switching to it. Upon its creation previously added code will create a new Taskbar button for your second form.

Step 3: Now hide you actual Main Form. Hiding it will also hide the Taskbar button belonging to it. So you end up still having one Taskbar button shown and it is the one belonging to your second Form.

Step 4: In order to alow your second Form to terminate your application at its closure call Close method of your true Main Form from your second Forms OnClose or OnFormCloseQuery event.
If you wanna be able to switch back to your true Main Form call Show method of your Main Form instead of Close method.

This approach alows us of swaping forms pretty quickly so only most keen users will notice short animation of Taskbar button.
NOTE: If your second for is a complex one and becouse of that takes some time to create you might wanna create it hidden and then once its creation process is finished show it and do the swap. Othervise you might end up with two Taksbar buttons being shown at same time which I belive you wanna avoid.

Here is a short example:
- LoginForm is a true Main Form that is created at the application startup - WorkForm is the Form on which user will spend most of time after logging in and this one is created in login process

Login Form code:

unit ULoginForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TLoginForm = class(TForm)
    BLogIn: TButton;
    procedure BLogInClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  LoginForm: TLoginForm;

  //Global variable to tell us if we are only logging out or closing our program
  LoggingOut: Boolean;

implementation

uses Unit2;

{$R *.dfm}

procedure TLoginForm.BLogInClick(Sender: TObject);
begin
  //Create second Form
  Application.CreateForm(TWorkForm, WorkForm);
  //Hide Main Form
  Self.Hide;
  //Don't forget to clear login fields
end;

end.

Woork form code:

unit UWorkForm;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TWorkForm = class(TForm)
    BLogOut: TButton;
    //Used in overriding forms creating parameters so we can add its own Taskbar button
    procedure CreateParams(var Params: TCreateParams); override;
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure BLogOutClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  WorkForm: TWorkForm;

implementation

uses Unit1;

{$R *.dfm}

procedure TWorkForm.BLogOutClick(Sender: TObject);
begin
  //Set to true so we know we are in the process of simply logging out
  LoggingOut := True;
  //Call close method to beging closing the current Form
  Close;
end;

procedure TWorkForm.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;

procedure TWorkForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  //Check to see if we are in the process of simply logging out
  if not LoggingOut then
  begin
    //If we are not in the process of logging out close the Main Form
    LoginForm.Close;
    //and then alow closing of current form
    CanClose := True;
  end
  else
  begin
    //But if we are in the process of simply logging out show the Main Form
    LoginForm.Show;
    //Reset the LoggingOut to false
    LoggingOut := False;
    //and then alow closing of current form
    CanClose := True;
  end;
end;

end.

这篇关于Delphi在应用程序运行时更改主窗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆