如何設置TBitBtn控件的背景顏色?急!急!!! (100分)

  • 主题发起人 主题发起人 delphiprogramer
  • 开始时间 开始时间
D

delphiprogramer

Unregistered / Unconfirmed
GUEST, unregistred user!
大家都知道 TBitBtn 的背景顏色是不能改變的.但我在做一個程序中需要這一特性,在TBitBtn
按鈕得到焦點的時候,要改變其背景顏色. 請教各位高手,如何給TBitBtn添加一個 Color屬性
(TBitBtn.Color). TBitBtn是從TButton繼承而來的.我這有一段代碼能改變TButton控件的背景顏色,
但沒有TBitBtn的一些功能,如不能改變字體顏色,不能加載圖片。
想請各位高手幫忙將TColorButton.Color屬性轉到TBitBtn中.重新编写一个TColorBitBtn控件,
添加Color属性,能改變TBitBtn的背景顏色,這樣就能實現以上的全部功能了。

TColorButton控件的代碼如下:
unit ColorButton;

interface

uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls,
Graphics,Forms,Dialogs,Buttons,ExtCtrls;

type
TDrawButtonEvent=procedure(Control:TWinControl;Rect:TRect;
State:TOwnerDrawState) of Object;
type
TColorButton = class(TButton)
private
{ Private declarations }
FCanvas:TCanvas;
IsFocused:Boolean;
FOnDrawButton:TDrawButtonEvent;
protected
{ Protected declarations }
procedure CreateParams(var Params:TCreateParams);override;
procedure SetButtonStyle(ADefault:Boolean);override;
procedure CMEnabledChanged(var Message:TMessage);message CM_ENABLEDCHANGED;
procedure CMFontChanged(var Message:TMessage);message CM_FONTCHANGED;
procedure CNMeasureItem(var Message:TWMMeasureItem);message CN_MEASUREITEM;
procedure CNDrawItem(var Message:TWMDrawItem);message CN_DRAWITEM;
procedure WMLButtonDblClk(var Message:TWMLButtonDblClk);message WM_LBUTTONDBLCLK;
procedure DrawButton(Rect:TRect;State:Uint);
public
{ Public declarations }
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
property Canvas:TCanvas read FCanvas;
published
{ Published declarations }
property OnDrawButton:TDrawButtonEvent read FOnDrawButton write FOnDrawButton;
property Color;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Standard', [TColorButton]);
end;

constructor TColorButton.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FCanvas:=TCanvas.Create;
end;

destructor TColorButton.Destroy;
begin
inherited Destroy;
FCanvas.Free;
end;

procedure TColorButton.CreateParams(var Params:TCreateParams);
begin
inherited CreateParams(Params);
with Params do
Style:=Style or BS_OWNERDRAW;
end;

procedure TColorButton.SetButtonStyle(ADefault:Boolean);
begin
if ADefault<>IsFocused then
begin
IsFocused:=ADefault;
Refresh;
end;
end;

procedure TColorButton.CNMeasureItem(var Message:TWMMeasureItem);
begin
with Message.MeasureItemStruct^ do
begin
ItemWidth:=Width;
itemHeight:=Height;
end;
end;

procedure TColorButton.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;
DrawButton(rcItem,ItemState);
finally
FCanvas.Handle:=0;
FCanvas.Unlock;
RestoreDC(hDC,SaveIndex);
end;
end;
Message.Result:=1;
end;

procedure TColorButton.CMEnabledChanged(var Message:TMessage);
begin
inherited;
Invalidate;
end;

procedure TColorButton.CMFontChanged(var Message:TMessage);
begin
inherited;
Invalidate;
end;

procedure TColorButton.WMLButtonDblClk(var Message:TWMLButtonDblClk);
begin
Perform(WM_LBUTTONDOWN,Message.Keys,Longint(Message.Pos));
end;

procedure TColorButton.DrawButton(Rect:TRect;State:Uint);
var
Flags,OldMode:Longint;
IsDown,IsDefault,IsDisabled:Boolean;
OldColor:TColor;
OldRect:TRect;
begin
OldRect:=Rect;
Flags:=DFCS_BUTTONPUSH or DFCS_ADJUSTRECT;
IsDown:=State and ODS_SELECTED<>0;
ISDefault:=State and ODS_FOCUS<>0;
IsDisabled:=State and ODS_DISABLED<>0;

if IsDown then
Flags:=Flags or DFCS_PUSHED;
if IsDisabled 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(Rect.Left,Rect.Top,Rect.Right,Rect.Bottom);
InFlateRect(Rect,-1,-1);
end;

if IsDown then
begin
FCanvas.Pen.Color:=clBtnShadow;
FCanvas.Pen.Width:=1;
FCanvas.Brush.Color:=clBtnFace;
FCanvas.Rectangle(Rect.Left,Rect.Top,Rect.Right,Rect.Bottom);
InFlateRect(Rect,-1,-1);
end
else
DrawFrameControl(FCanvas.Handle,Rect,DFC_BUTTON,Flags);

if IsDown then OffsetRect(Rect,1,1);

