如何在Windows 7中隐藏任务栏上的应用程序?

16

我想要在Windows 7任务栏中隐藏一个应用程序。

我想要制作一个类似于屏幕边缘的工具栏,当用户单击它时可以执行某些操作,但我不希望它出现在任务栏中,因为这是一件我希望保持在后台的事情。

我尝试了以下帖子中的说明,但它并没有在我的应用程序上起作用:

如何隐藏任务栏入口但保留窗口表单

然后我在一个新的空VCL表单应用程序上尝试了它,但仍然没有起作用。我搜索其他解决方案,但它们都与链接的帖子非常相似。

在Windows 7中是否有什么变化使它变得不可能?或者你能否想到任何可能阻止它正常工作的问题?


你的Application.MainFormOnTaskBar属性的值是什么? - jachguate
2
请注意,Shell的AppBar API是为此设计的。参考链接:http://msdn.microsoft.com/en-gb/library/windows/desktop/cc144177(v=vs.85).aspx / https://dev59.com/UHVD5IYBdhLWcg3wI3-L - Alex K.
Application.MainFormOnTaskBar 默认为 true。当我将它设置为 false 时,在任务栏中会出现两个条目。一个是 exe 文件本身,另一个是主窗口。 - Marks
3个回答

14

您可以通过覆盖主窗体的CreateParam方法来移除强制使任务栏按钮(WS_EX_APPWINDOW)以及将窗体所有权设置为应用程序窗口。这相当于执行与要求Windows Shell在窗口上放置任务栏按钮相反的操作。参见“管理任务栏按钮”:

[...] 创建一个带有WS_EX_APPWINDOW扩展样式的非拥有窗口,以确保窗口按钮被放置在任务栏上。[...]

示例:

type
  TForm1 = class(TForm)
  protected
    procedure CreateParams(var Params: TCreateParams); override;
  end;

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.ExStyle := Params.ExStyle and not WS_EX_APPWINDOW;
  Params.WndParent := Application.Handle;
end;

如果您使用此方法,请不要更改“Application”的MainFormOnTaskbar属性的状态,使其保持默认值“True”。

您还可以删除第二行(..WndParent:= ..),而是在对象检查器中将窗体的PopupMode设置为pmExplicit以达到相同的效果。


顺便说一下,在相同主题的文档中,以下是来自TLama发布的解决方案的摘录:

  

为了防止窗口按钮被放置在任务栏上,[...]。 作为替代,您可以创建一个隐藏的窗口,并使该隐藏的窗口成为可见窗口的所有者。

当您将MainFormOnTaskbar设置为false时,按照VCL设计,主窗体由应用程序窗口拥有。如果您隐藏应用程序窗口,那么要求就得到满足。


9

尝试使用这篇文章中所描述的巧妙方法:

在项目文件中将MainFormOnTaskBar设置为False。然后尝试在主窗体的OnShowOnActivate事件处理程序中隐藏应用程序窗口。因此,您的项目可能如下所示:

Project1.dpr:

program Project1;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := False;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Unit1.pas:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormShow(Sender: TObject);
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
  ShowWindow(Application.Handle, SW_HIDE);
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
  ShowWindow(Application.Handle, SW_HIDE);
end;

end.

1
你可以使用Application.ShowMainForm := False;来隐藏主窗体,而不是在主窗体代码中隐藏主窗体。 - Shannon Matthews

2

你的应用程序主窗体通常是在dpr文件中创建的,因此打开dpr文件并查找创建主窗体的行。

// add this line first
// blank app title will prevent app from showing in the applications list in task manager
Application.Title := '';

// this line is already in the dpr and creates the main form, the class will differ
Application.CreateForm(TMainForm, Result);

// make the main form invisible to windows taskbar/task switcher
i := GetWindowLong(Application.Handle, GWL_EXSTYLE);
SetWindowLong(Application.Handle, GWL_EXSTYLE, i OR WS_EX_TOOLWINDOW AND NOT WS_EX_APPWINDOW);

我知道这个方法适用于XP和7操作系统,猜测在8上也可以使用。这个方法添加了工具窗口标志并移除了应用程序窗口标志,所以如果你不需要工具窗口标志,可以省略以下部分:

i OR WS_EX_TOOLWINDOW

在最后一个 Application.CreateForm 后面,你应该真的添加 SetWindowLong(Application.Handle, GWL_EXSTYLE, (GetWindowLong(Application.Handle, GWL_EXSTYLE) OR WS_EX_TOOLWINDOW) AND NOT WS_EX_APPWINDOW);。 - Torbins

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接