当前位置: 首页 > 知识库问答 >
问题:

当最小化/还原动画打开时,如何在移除任务栏按钮之前平滑最小化窗口?

隗翰海
2023-03-14

我正在最小化一个表单到系统托盘(显示一个托盘图标),同时保留它的任务栏按钮,当它没有最小化。这意味着在窗体最小化时移除任务栏按钮,否则将其还原。

实现这一点的最简单方法是隐藏/显示窗体,最小化的窗口无论如何都不会显示。

type
  TForm1 = class(TForm)
    TrayIcon1: TTrayIcon;
    procedure TrayIcon1DblClick(Sender: TObject);
  protected
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.WMSize(var Message: TWMSize);
begin
  inherited;
  case Message.SizeType of
    SIZE_MINIMIZED:
      if not TrayIcon1.Visible then begin
        TrayIcon1.Visible := True;
        Hide;
      end;
    SIZE_RESTORED, SIZE_MAXIMIZED:
      if TrayIcon1.Visible then begin
        Show;
        Application.BringToFront;
        TrayIcon1.Visible := False;
      end;
  end;
end;

procedure TForm1.TrayIcon1DblClick(Sender: TObject);
begin
  Show;
  WindowState := wsNormal;
end;

系统的“最小化和最大化时动画窗口”设置为on(可通过'systempropertiesperformance.exe'访问)时,上述应用程序引入了一个视觉故障。跳过最小化窗口动画。看起来动画实际上发生在窗口最小化之后。在代码中,此时窗口已经隐藏。<>

,如果我移动代码(更不用说窗口可以通过 等最小化),它不会导致任何进展。

没有它。这里类似的问题试图处理第一次显示窗口时显示的动画,尽管该动画似乎与DWM相关,并且Minimize/Maximize动画先于DWM。也没有定论。就像在这个问题中一样,250ms的延迟似乎可以正常工作。但我不确定这是一个普遍合理的延迟。我甚至不确定一个离散的延迟会是决定性的,也许一个口吃会导致它的程度(这并不是很重要,但无论如何。。。)。

共有1个答案

仉昱
2023-03-14

关于 (当Aero打开时,它不会绘制动画)的评论说服我在找到更好的替代方案之前稍微不进行文档化处理。使用 的方法必须确定最小化的位置,这就是它们使用未记录的系统托盘窗口类名的地方。

当删除表单的任务栏按钮时,下面的代码没有文档说明,特别是在使用 索引时。在任何情况下,移除任务栏按钮都不会像将窗口转换为工具窗口那样笨拙,并且动画进行得很流畅。

代码返回到一个计时器,该计时器在移除任务栏按钮失败时隐藏窗体。

type
  TForm1 = class(TForm)
    TrayIcon1: TTrayIcon;
    Timer1: TTimer;
    procedure TrayIcon1DblClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  protected
    procedure WMSize(var Message: TWMSize); message WM_SIZE;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function ShowTaskbarButton(Wnd: HWND; Show: Boolean = True;
    OwnerWnd: HWND = 0): Boolean;
var
  ExStyle, HWndParent: LONG_PTR;
  IsToolWindow: Boolean;
begin
  HwndParent := GetWindowLongPtr(Wnd, GWLP_HWNDPARENT);
  ExStyle := GetWindowLongPtr(Wnd, GWL_EXSTYLE);
  Result := Show = (HWndParent = 0) and (ExStyle and WS_EX_APPWINDOW <> 0);

  if not Result then begin
    IsToolWindow := ExStyle and WS_EX_TOOLWINDOW <> 0;
    if IsToolWindow then begin
      ShowWindow(Wnd, SW_HIDE);
      ShowWindowAsync(Wnd, SW_SHOW);
    end;
    SetLastError(0);
    if Show then
      SetWindowLongPtr(Wnd, GWL_EXSTYLE, ExStyle or WS_EX_APPWINDOW)
    else
      SetWindowLongPtr(Wnd, GWL_EXSTYLE, ExStyle and not WS_EX_APPWINDOW);
    if not IsToolWindow and (GetLastError = 0) then
      SetWindowLongPtr(Wnd, GWLP_HWNDPARENT, OwnerWnd);

    Result := GetLastError = 0;
  end;
end;

procedure TForm1.WMSize(var Message: TWMSize);
begin
  inherited;
  case Message.SizeType of
    SIZE_MINIMIZED:
      if not TrayIcon1.Visible then begin
        if not ShowTaskbarButton(Handle, False, Application.Handle) then
          Timer1.Enabled := True;   // fall back
        TrayIcon1.Visible := True
      end;
    SIZE_RESTORED, SIZE_MAXIMIZED:
      if TrayIcon1.Visible then begin
        ShowTaskbarButton(Handle);
        Application.BringToFront;
        TrayIcon1.Visible := False;
      end;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Timer1.Interval := 250;
  Timer1.Enabled := False;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Hide;
  Timer1.Enabled := False;
end;

procedure TForm1.TrayIcon1DblClick(Sender: TObject);
begin
  ShowTaskbarButton(Handle);
  if not Showing then   // used timer to hide
    Show;
  WindowState := wsNormal;
end;
 类似资料:
  • 我将GLFW3.2与LWJGL和Java一起使用。 我想删除窗口上的最大化和最小化按钮,而窗口保持可调整大小,我找不到任何方法在glfw留档中做到这一点。 我见过这个解决方案,但它只适用于窗口,使用C,我正在寻找的解决方案需要跨平台。 是否有可能使用glfw实现这一点?或者我应该使用一个未装饰的glfw窗口并绘制自己的标题栏?

  • 问题内容: 我需要从中删除最大化和最小化按钮。请提出建议。 问题答案:

  • 问题内容: 我有一个python程序,它将打开一个新窗口以显示一些“关于”信息。该窗口有其自己的关闭按钮,而我已使其不可调整大小。但是,最大化和最小化按钮仍然存在,我希望它们消失。 我正在使用Tkinter,包装所有信息以显示在Tk类中。 到目前为止的代码如下。我知道它不是很漂亮,我打算将信息扩展到一个类中,但是我想在继续之前解决这个问题。 任何人都知道如何管理Windows管理器显示哪些默认按钮

  • 我正在使用Python/Tkinter在XP上编写一个IM软件。现在,我已经完成了所有的主要功能,除了我不知道如何突出显示或改变颜色我的IM项目在任务栏在windows xp当窗口最小化到任务栏时,当收到一个新的消息。我已经搜索过了,但是得到了C#解。我在Python上需要帮助。谢啦!

  • 我在JavaFX应用程序中有一个未修饰的阶段。为了最小化它,我需要一个最小化按钮。我在中创建了我的布局,其中有一个,但是当我尝试使用最小化位于控制器内部的这个按钮时,使用,它找不到阶段。 如何在控制器类中找到对该阶段的引用?