我正在尝试回复一些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问题。
答案 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.