0

这是我为 Tray ... 找到的方法:

http://www.programmersheaven.com/mb/delphikylix/257563/257563/how-can-i-make-a-system-tray-flash/

同样的技术是否适用于对话框(实际上它们是带有附加参数的表单)?或者我可以用更快的方法来做到这一点,比如获取句柄/地址/接口,并使用 FlashWindow(Ex) 方法重载或超速驱动函数?

我的意思是 - 我可以使用 FlashWindowEx() 方法制作例如 ShowMessage()、窗口/对话框闪烁吗?如果可以,可以使用上面给出的链接中的示例来完成吗?

请指出最佳方向或澄清我的疑问..

谢谢。

抱歉问题的表述不好。

4

2 回答 2

2

相同的技术适用于任何顶级窗口,包括对话框。如果您可以获得窗口的句柄,则可以将其传递给FlashWindowEx.

于 2009-12-29T21:48:14.350 回答
1

有多种方式可以从 Delphi 程序中显示模态表单或对话框(VCL 或系统原生),因此您需要以某种方式挂钩到消息处理并捕获显示模态表单或对话框时发送的消息。

为此,可以使用API 函数设置消息挂钩。SetWindowsHookEx()由于您仅在应用程序处于非活动状态时才需要它,您可以在应用程序事件的处理程序中设置它OnDeactivate,并在应用程序事件的处理程序中将其重置OnActivate

var
  gNextHook: HHOOK;

procedure TForm1.AppActivate(Sender: TObject);
begin
  if gNextHook <> 0 then
    UnhookWindowsHookEx(gNextHook);
  gNextHook := 0;
end;

procedure TForm1.AppDeactivate(Sender: TObject);
begin
  gNextHook := SetWindowsHookEx(WH_CALLWNDPROC, @WndProcHook, 0,
    GetCurrentThreadId);
end;

钩子函数将监视显示模式对话框或表单时发送的消息,并FlashWindowEx()使用正确的参数调用:

function WndProcHook(nCode: integer; AWParam: WPARAM; ALParam: LPARAM): LRESULT; stdcall;
var
  DataPtr: PCWPStruct;
  Fwi: TFlashWInfo;
begin
  DataPtr := PCWPStruct(ALParam);
  if (DataPtr^.message = WM_INITDIALOG)
    or ((DataPtr^.message = CM_ACTIVATE) and (DataPtr^.lParam = 0) and (DataPtr^.wParam = 0))
  then begin
    Fwi.cbSize := SizeOf(TFlashWInfo);
    // flash caption of new modal window
    Fwi.hwnd := DataPtr^.hwnd;
    Fwi.dwFlags := FLASHW_ALL or FLASHW_TIMERNOFG;
    Fwi.uCount := 0;
    Fwi.dwTimeout := 0;
    FlashWindowEx(Fwi);
    // uncomment this to flash task bar button as well
(*
    Fwi.hwnd := Application.MainForm.Handle;
    Fwi.dwFlags := FLASHW_TRAY or FLASHW_TIMERNOFG;
    FlashWindowEx(Fwi);
*)
  end;
  Result := CallNextHookEx(gNextHook, nCode, AWParam, ALParam);
end;

我选择了WM_INITDIALOG为打开或保存对话框之类的本机对话框发送的内容,以及CM_ACTIVATE在以模态方式显示 VCL 表单时发送的内容。可能有更多这样的消息需要被捕获。上面的代码适用于MessageDlg()函数、Application.MessageBox()函数和TOpenDialog至少。

由于这些对话框没有自己的任务栏按钮,我添加了(注释掉)代码来刷新主窗体的任务栏按钮。这不是最佳的,因为它们不同步。

在 Windows XP 上使用 Delphi 2009 进行测试,省略了所有错误处理,仅将其用作起点。

于 2009-12-30T11:35:41.093 回答