正如 David Heffernan 已经说过的那样,不可能更改已经运行的应用程序的主窗体。这是windows本身的局限。
你可以做的就是作弊,从不真正改变主窗体,而只是让它看起来像你所做的那样。
你是怎么做到的?
第 1 步:将代码添加到第二个表单以制作自己的任务栏按钮
procedure TWorkForm.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;
第 2 步:在切换到第二个表单之前动态创建第二个表单。在创建之前添加的代码将为您的第二个表单创建一个新的任务栏按钮。
第 3 步:现在隐藏实际的主窗体。隐藏它也会隐藏属于它的任务栏按钮。因此,您最终仍然会显示一个任务栏按钮,它属于您的第二个表单。
第 4 步:为了让您的第二个表单在关闭时终止您的应用程序,请从您的第二个表单 OnClose 或 OnFormCloseQuery 事件调用您真正的主表单的 Close 方法。
如果您希望能够切换回真正的主窗体调用主窗体的 Show 方法而不是 Close 方法。
这种方法让我们可以非常快速地交换表单,因此只有最热衷的用户才会注意到任务栏按钮的短动画。
注意:如果您的第二个 for 是一个复杂的,并且因此需要一些时间来创建,您可能希望隐藏它,然后在其创建过程完成后显示它并进行交换。否则,您最终可能会同时显示两个任务栏按钮,我相信您想避免这样做。
这是一个简短的例子:
- LoginForm 是一个真正的主窗体,在应用程序启动时创建
- WorkForm 是用户在登录后会花费大部分时间的表单,这个表单是在登录过程中创建的
登录表单代码:
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.
工作表代码:
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 begin 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 allow 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.