我广播了一条消息为什么TConnBC_A,TConnBC_B 收不到?
unit baseC;interfaceuses
  Windows, Messages, SysUtils, Classes, Controls, ExtCtrls;
const
  CM_REPAINT_BY_SELF = WM_USER + 100;type
  TChangeEvent = procedure(Sender: TObject; Value: integer) of object;  //-----------------------------------------------------------------  TConnBC_A
  TbaseC = class(TWinControl)
  private
    FEvent: TChangeEvent;
    Fsin: integer;
    FEnable: Boolean;
    FNewTimer: TTimer;
    FTimerEvent: TNotifyEvent;
    { Private declarations }
  protected
    procedure TimerChange(Sender: TObject);
    procedure SetSin(Value: integer);
    procedure SetEnable(Value: Boolean);
    property Sin: integer read Fsin write SetSin;
    property ChangeEvent: TChangeEvent read FEvent write FEvent;
    { Protected declarations }
  public
    procedure BroAll();
    { Public declarations }
  published
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property Enable: Boolean read FEnable write SetEnable;
    property OnTimer: TNotifyEvent read FTimerEvent write FTimerEvent;     { Published declarations }
  end;
 //-----------------------------------------------------------------  TConnBC_A
  TConnBC_A = class(TbaseC)
  private
    FConBase: TbaseC;
    { Private declarations }
  protected
    procedure SetConBase(Value: TbaseC);
    procedure WMREPAINT_BY_SELF(var Message: TMessage); message CM_REPAINT_BY_SELF;
  { Protected declarations }
  public
    { Public declarations }
  published
    property ChangeEvent;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    { Published declarations }
  end;//-------------------------------------------------------------------  TConnBC_B
  TConnBC_B = class(TbaseC)
  private
    FConBase: TbaseC;
   { Private declarations }
  protected
    procedure WMREPAINT_BY_SELF(var Message: TMessage); message CM_REPAINT_BY_SELF;
    procedure SetConBase(Value: TbaseC);
    { Protected declarations }
  public
    { Public declarations }
  published
    property ChangeEvent;
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;    { Published declarations }
  end;procedure Register;implementationconstructor TbaseC.Create(AOwner: TComponent);
begin
  inherited Create(AOWner);
  FNewTimer := TTimer.Create(Self);
  FNewTimer.Enabled := False;
  FEnable := False;
  FNewTimer.OnTimer := TimerChange;
end;destructor TbaseC.Destroy;
begin
  inherited Destroy;
  FNewTimer.Destroy;
end;procedure TbaseC.SetEnable(Value: Boolean);
begin
  FEnable := Value;
  if not (csDesigning in ComponentState) then
    FNewTimer.Enabled := Value;
end;procedure TbaseC.BroAll();
var
  Msg: TMessage;
begin
  Msg.Msg := CM_REPAINT_BY_SELF;
  Msg.WParam := 0;
  Msg.LParam := 0;
  Msg.Result := 0;
  Self.Broadcast(Msg);
end;procedure TbaseC.SetSin(Value: integer);
begin
  FSin := Value;
// 让别的元件感知
end;procedure TbaseC.TimerChange(Sender: TObject);
begin
  FEnable := False;
  if Assigned(FTimerEvent) then
    FTimerEvent(Sender);
end;
//--------------------------------------------constructor TConnBC_A.Create(AOwner: TComponent);
begin
  inherited Create(AOWner);
end;destructor TConnBC_A.Destroy;
begin
  inherited Destroy;
end;procedure TConnBC_A.WMREPAINT_BY_SELF(var Message: TMessage);
begin
  Invalidate;
end;procedure TConnBC_A.SetConBase(Value: TbaseC);
begin
  FConBase := Value;
  //画图
end;
//-------------------------------------------constructor TConnBC_B.Create(AOwner: TComponent);
begin
  inherited Create(AOWner);
end;destructor TConnBC_B.Destroy;
begin
  inherited Destroy;
end;procedure TConnBC_B.SetConBase(Value: TbaseC);
begin
  FConBase := Value;
  //画图
