p> 在開發證券分析軟件中,經常要繪製各種股票的分析曲線。為了使得軟件的功能更加方便.靈活,用戶希望能夠按照自己的喜好自定義各種曲線的顏色。在WORD97的[格式]菜單下的字體對話框中有類似的功能。當用戶單擊字體對話框中的顏色下拉框時,各種顏色的簡單圖案和字體的顏色名稱一起顯示出來,這樣處理的結果顯然比只提供一個裝有顏色名稱的下拉框效果要好的多。 一、自定義顏色對話框的實現
在Delphi中,我們可以使用TComboBox 實現類似的功能。在TcomboBox構件中有一個Style屬性, 決定TcomboBox的顯示屬性。 通常可選取csDropDown,CSSimple,csDropDownList, csOwnerDrawFixed,csOwnerDrawVariable等。其中當選取csOwnerDrawFixed時表示創建一個自畫下拉框,下拉框的每一項的高度由ItemHeight屬性決定。並且必須在TcomboBox的OnDrawItem事件中響應自畫過程。 OnDrawItem的定義為:
PRopertyOnDrawItem:TDrawItemEvent;
TDrawItemEvent =procedure(Control:TWinControl;Index:IntegerRect:TRect; State:TOwnerDrawState)ofobject;
其中的三個參數的含義為:
Control: 包含下拉框的TComboBox
Index:自畫的下拉框在TComboBox 的Items屬性中的索引號
Rect:自畫的位置因此,知道了需要自畫的矩形的位置(Rect參數)和在TComboBox中的索引號(Index參數),我們可以使用TcomboBox的Canvas屬性在其畫布上自畫。 具體的實現過程如下:
1.新建一個工程文件,設置其默認窗體的有關屬性為:
Caption 自定義下拉框
Name Form1
PositionpoScreenCenter
2 .在窗體中放置兩個TcomboBox構件,設置其屬性如下:
NameStyleItemHeightOnDrawItem
ColorCombo1csOwnerDrawFixed 20ColorComboDrawItem
ColorCombo2csOwnerDrawFixed 30ColorComboDrawItem
3 .雙擊ColorCombo1和ColorCombo2 的Items屬性旁的圓點按鈕,在StringListEditor對話框中輸入
黑色
藍色
藍綠
鮮綠
紅色
黃色
等各種顏色的名稱
4 .在ColorCombo1的OnDrawItem 事件中餚縵麓?
procedureTForm1.ColorComboDrawItem(Control: TWinControl;Index:Integer;Rect:TRect;State:OwnerDrawState);
var
TempColor:TColor; //自畫顏色
TempBrushColor:TColor; //臨時顏色
begin
with(ControlasTComboBox)do
//在Combo的Canvas 上自畫
begin
TempBrushColor:=Canvas.Brush.Color;
//保存原來的的顏色
Canvas.FillRect(Rect);
caseIndexof//根據Index 的不同,定義不同自畫的顏色
0://黑色
TempColor:=clBlack;
1://藍色
TempColor:=clBlue;
2://藍綠
TempColor:=clAqua;
3://鮮綠
TempColor:=clLime;
4://紅色
TempColor:=clRed;
5://黃色
TempColor:=clyellow;
//可以在此加入對其它顏色的響應
end;
Canvas.Brush.Color:=TempColor;
//自畫顏色矩形
Canvas.Rectangle(Rect.Left+4,
Rect.Top+1,
(Rect.Right+Rect.Left)div3,
Rect.Bottom 1);
Canvas.Brush.Color:=TempBrushColor;
//顯示與顏色對應的字符串
Canvas.TextOut((Rect.Left+Rect.Right)div2,
Rect.Top+1,
Items[Index]);
end;
end;
5 .保存,運行文件,我們可以看到和WORD中顏色下拉框相同的效果
有愛好的讀者,可以在文中所示的位置加入對其它顏色處理。
以上程序在Delphi3.0,4.0 上通過。 二、 自定義顏色對話框構件的編寫
對許多Delphi程序員來說,如何編寫自己的Delphi構件還是比較生疏的,Delphi構件實際上是從Tcomponent 類繼續發展而來,編寫構件實際就是編寫非凡的類。下面我們就以自定義顏色對話框為例介紹構件的編寫。 下面TColorComboBox是從TcomboBox 類繼續來的,當點擊右邊的下拉箭頭時彈出和下拉items對應的各種顏色自畫框。 1. 選中Component菜單項中的New Component選項。在AncestorType 框中選TcomboBox,在ClassName 框中填入TColorComboBox,在Palette Page框中選Samples,在UnitFileName框中填入ColorComboBox.pas, 然後點擊OK按鈕。
2. 選中Component菜單項中的Install Component選項,點擊Intonewpackage,在package name框中寫入路徑和ColorComboDpk.dpk, 點擊ok,生成ColorComboDpk.bpl 文件。
3. 使用Tools菜單中的ImageEditor 來創建編輯文件ColorComBox.dcr, 為TColorComboBox類建立位圖。
4. 在Create中加入對字體大小高度的規定及對控件的Style 屬性(設成csOwnerDrawFixed) 的規定,在Create後執行的CreateWnd中初始化顏色的items,如果不需要那麼多顏色項,可以以後在生成控件的items 屬性中直接刪除不需要的顏色。
5. 在DrawItem事件中加入顏色自畫程序,此事件在On DrawItem之前發生。
實現程序如下:
unitColorComboBox;
interface
uses
Windows,Messages,SysUtils,Classes,
Graphics,Controls,Forms,Dialogs,
StdCtrls;
type
TColorComboBox=class(TComboBox)
private
{Privatedeclarations}
FOnDrawItem:TDrawItemEvent;
procedureDrawItem(Index:Integer;Rect:TRect; State:TOwnerDrawState);override;
protected
{Protecteddeclarations}
public
{Publicdeclarations}
constrUCtorCreate(AOwner:TComponent);override;
procedureCreateWnd;override;
published
{Publisheddeclarations}
propertyOnDrawItem:TDrawItemEvent
ReadFOnDrawItemwriteFOnDrawItem;
end;
procedureRegister;
implementation
procedureRegister;//註冊構件
begin
RegisterComponents(Samples,[TColorComboBox]);
end;
constructorTColorComboBox.Create
(AOwner:TComponent);//構件的初始化
begin
inheritedCreate(AOwner);
Style:=csOwnerDrawFixed; //構件的初始類型
ItemHeight :=20;
Font.Size:=10;
end;
procedureTColorComboBox.CreateWnd;
//顏色構件的Items屬性初始化
begin
inheritedCreateWnd;
Items.Clear;
Items.Add(黑色);
Items.Add(藍色);
Items.Add(藍綠);
Items.Add(鮮綠);
Items.Add(粉紅);
Items.Add(紅色);
Items.Add(黃色);
Items.Add(白色);
Items.Add(深藍);
Items.Add(青色);
Items.Add(綠色);
Items.Add(紫色);
Items.Add(深紅);
Items.Add(深黃);
Items.Add(深灰);
Items.Add(銀色);
//若不需要這麼多顏色可在構件的items屬性中刪除不需要的顏色
end;
//重載DrawItem 過程
procedureTColorComboBox.DrawItem(Index: Integer;Rect:TRect;State:TOwnerDrawState);
var
TempColor:TColor; //自畫顏色
TempBrushColor:TColor; //臨時顏色
begin
//本構件的默認自畫設置
TempBrushColor:=Canvas.Brush.Color;
//保存原來的的顏色
Canvas.FillRect(Rect);
ifItems[index]=黑色then
TempColor:=clBlack
elseifItems[index]=藍色then
TempColor:=clBlue
elseifItems[index]=藍綠then
TempColor:=clAqua
elseifItems[index]=鮮綠then
TempColor:=clLime
elseifItems[index]=粉紅then
TempColor:=clFuchsia
elseifItems[index]=紅色then
TempColor:=clRed
elseifItems[index]=黃色then
TempColor:=clYellow
elseifItems[index]=白色then
TempColor:=clWhite
elseifItems[index]=深藍then
TempColor:=clNavy
elseifItems[index]=青色then
TempColor:=clTeal
elseifItems[index]=綠色then
TempColor:=clGreen
elseifItems[index]=紫色then
TempColor:=clPurple
elseifItems[index]=深紅then
TempColor:=clMaroon
elseifItems[index]=深黃then
TempColor:=clOlive
elseifItems[index]=深灰then
TempColor:=clGray
elseifItems[index]=銀色then
elseTempColor:=clSilver;
Canvas.Brush.Color:=TempColor;
//自畫顏色矩形
Canvas.Rectangle(Rect.Left+4,
Rect.Top+1,
(Rect.Right+Rect.Left)div3,
Rect.Bottom 1);
Canvas.Brush.Color:=TempBrushColor;
//顯示與顏色對應的字符串
Canvas.TextOut((Rect.Left+Rect.Right)div2,
Rect.Top+1,
Items[Index]);
end;
end. 此控件可以在所有需要顏色選項的程序中使用而且非常方便和美觀,並且使編程節省很多時間,增加了程序可靠性和可讀性。 三、 自定義顏色對話框構件的使用
當註冊完自定義顏色構件後,可以從Delphi構件模板的Sample頁中選擇自定義顏色構件,和使用Delphi本身構件沒有區別。