程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 用Delphi做一個有顏色屬性的按鈕

用Delphi做一個有顏色屬性的按鈕

編輯:Delphi

在標准的Windows程序中所有按鈕均沒有顏色。因此Delphi提供的所有按鈕組件也均無顏色屬性,有時你可能做了一個五顏六色的程序界面,而按鈕顏色可能很不相稱。
      在此本人提供一種用自定義組件制作有顏色屬性的铵鈕的方法,它遵循了Delphi的組件定義規則,完成後該按鈕與普通按鈕(Button)相比,多了一個Color屬性,你可以永遠地使用它,在設計階段隨意地改變顏色,就象是Delphi本身提供的組件一樣(本文代碼在Delphi 4.0下完成)。
  第一步
     
打開Delphi,選擇菜單的Component/New Component選項,在彈出對話框的Ancestor type下拉框中手工填入或下拉選擇TButton,這是選擇了我們自定義組件的祖先類,我們將以此為基礎完成自定義組件的下一步代碼編寫(這也是自定義組件編寫的第一步)。對話框中的其余可編寫內容就隨你的高興而填寫了,但是你必須注意Class Name(類名)不能和已有的(包括你自定義的)類名相同,同時還應該記住該自定義組件的安裝位置(Palette Page下拉框中的內容)和單元文件在磁盤上的存放位置(Unit file name編輯框內容),不然以後你在何處去找它?本文以 Delphi的默認值TButton1為類名。
  第二步
      做完以上工作後,按下面的OK按鈕,Delphi將為你自動生成一個基本的組件代碼,對這樣的代碼框架一般沒有必要修改,一定要修改的話請注意Delphi的組件定義規則(本文只是刪除了所有自動生成的注釋內容),接著就應該將其文件存盤。
  第三步
      在上面的代碼框架中添加我們的代碼,當然這是我們要做的主要工作。

1.      將Delphi自動生成的單元文件的數據類型定義部份修改為:
  type
  TButton1 = class(TButton)
  private
    FColor:TColor;
    FCanvas: TCanvas;
    IsFocused: Boolean;
    procedure SetColor(Value:TColor);
    procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
  protected
    procedure CreateParams(var Params: TCreateParams); override;
    procedure SetButtonStyle(ADefault: Boolean); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Color:TColor read FColor write SetColor default clWhite;
  end;
  說明:
      a. 我們只添加了一個屬性,因此在published段的代碼下只有一個Color屬性,並將默認顏色設為白色(clWhite,當然你可以隨意改變)。
      b. 重載構造函數和析構函數,二者應為可以在外部調用,因此應將其放在public段。
      c. 讀屬性的私有數據域FColor和屬性的寫方法SetColor,應放在私有段(private),其它與此相關的非獨立的變量和過程/函數等也應放在private段,以使在類以外不能訪問它們。