OldColor:=Fcanvas.Brush.Color;
FCanvas.Brush.Color:=Color;
FCanvas.FillRect(Rect);
FCanvas.Brush.Color:=OldColor;
OldMode:=SetBkMode(FCanvas.Handle,TRANSPARENT);
FCanvas.Font.Color:=clBtnText;
if isDisabled then
DrawState(FCanvas.Handle,FCanvas.Brush.Handle,nil,Integer(Caption),0,
((Rect.Right-Rect.Left)-FCanvas.TextHeight(Caption)) div 2,
((Rect.Bottom-Rect.Top)-FCanvas.TextHeight(Caption)) div 2,
0,0,DST_TEXT or DSS_DISABLED)
else
DrawText(FCanvas.Handle,PChar(Caption),-1,Rect,
DT_SINGLELINE or DT_CENTER or DT_VCENTER);
SetBkMode(FCanvas.Handle,OldMode);

if Assigned(FOnDrawButton) then
FOndrawButton(Self,Rect,TOWnerDrawState(LongRec(State).Lo));

if IsFocused and IsDefault then
begin
Rect:=OldRect;
InflateRect(Rect,-4,-4);
FCanvas.Pen.Color:=clWindowFrame;
FCanvas.Brush.Color:=clBtnFace;
DrawFocusRect(FCanvas.Handle,Rect);
end;
end;
end.
 
圖片都可以加,背景還不可以實現嗎?你不能用圖片呀
 
上面的大哥,TBitBtn控件本來就可以加載圖片,但不能改變背景顏色。我是需要
改變TBitBtn 的背景顏色。
 
procedure TColorButton.DrawItem(const DrawItemStruct: TDrawItemStruct);
var
IsDown: Boolean;
State: TButtonState;
R: TRect;
i:Integer;
begin
FCanvas.Handle := DrawItemStruct.hDC;
R := ClientRect;
if (DrawItemStruct.itemState and ODS_DISABLED <> 0) or not Enabled then
FCanvas.Brush.Color:=FDisColor
else
FCanvas.Brush.Color:=FColor;
FCanvas.FillRect(R);
with DrawItemStruct do
begin
IsDown := itemState and ODS_SELECTED <> 0;

if not Enabled then State := bsDisabled
else if IsDown then State := bsDown
else State := bsUp;
end;

{ DrawFrameControl does not draw a pressed button correctly }
if IsDown then
begin
FCanvas.Pen.Color := clBtnShadow;
FCanvas.Pen.Width := 1;
i:=2;
Frame3D(FCanvas,R,clBtnShadow,clBtnHighlight,i);
InflateRect(R, -i, -i);
end
else
begin
if not MouseIn then
begin
i:=1;
Frame3D(FCanvas,R,clBtnHighlight,clBtnShadow,i);
InflateRect(R, -i, -i);
end else
begin
i:=2;
Frame3D(FCanvas,R,clBtnHighlight,clBtnShadow,i);
InflateRect(R, -i, -i);
end;
end;
if (Default or IsDown or MouseIn) and Enabled then
DrawFocusRect(FCanvas.Handle,R);

FCanvas.Font := Self.Font;
if IsDown then
OffsetRect(R, 1, 1);
TButtonGlyph(FGlyph).Draw(FCanvas, R, Point(0,0), Caption, FLayout, FMargin,
FSpacing, State, True, DrawTextBiDiModeFlags(0));

FCanvas.Handle := 0;
end;
 
可以用别的控件啊!
 
TO:aizb
很高興得到你的幫助,同時也訪問了你的網站,並找到了答案。希望多些像你這樣的富翁。
請多多指教!
 
喝喝,不客气大家一起学习!
 
To:aizb
昨天下載了你的 MyBitBtn 控件,安裝後才發現有一缺點。就是控件不能獲得焦點(不能使用SetFocus,運行時會出錯),晚上
自己改了一段時間,但沒改過來。希望你有空時,把它完美下。
 
procedure TSA3BitBtn.DrawItem(const DrawItemStruct: TDrawItemStruct);
var
IsDown: Boolean;
State: TButtonState;
R: TRect;
i:Integer;
begin
FCanvas.Handle := DrawItemStruct.hDC;
R := ClientRect;
if (DrawItemStruct.itemState and ODS_DISABLED <> 0) or not Enabled then
FCanvas.Brush.Color:=FDisColor
else
FCanvas.Brush.Color:=FColor;
FCanvas.FillRect(R);
with DrawItemStruct do
begin
IsDown := itemState and ODS_SELECTED <> 0;
if not Enabled then State := bsDisabled
else if IsDown then State := bsDown
else State := bsUp;
end;
{ DrawFrameControl does not draw a pressed button correctly }
if IsDown then
begin
FCanvas.Pen.Color := clBtnShadow;
FCanvas.Pen.Width := 1;
i:=2;
Frame3D(FCanvas,R,clBtnShadow,clBtnHighlight,i);
InflateRect(R, -i, -i);
end
else
begin
if not MouseIn then
begin
i:=1;
Frame3D(FCanvas,R,clBtnHighlight,clBtnShadow,i);
InflateRect(R, -i, -i);
end else
begin
i:=2;
Frame3D(FCanvas,R,clBtnHighlight,clBtnShadow,i);
InflateRect(R, -i, -i);
end;
end;
if (Default or IsDown or MouseIn or Focused) and Enabled then
//请注意上面这一行的条件里面比原来的代码增加了一个 or Focused,也就是说如果控件当前获得了焦点则绘制焦点框.
DrawFocusRect(FCanvas.Handle,R);
FCanvas.Font := Self.Font;
if IsDown then
OffsetRect(R, 1, 1);
TButtonGlyph(FGlyph).Draw(FCanvas, R, Point(0,0), Caption, FLayout, FMargin,
FSpacing, State, True, DrawTextBiDiModeFlags(0));
FCanvas.Handle := 0;
end;

 
后退
顶部