用SendNotifyMessage代替PostMessage避免消息丢失
大家都知道PostMessage会丢消息,但是消息队列的大小是多少呢,下面做了一个测试。
代码:
1 unit Unit1; 2 3 interface 4 5 uses 6 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 7 Dialogs, StdCtrls; 8 9 const 10 UM_ADD = WM_USER + 100; 11 12 type 13 TForm1 = class(TForm) 14 Label1: TLabel; 15 procedure FormCreate(Sender: TObject); 16 private 17 FVal: Integer; 18 procedure OnMsgAdd(var Msg: TMsg); message UM_ADD; 19 public 20 { Public declarations } 21 end; 22 23 var 24 Form1: TForm1; 25 26 implementation 27 28 {$R *.dfm} 29 30 procedure TForm1.FormCreate(Sender: TObject); 31 var 32 i: Integer; 33 begin 34 for i:=0 to 1000000 do 35 PostMessage(Handle, UM_ADD, 0, 0); 36 end; 37 38 procedure TForm1.OnMsgAdd(var Msg: TMsg); 39 begin 40 Inc(FVal); 41 Label1.Caption := IntToStr(FVal); 42 end; 43 44 end.
XP下运行结果:
可见,消息队列的默认长度是10000(在WIN7下运行结果是9998),队列满后消息将被丢弃。
如果把代码中的PostMessage改成SendNotifyMessage,运行后过了一段时间,窗口弹出:
所以,功能类似的SendNotifyMessage不会丢掉消息,必要时可以用它代替PostMessage。
上面的结论是错误的,SendNotifyMessage并没有那么神奇,上面的例子没有丢失消息的原因是因为
SendNotifyMessage发消息给同线程创建的窗口时,采用的是直接调用窗口函数的方式,换句话说
就是在执行SendMessage。