2.      Delphi自動生成的 procedure Register可以不理它。我們在它的過程體之後,在end.(注意符號“.”)之前手工加上以下代碼,完成我們在上面定義的全部過程的過程體編寫(這裡我們沒有定義有函數原型):
  
  //*** 構造函數 *****************************************************
  constructor TButton1.Create(AOwner: TComponent);
  begin
    inherited Create(AOwner);
    FCanvas := TCanvas.Create;
    FColor:=clWhite;//默認顏色
  end;
  
  //*** 析構函數 *************************************************
  destructor TButton1.Destroy;
  begin
    FCanvas.Free;
    inherited Destroy;
  end;
  
  //*** 定義按鈕樣式,必須將該按鈕重定義為自繪式按鈕 *************
  procedure TButton1.CreateParams(var Params: TCreateParams);
  begin
    inherited CreateParams(Params);
    with Params do Style := Style or BS_OWNERDRAW;
  end;
  
  //*** 屬性寫方法 ************************************************
  procedure TButton1.SetColor(Value:TColor);
  begin
    FColor:=Value;
    Invalidate;
  end;
  
  //*** 設置按鈕狀態***********************************************
  procedure TButton1.SetButtonStyle(ADefault: Boolean);
  begin
    if ADefault <> IsFocused then
    begin
      IsFocused := ADefault;
      Refresh;
    end;
  end;
  
  //*** 繪制按鈕 ***************************************************
  procedure TButton1.CNDrawItem(var Message: TWMDrawItem);
  var
    IsDown, IsDefault: Boolean;
    ARect: TRect;
    Flags: Longint;
    DrawItemStruct: TDrawItemStruct;
    wh:TSize;
  begin
    DrawItemStruct:=Message.DrawItemStruct^;
    FCanvas.Handle := DrawItemStruct.hDC;
    ARect := ClIEntRect;
    with DrawItemStruct do
    begin
      IsDown := itemState and ODS_SELECTED <> 0;
      IsDefault := itemState and ODS_FOCUS <> 0;
    end;
  
    Flags := DFCS_BUTTONPUSH or DFCS_ADJUSTRECT;
    if IsDown then Flags := Flags or DFCS_PUSHED;
    if DrawItemStruct.itemState and ODS_DISABLED <> 0 then
       Flags := Flags or DFCS_INACTIVE;
  
    if IsFocused or IsDefault then
    begin
      //按鈕得到焦點時的狀態繪制
      FCanvas.Pen.Color := clWindowFrame;
      FCanvas.Pen.Width := 1;
      FCanvas.Brush.Style := bsClear;
      FCanvas.Rectangle(ARect.Left, ARect.Top, ARect.Right, ARect.Bottom);
      InflateRect(ARect, -1, -1);
    end;
  
    FCanvas.Pen.Color := clBtnShadow;
    FCanvas.Pen.Width := 1;
    FCanvas.Brush.Color := FColor;
    if IsDown then begin
      //按鈕被按下時的狀態繪制
       FCanvas.Rectangle(ARect.Left , ARect.Top, ARect.Right, ARect.Bottom);
       InflateRect(ARect, -1, -1);
    end else
       //繪制一個未按下的按鈕
       DrawFrameControl(DrawItemStruct.hDC, ARect, DFC_BUTTON, Flags);
    FCanvas.FillRect(ARect);
  
    //繪制Caption文本內容
    FCanvas.Font := Self.Font;
    ARect:=ClIEntRect;
    wh:=FCanvas.TextExtent(Caption);
    FCanvas.Pen.Width := 1;
    FCanvas.Brush.Style := bsClear;
    if not Enabled then
    begin //按鈕失效時應多繪一次Caption文本
       FCanvas.Font.Color := clBtnHighlight;
       FCanvas.TextOut((Width div 2)-(wh.cx div 2)+1,
                       (height div 2)-(wh.cy div 2)+1,
                        Caption);
       FCanvas.Font.Color := clBtnShadow;
    end;
    FCanvas.TextOut((Width div 2)-(wh.cx div 2),(height div 2)-(wh.cy div 2),Caption);
  
    //繪制得到焦點時的內框虛線
    if IsFocused and IsDefault then
    begin
       ARect := ClIEntRect;
       InflateRect(ARect, -4, -4);
       FCanvas.Pen.Color := clWindowFrame;
       FCanvas.Brush.Color := FColor;
       DrawFocusRect(FCanvas.Handle, ARect);
    end;
    FCanvas.Handle := 0;
  end;
  //** The End *********************************************************
  end.

第四步:檢查確認無誤後選擇Delphi菜單的Component/Install Component選項,在Unite file name編輯框中確認你的文件路徑和名稱後按OK按鈕,Delphi將編譯、安裝該組件。
        如果你完全按本文步聚進行,在編譯安裝無誤後,你可以在Delphi組件標簽的Samples標簽頁中找到一個圖標和TButton一樣的按鈕。新建一個工程並將這個我們自義的按鈕放置在Form上其默認的名稱是Button11,你會看到一個白色的按鈕。怎麼樣?通過其Color屬性你以隨意設置它的顏色。
        最後說明:本文中的按鈕繪制方式采用了和Delphi本身的TButton相似的繪制方式,以達到和Delphi按鈕相似的動作外觀。然而你想要發揮的話你可以在FCanvas這塊畫布上繪制任意的、你想要的、可以表達你的個性的所有文字和圖形。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved