首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检测其他控件何时更改其界限?

如何检测其他控件何时更改其界限?
EN

Stack Overflow用户
提问于 2013-12-15 17:42:52
回答 2查看 1.3K关注 0票数 5

我有一个定制的TLabel,原则上可以附加到表单中的任何其他可视组件。该组件具有一个属性position,它指示它将定位到附加控件的位置(左、上等)。当附加了相关控件,并且组件根据position属性定位自己时,这是很好的。

问题是,我无法让组件检测到相关控件何时改变了它的界限,这样它就可以正确地重新定位自己。我想这与WMMoveWMResize有关。如何使相关控件通知TLabel任何边界属性都已更改?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-15 21:53:12

每当控件的位置和/或维度发生更改时,都会触发控件的OnResize事件。因此,一个简单的解决方案是在将标签附加到控件时为该事件分配一个处理程序,例如:

代码语言:javascript
复制
private
  FControl: TControl;

// OnResize is protected in TControl so use an accessor class to reach it...
type
  TControlAccess = class(TControl)
  end;

procedure TMyLabel.Destroy;
begin
  SetControl(nil);
  inherited;
end;

procedure TMyLabel.SetControl(AControl: TControl);
begin
  if FControl <> AControl then
  begin
    if FControl <> nil then
    begin
      TControlAccess(FControl).OnResize := nil;
      FControl.RemoveFreeNotification(Self);
    end;
    FControl := AControl;
    if FControl <> nil then
    begin
      FControl.FreeNotification(Self);
      TControlAccess(FControl).OnResize := ControlResized;
    end;
    ...
  end;
end;

procedure TMyLabel.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited;
  if (Operation = opRemove) and (AComponent = FControl) then
    FControl := nil;
end;

procedure TMyLabel.ControlResized(Sender: TObject);
begin
  // reposition as needed...
end;

当然,如果用户希望将自己的OnResize处理程序分配给控件,这将导致问题。

另一种方法是子类控件的WindowProc属性,而不是:

代码语言:javascript
复制
private
  FControl: TControl;
  FControlWndProc: TWndMethod;

procedure TMyLabel.Destroy;
begin
  SetControl(nil);
  inherited;
end;

procedure TMyLabel.SetControl(AControl: TControl);
begin
  if FControl <> AControl then
  begin
    if FControl <> nil then
    begin
      FControl.WindowProc := FControlWndProc;
      FControl.RemoveFreeNotification(Self);
    end;
    FControl := AControl;
    if FControl <> nil then
    begin
      FControlWndProc := FControl.WindowProc;
      FControl.WindowProc := ControlWndProc;
      FControl.FreeNotification(Self);
    end else
     FControlWndProc := nil;
    ...
  end;
end;

procedure TMyLabel.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited;
  if (Operation = opRemove) and (AComponent = FControl) then
  begin
    FControl := nil;
    FControlWndProc := nil;
  end;
end;

procedure TMyLabel.ControlWndProc(var Message: TMessage);
begin
  FControlWndProc(Message);
  // now check for position/size messages and reposition as needed...
end;
票数 8
EN

Stack Overflow用户

发布于 2013-12-24 22:11:42

基于@RemyLebeau的答案和ExtCtrls.TLabeledEdit的一些概念想法,我编写了自己的TStickyLabel控件。(工作正在进行中)。雷米的回答应该被接受-当然:)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20597649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档