TUpDown 并没有拦截 Associated 对象的事件。
但是,当关联控件(比如 TEdit)的内容改变之后,TUpdown 控件的 Position 的确会跟着改变,这是怎么回事呢?
原因是:UDM_SETBUDDY 和 UDM_GETPOS 消息。
procedure TCustomUpDown.SetAssociate(Value: TWinControl);
begin
if FAssociate <> nil then { undo the current associate control }
begin
if HandleAllocated then
SendMessage(Handle, UDM_SETBUDDY, 0, 0); // 发送 UDM_SETBUDDY 消息
FAssociate := nil;
end;
end;
function TCustomUpDown.GetPosition: SmallInt;
begin
if HandleAllocated then
begin
Result := LoWord(SendMessage(Handle, UDM_GETPOS, 0, 0));
FPosition := Result;
end
else Result := FPosition;
end;
UDM_SETBUDDY 消息把 Edit 设置为 TUpdown 的“伙伴”,这样,当 Edit 内容改变之后,
因为对 Position 属性的读取会触发 GetPosition 方法,导致发送 UDM_GETPOS 消息,就
得到了 Edit 的当前内容,把它赋给 FPosition 。
下面是 UDM_GETPOS 的说明:
The UDM_GETPOS message retrieves the current position of an up-down control.
UDM_GETPOS
wParam = 0;
lParam = 0;
Return Values
The return value is the current position in the low-order word. If an error occurred, the high-order word is nonzero.
Remarks
When processing this message, the up-down control updates its current position based on the caption of the buddy window.
The up-down control returns an error if there is no buddy window or if the caption specifies an invalid or out-of-range value.
从说明里介绍的可以知道,其实 FAssociated 可以是任何 TWindowControl 的后代。
从上面的说明可以看到,这一过程不是通过 VCL 的对象继承与消息拦截实现的,它是由 Windows
标准控件(TUpdown 是标准控件)本身的特性决定的。
Clear ?
From: BaKuBaKu