Why am I receiving multiple window messages of the same type?

I am trying to reply to windows and application messages, but I get them several times.

For example, I write the following code to display a message box when the system date is changed using WM_TIMECHANGE. WMTimeChange is executed more than once, and I see one-time (most often two or three) mailboxes one after another. Maybe I missed something?

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. 

Testing in Windows XP.

EDIT: just to clarify, my intention is to understand WHY , and not how to get around a few challenges. In any case, if the answer to this question is not possible, I will probably accept one answer later.

EDIT2: Delphi tag removed because it is not a Delphi problem.

+4
source share
2 answers

Your code is correct. Windows seems to send the WM_TIMECHANGE message several times.

Thus, you can simply add a small time-hysteresis comparison so that your message only works once in 1% of the day, i.e. more or less than 15 minutes:

 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; 
+3
source

This is what I used in my case to be resistant to this behavior. But, as stated in the comments, it will work only if the user needs time to respond to the application. So Arno Bounchez is the best approach to general use. Just remember to initialize FWMTimeChangeStamp in a way that differs from the current computer clock.

 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. 
+1
source

Source: https://habr.com/ru/post/1389514/


All Articles