Sha*_*elt 10 forms delphi vcl taskbar delphi-xe6
我有这个问题.当我隐藏我的主窗体时,我的应用程序的任务栏图标也被隐藏.我也看到了一个关于这个问题的新问题,答案并没有真正帮助.他们建议尽量减少它,但我不想最小化应用程序.
应用程序运行时是否可以更改主窗体?
例如.我有两种形式.当我想隐藏一个表单并显示另一个表单时,任务栏图标应保留在任务栏上,主表单应切换到另一个表单.
我使用的是Delphi XE6,它是一个VCL Forms应用程序.
我还看到了一个关于在运行时更改主窗体的一个不同的老问题,但它很老,仍然基于Delphi 6.
应用程序运行时是否可以更改主窗体?
程序运行时无法更改VCL主窗体.程序启动时,此属性一劳永逸地确定.
一种可行的方法是安排辅助表单,即非主表单的表单,在任务栏上有一个按钮.通过使其无主,或使用WS_EX_APPWINDOW
扩展窗口样式来做到这一点.
更新
好吧,你可以改变Application.MainForm
,但它需要你破坏当前的主窗体,然后创建一个新窗体.
正如 David Heffernan 已经说过的那样,不可能更改已运行的应用程序的主窗体。这是windows本身的限制。
你能做的就是作弊,永远不会真正改变主窗体,而只是让它看起来像你所做的那样。
你如何实现这一目标?
第 1 步:向第二个窗体添加代码以制作自己的任务栏按钮
procedure TWorkForm.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
end;
Run Code Online (Sandbox Code Playgroud)
步骤 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.
Run Code Online (Sandbox Code Playgroud)
工作表格代码:
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.
Run Code Online (Sandbox Code Playgroud)
Application.MainForm
一旦分配,就无法更改。但是,您也不需要。这个问题最简单的解决方案是创建一个空白隐藏TForm
作为真实 Application.MainForm
并让它正常管理任务栏,然后您可以TForm
在需要时显示/隐藏任何辅助对象,其中您想要的“MainForm”是辅助表单而不是真实的MainForm
。