Почему я получаю несколько сообщений Windows одного и того же вида? - PullRequest
4 голосов
/ 05 января 2012

Я пытаюсь ответить на некоторые сообщения 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, поскольку он, похоже, не является проблемой Delphi.

Ответы [ 2 ]

3 голосов
/ 05 января 2012

Ваш код правильный.Похоже, что 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 голос
/ 27 марта 2012

Это то, что я использовал в моем случае, чтобы быть устойчивым к такому поведению. Но, как сказано в комментариях, будет работать, только если пользователь займет время, чтобы ответить на заявку. Итак, 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...