Delphi中的Windows 7风格通知弹出窗口

17

关于微软推荐的通知区域(Notification Area), 我正在寻找想法或者一个Delphi组件来实现通知区域Flyout

alt text

第一个“自然”的想法是使用标准的Delphi窗体,但我遇到了两个问题:

  1. 无法使用标准的“BorderStyle”属性获取窗体边框行为。尝试使用GlassFrame属性以及BorderStyle设置为bsNone来“模拟”边框,但在没有边框时没有GlassFrame(至少在Delphi 2007中是如此)。
  2. 我无法弄清楚如何使窗体在用户单击窗体之外的任何地方时关闭。昨天我尝试使用不同的消息,但没有一个像预期的那样工作。

感谢任何提示或组件使其成为可能 :)

最好的问候。

jachguate。

ps. 这里有一个相关问题:在Win7(Delphi)中将通知区域图标转换为程序图标

更新[0] 我仍在寻找建议。@skamradt的回答看起来非常好,但在实践中不起作用。

更新[1] 最终,通过在调用SetForegroundWindog来强制Flyout“激活”之后使用WM_ACTIVATE消息,自动关闭行为正在工作。

begin
  FlyoutForm.Show;
  SetForegroundWindow(FlyoutForm.Handle);
end;

现在,我正在寻求建议,以达到边框行为和视觉风格,因为最接近的行为是通过样式WS_POPUP或WS_DLGFRAME实现的,而最接近的视觉目标是通过设置样式为WS_POPUP或WS_THICKFRAME来实现的。


感谢RRUZ提供的链接转换 :) - jachguate
1个回答

9
我相信您需要的是以下内容:

我相信您需要的是以下内容:

TForm1 = class(TForm)
  :
protected
  procedure CreateParams(var Params: TCreateParams); override;
  procedure WMActivate(Var msg:tMessage); message WM_ACTIVATE;
end;

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  Params.Style := WS_POPUP or WS_THICKFRAME;
end;

procedure TForm4.WMActivate(var msg: tMessage);
begin
  if Msg.WParam = WA_INACTIVE then
    Hide; // or close
end;

这将为您提供一个具有玻璃框架的大型弹出窗口。由于标准窗口标题栏缺失,您无法在没有额外编程的情况下移动窗口。当另一个窗口获得焦点时,将触发FormDeactivate事件...但仅在您切换到同一应用程序中的另一个窗体时才会触发。为了无论切换到哪个应用程序都能处理它,请使用消息捕获方法。


谢谢!看起来非常好。我手头没有Win7,在Vista上它的工作效果只有50%,因为WM_ACTIVATE并不总是被触发,或者可能是因为我现在太累了。过几个小时,休息一下,拿到Win7后我会再试一次。再次感谢。 - jachguate
我终于得到了Win7机器并进行了测试,但与Vista一样,当其他弹出窗口关闭时,表单仍然可见。例如,如果您切换到另一个应用程序并选择其任务栏按钮,则它只关闭50%的时间(大约)。我尝试了几件事情来理解,但表单并不总是收到WM_ACTIVATE消息。也许是Windows的一个错误,但肯定有一个解决方法,因为系统弹出窗口(如电池)可以正常工作。如果您单击另一个托盘图标,则Delphi frm不会关闭。 我错过了什么吗?就我所看到的,在我的测试程序中实现了您的想法。 - jachguate
你也可以钩入Application.OnDeactivate事件。只需将Application.OnDeactivate设置为一个通知事件,如果弹出窗口可见,则还隐藏它。不幸的是,我没有Vista进行测试。 - skamradt
@skamradt:感谢您的建议,但不幸的是,行为与WM_ACTIVATE消息相同...也许是Delphi的一个bug。这让我疯狂。 - jachguate
1
@mghie:谢谢,我会继续尝试。我找到了不总是收到非活动事件的原因,原来是在Show()调用时窗体并不总是“激活”的。现在通过在显示后调用SetForegroundWindow来修复它,并且自动关闭似乎只需要WM_ACTIVATE消息即可正常工作。现在,我正在尝试获得正确的边框行为。@skamradt建议使用WS_POPUP或WS_THICKFRAME可以让用户调整窗口大小。我尝试了很多组合,但没有一个像预期的那样工作(粗边框,无标题,无移动,无调整大小)。 - jachguate
显示剩余3条评论

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