我想以 TPageControl 为父类派生一个新控件,使 Tab 的标题文字可以改变颜色并具有闪烁功能。
但我找遍了 ComCtrls 单元,都看不到 TPageControl 和 TCustomTabControl 是怎样绘制控件的,这是怎么回事?如果能看得到的话我就可以决定重载哪些过程或属性。

解决方案 »

  1.   

    我想一定是你理解错了,事实上我当然在 ComCtrls 单元里找到了 TPageControl 及它所有的private、public、published和事件代码,但就是找不到具体绘制控件的代码,让我的改制工作无法进行。:(
      

  2.   

    TPageControl 本身就具有你所要求的功能阿
      

  3.   

    把TPageControl的OwnerDraw置为True;
    然后Override DrawTab这个方法
        procedure DrawTab(TabIndex: Integer; const Rect: TRect; Active: Boolean); virtual;
    事实上直接就可以
      

  4.   

    To: F1OnEverest(天问) 
    TPageControl本身可以给不同的Tab(标签)字体设置不同的颜色么?不行吧
    要Tab(标签)字体闪烁(黑色<->红色)更是不可能。To: xzgyb(老达摩)
    你说的办法是可以,但我就得在Form里用定时器来控制Tab(标签)字体的闪烁。我是想从TPageControl派生一个新控件,来完成给TPageControl增加Tab(标签)字体颜色可设置的功能。并给控件内置一个TTimer来实现Tab(标签)字体的闪烁,这样也比较符合结构化和代码复用的思想。
      

  5.   

    试试看看procedure TCustomTabControl.CNDrawItem(var Message:TWMDrawItem)
      

  6.   

    To: redcony()procedure TCustomTabControl.CNDrawItem(var Message: TWMDrawItem);
    var
      SaveIndex: Integer;
    begin
      with Message.DrawItemStruct^ do
      begin
        SaveIndex := SaveDC(hDC);
        FCanvas.Lock;
        try
          FCanvas.Handle := hDC;
          FCanvas.Font := Font;
          FCanvas.Brush := Brush;
          DrawTab(itemID, rcItem, itemState and ODS_SELECTED <> 0);
        finally
          FCanvas.Handle := 0;
          FCanvas.Unlock;
          RestoreDC(hDC, SaveIndex);
        end;
      end;
      Message.Result := 1;
    end;就一句 DrawTab(itemID, rcItem, itemState and ODS_SELECTED <> 0); 就完成了 TabControl 的界面绘制?来看看 DrawTab 做了点什么:procedure TCustomTabControl.DrawTab(TabIndex: Integer; const Rect: TRect;
      Active: Boolean);
    begin
      if Assigned(FOnDrawTab) then
        FOnDrawTab(Self, TabIndex, Rect, Active) // 这里是交给OwnerDraw=True时用户的代码去画Tab。
      else
        FCanvas.FillRect(Rect); // 这里仅仅在 Rect 框里用单色涂了一层而已。
    end;
      

  7.   

    To: reallike(爱翔)
    呵呵没办法,求知心切嘛。
    我一直在两头看呀,大富翁那里还没有像样的答案。
      

  8.   

    unit MyPageControl;interfaceuses
      Windows, Messages, SysUtils, Classes, Controls, ComCtrls, ExtCtrls, Graphics;type
      TMyPageControl = class(TPageControl)
      private
        { Private declarations }
        FTimer: TTimer;
        FTimerEnabled: Boolean;
        FColor: TColor;    procedure SetTimerEnabled(AValue: Boolean);
        procedure FTimerOnTimer(Sender: TObject);
      protected
        { Protected declarations }
        procedure DrawTab(TabIndex: Integer; const Rect: TRect; Active: Boolean); override;
      public
        { Public declarations }
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
      published
        { Published declarations }
        property TimerEnabled: Boolean read FTimerEnabled write SetTimerEnabled default False;
      end;procedure Register;implementationprocedure Register;
    begin
      RegisterComponents('GybCtrl', [TMyPageControl]);
    end;{ TMyPageControl }constructor TMyPageControl.Create(AOwner: TComponent);
    begin
      inherited;
      OwnerDraw := True;
      FTimer := TTimer.Create(Self);
      FTimerEnabled := False;
      FTimer.Enabled := FTimerEnabled;
      FTimer.OnTimer := FTimerOnTimer;
      FTimer.Interval := 200;
      FColor := clRed;
    end;destructor TMyPageControl.Destroy;
    begin
      if FTimer <> nil then
        FTimer.Free;
      inherited;
    end;procedure TMyPageControl.DrawTab(TabIndex: Integer; const Rect: TRect;
      Active: Boolean);
    var
      TmpRect: TRect;
    begin
      inherited;
      TmpRect := Rect;
      if Active then
        Canvas.Brush.Color := clBlue
      else
        Canvas.Brush.Color := FColor;
      Canvas.FillRect(Rect);
      DrawText(Canvas.Handle, PChar(Pages[TabIndex].Caption), -1, TmpRect,
        DT_SINGLELINE or DT_VCENTER or DT_CENTER);
    end;procedure TMyPageControl.FTimerOnTimer(Sender: TObject);
    begin
      if FColor = clRed then
        FColor := clBlack
      else
        FColor := clRed;
      Repaint;
    end;procedure TMyPageControl.SetTimerEnabled(AValue: Boolean);
    begin
      if FTImerEnabled <> AValue then
      begin
        FTimerEnabled := AValue;
        FTimer.Enabled := FTimerEnabled;
      end;
    end;end.
      

  9.   

    To: xzgyb(老达摩) 
    多谢高手指点!虽然得到的效果和我的原意不一样(我要改变的是标签字体的颜色,而这段代码改变的是标签底色),但还是非常感谢!给分!
      

  10.   

    DDGG:
      不谢,呵呵
      我又理解错了
      我不是高手,初学阶段。