我定义的图形组件属性有一个子组件。
发现更新子组件属性时,图形不能重画,一直不能解决。即使在更改子组件属性时加了
invalidate;也不行。
看delphi中,TPen,TBrush这几个子组件,都是定义了句柄的(HPen,HBrush),我们可以自定义句柄么?
可以定义在windows.pas单元内么?
这些组件还有个resource属性,
我需要修改下面这个类的定义么?
  TResource = record
    Next: PResource;
    RefCount: Integer;
    Handle: THandle;
    HashCode: Word;
    case Integer of
      0: (Data: TResData);
      1: (Font: TFontData);
      2: (Pen: TPenData);
      3: (Brush: TBrushData);
  end;

解决方案 »

  1.   

    更新子组件属性时,应该inherited父组件的重绘
      

  2.   

    你要把子組件 加到 你的圖形組件的components數組里面去,這部分可以在create時,傳入圖形組件本身,讓圖形組件記住它的子組件。這樣,在產生消息時,子組件可以處理到。前提是你的這些組件的來源于 TComponent
      

  3.   

    子组件属性更新是,用了paint,refresh,也不管用。
    可能是系统得不到重绘的消息。
    to Avan_Lau
    你可以举个例子么
      

  4.   

    ...Type
      TYourGraphi = Class(TComponent)
      private
        SubComp : TXXX;//should be from TComponent
      ...  public
        constructor Create(Aowner : TComponent); override;
      ... 
      end; 
      
    ...
      
    constructor Create(AOwner : TComponent);
    begin
      SubComp := TXXX.Create(AOwner);// or self(should be inherites from tcomponent)
    end;  對于無句柄組件,delphi通過isControlMsg-->controlatPos-->perform message,這個過程中,delphi會去遍歷components,若你的子組件不在此列,則無法收到消息,比如重繪消息(paint)
      

  5.   

    可以帮我看看下面的代码么,我想实现输入一个顶点的坐标,修改这个直线的一个端点的位置,这里 修改了P1后,组件不能自动重绘。unit MLine1;interfaceuses
      SysUtils, Classes, Controls,Graphics;type  TXY=class(TComponent)
      //TXY=class(TControl)
      private
        Fx:integer;
        Fy:integer;
        procedure set_x(value:integer);
        procedure set_y(value:integer);
      public
        constructor Create(Aowner : TComponent); override;
      published
        property X:integer read Fx write set_x ;
        property Y:integer read Fy write set_y ;
      end;
      TMLine = class(TGraphicControl)
      private
      Fpen:Tpen;
      Fp1:TXY;
      procedure setpen(value:Tpen);
      procedure setpoint(value:TXY);
      procedure stylechanged(Sender:Tobject);
        
      protected
      procedure paint;override;
        
      public
      constructor create(aowner:Tcomponent);override;
      destructor destroy;override;
        
      published
      property Pen:Tpen read fpen write setpen;
      property P1:TXY read fp1 write setpoint;
        
      end;procedure Register;implementationconstructor TXY.create(aowner:Tcomponent);
    begin
      inherited create(aowner);
    end;
    procedure TXY.set_x(value:integer);
    begin
      Fx:=value;
      //invalidate;end;
    procedure TXy.set_y(value:integer);
    begin
      Fy:=value;
      //invalidate;
    end;
    constructor TMline.create(aowner:Tcomponent);
    begin
      inherited create(aowner);
      height:=80;
      width:=80;
      fpen:=tpen.Create;
      fp1:=TXY.create(self);
      
      fpen.OnChange:=stylechanged;
    end;
    destructor TMline.destroy;
    begin
      fpen.Free;
      inherited;
    end;procedure TMline.setpen(value:Tpen);
    begin
      fpen.Assign(value);
      //invalidate;
    end;
    procedure TMline.setpoint(value:TXY);
    begin   //fp1:=value;
      if fp1<>value then
      begin
        if value<>nil then
        begin
          if  assigned(Fp1) and (fp1.Owner=self)then
          fp1.Free;
          fp1:=value;      fp1.FreeNotification(self);
        end
        else //nil value
        begin
          if assigned(fp1) and (fp1.Owner<>self) then
          begin
            fp1:=txy.Create(self);
            fp1.SetSubComponent(true);
            fp1.FreeNotification(self);
          end;
        end;
      end; 
      Invalidate;
     end;
    procedure TMLine.stylechanged(Sender:Tobject);
    begin
      invalidate;
    end;
    procedure TMline.paint;
    begin
       inherited;
       with canvas do
       begin
       pen:=fpen;
       MoveTo(fp1.x,fp1.Y);
       LineTo(70,70);
       end;
    end;
    procedure Register;
    begin
      RegisterComponents('User', [TMLine]);
    end;end.
      

  6.   

    1.  TXY=class(TComponent)
      //TXY=class(TControl)
    用TXY=class(TControl)也是可以的,Tcontrol inherites from TComponent2. 從你的代碼看 公布property P1:TXY read fp1 write setpoint ---fp1應該由外部指定,所以就沒必要在Tmline構建時,再create fp1。3. 關于在setpoint,其實關鍵代碼在你的TMline的paint方法,所以在setpoint里面,應該要能觸發它,不應該調用invalidate,這個只會產生消息 WM_ERASEBKGND and WM_NCPAINT ,所以不會觸發wm_paint,也就不會執行paint方法。
    所以你在setpoint直接調用paint
      

  7.   

    兄弟愚钝,有些不太理解的地方
    2。如果TMline创建时不创建FP1,在TMline对象属性里不会列出FP1公布的属性。
    3.invalidate产生的消息,就是让系统去调用paint方法吧。
    我按你的方法修改了一下,还是老样子,真是愁死我了。
      

  8.   

    关于第2点,要看你在调用时,是如何调用的。
    根据你的属性类型以及设定属性的方法,我推断:你在外部使用 时,应该会先创建一个TXY类型的对象,然后再进行赋值,这样才能正常使用。不知道你是如何调用的?
      

  9.   

    你说的外部是哪里啊?
    我在TXy类的外部,在TMyline类内定义了TXy的对象Fp1。
    你说的外部是怎么定义的,这个程序你可以改一下么?
      

  10.   

    其實你主要用的是Tmline類,我說的“外部”,是指使用Tmline類的程序。要確認你是如何設定TMline的P1屬性的。問題有可能出在你設定這個屬性上面。你可以跟蹤到setpoint這個方法里面,看能進去不?以及如何執行?這樣就可以知道問題在哪了