为什么我会收到多个同类窗口消息?

时间:2012-01-05 17:14:45

标签: windows winapi

我正在尝试回复一些Windows 和应用程序消息,但我多次得到它们。

例如,我编写以下代码,以便在使用WM_TIMECHANGE更改系统日期时显示消息框。 WMTimeChange被执行多次,我看到多个(大多数时候是两三个)消息框一个接一个地出现。也许,我错过了什么?

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
  protected
    procedure WMTimeChange(var Msg: TMessage) ; message WM_TIMECHANGE;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.WMTimeChange(var Msg: TMessage);
begin
    showmessage('Date/Time has changed!');
end;

end.

在Windows XP中进行测试。

编辑:只是为了澄清,我的意图是理解发生的为什么,而不是如何绕过多个电话。无论如何,如果无法回答这个问题,我可能会接受后来的一个答案。

EDIT2:删除了Delphi Tag,因为它似乎不是Delphi问题。

2 个答案:

答案 0 :(得分:3)

您的代码是正确的。听起来好像Windows多次发送WM_TIMECHANGE消息。

所以你可以添加一个小的时间滞后比较,让你的信息每天只有1%触发一次,即或多或少15分钟:

type
  TForm1 = class(TForm)
  protected
    FWMTimeChangeTimeStamp: TDateTime;
    procedure WMTimeChange(var Msg: TMessage) ; message WM_TIMECHANGE;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.WMTimeChange(var Msg: TMessage);
begin
  if Now-FWMTimeChangeTimeStamp>0.01 then 
  begin
    showmessage('Date/Time has changed!');
    FWMTimeChangeTimeStamp := Now; 
  end;
end;

答案 1 :(得分:1)

这是我在我的案例中使用的那种能够适应这种行为的东西。但正如评论中所述,只有在用户花时间回答应用程序时才会起作用。因此,Arnaud Bounchez是一种更好的通用方法。只是不要忘记将FWMTimeChangeStamp初始化为与当前计算机时钟不同的东西。

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  protected
    procedure WMTimeChange(var Msg: TMessage) ; message WM_TIMECHANGE;
  private
    isTimeChangeEventShowing: Boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  isTimeChangeEventShowing := false
end;

procedure TForm1.WMTimeChange(var Msg: TMessage);
begin
  if not isTimeChangeEventShowing then
  begin
    isTimeChangeEventShowing := true;
    showmessage('Date/Time has changed!');
    isTimeChangeEventShowing := false;
  end;
end;

end.