end;procedure TConnBC_B.WMREPAINT_BY_SELF(var Message: TMessage);
begin
  Invalidate;
end;procedure Register;
begin
  RegisterComponents('Standard', [TbaseC]);
  RegisterComponents('Standard', [TConnBC_A]);
  RegisterComponents('Standard', [TConnBC_B]);
end;end.
  

解决方案 »

  1.   

    ??你的TConnBC_A,TConnBC_B与TbaseC 没有任何关系,如何能收到消息?
    AWinControl.Broadcast 是将消息广播给所有子控件(即子控件.Parent = AWinControl)————————————————————————————————————
    宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
    ————————————————————————————————————
      

  2.   

    你没有看吗
    TConnBC_A,TConnBC_B 是从TBaseC 继承过来的,怎么说没有关系呢? 是他的 子控件?
      

  3.   

    >>TConnBC_A,TConnBC_B 是从TBaseC 继承过来的,怎么说没有关系呢? 是他的 子控件?
    其實故國說對了!
    你說的是設計時的, 而
    Broadcast 是運行時發生作用的, 而且, 與父類, 子類并沒有關系!它是與控件包含的子控件發生關系的!!
    如panel, 裹面放了几個 edit , 那麼 panel.Broadcast 就會通知panel包含的几個edit, 而edit與panel之間并沒有類的從屬關系
      

  4.   

    那 datasource 和 Adoquery 他们是怎么感知的,难到不是通过 消息的广播吗?
    你改变 Dbgrid 里的 值  回发现 和 Adoquery 关联的的 datasource 的dbgrid 的指针都边了
    Why?
      

  5.   

    VCL中的数据敏感功能主要依赖两个辅助类TDataLink和TFieldDataLink实现,广义上也可以理解为消息派遣和消息广播,但和通常意义上的Windows消息和VCL自定义消息有比较大的不同。从TField、TDataSet和TDataSource等外部来看,TDataLink和TFieldDataLink都是不可见的,它们都只是在这些组件内部使用。————————————————————————————————————
    宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
    ————————————————————————————————————
      

  6.   

    lxpbuaa : 对你对我的回答我深深的感谢!
    相信你对 vcl 数据敏感功能 已经很了解了,我对这个问题一直感到很迷惑
    我可以自己做一组控件,不用 Tdatalink ,TFieldDatalink 等 vcl 的辅助类,
    来实现 我自己元件的数据敏感功能,我想是可以的!但是我不知道怎么实现听你说是消息派遣,譬如 TA 和 TB 相连,难到 在设置 TB 的 datasource 连接 TA
    的时候 在 TA 某个地方 要登记 TB 的地址 ,然后 当 TA 变化的时候,就 按照这个地址
    发送消息 给 TB 吗? 我看了 vcl 这个代码 确实有一个 Tdatalist 这个类 来登记,但是
    我找不 发送消息(消息派遣或者 是消息广播那个代码)。再次深深的感谢你的回答! 萍水相逢,相见恨晚! 
    qq.61280979 ,[email protected]
      

  7.   

    谢谢。不过我对VCL的数据敏感机制也只是了解一个皮毛。
    1、TDataSource和TDataSet之间的连接,主要是内部直接操作。因为TDataSource包含属性DataSet,TDataSet也包含内部数据FDataSources: TList,记载了所有连接到它的TDataSource。这样一种相互连接的方法,在VCL中是很常见的。
    2、在数据敏感控件和TDataSource的连接时,则常常需要使用TDataLink及其子类。比如TDBGrid使用TGridDataLink,TDBEdit使用TFieldDataLink等。
    TDataLink内部含属性TDataSet和TDataSource,用以表示当前的数据连接体。因此数据敏感控件只需要在适当的地方调用TDataLink的方法,就可以让TDataLink自动操作对应的TDataSet和TDataSource。
    3、TDataLink、TDataSet、TDataSource内部的确在很多地方使用了类似消息派遣的办法,因为很多事件是类似的。例如TDataLink.DataEvent(Event: TDataEvent; Info: Longint);
    其中Event相当于消息类型,Info相当于消息参数。————————————————————————————————————
    宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
    ————————————————————————————————————