我有 Delphi 7,现在安装了 Delphi XE2。我对设计、VCL 等方面并没有真正的经验,但我想要一个按钮(带标题!)和一个简单的背景图像(PNG)。我有 3 张自定义按钮的图片(1 张用于单击,1 张用于鼠标悬停,1 张用于鼠标悬停)。我几乎尝试了所有方法,但我似乎无法找到一种方法来设置一个简单的按钮,中间有标题,背景有图像。请帮忙。
PS.:按钮不应该在点击时在视觉上下降(这已经在 png 图像中。)
我有 Delphi 7,现在安装了 Delphi XE2。我对设计、VCL 等方面并没有真正的经验,但我想要一个按钮(带标题!)和一个简单的背景图像(PNG)。我有 3 张自定义按钮的图片(1 张用于单击,1 张用于鼠标悬停,1 张用于鼠标悬停)。我几乎尝试了所有方法,但我似乎无法找到一种方法来设置一个简单的按钮,中间有标题,背景有图像。请帮忙。
PS.:按钮不应该在点击时在视觉上下降(这已经在 png 图像中。)
您可以调整这个微小的组件,无需安装测试
测试:
procedure TForm1.MyOnClick(Sender: TObject);
begin
ShowMessage('Hallo');
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
With TImageButton.Create(self) do
begin
parent := Self;
images := Imagelist1;
index := 0;
hoverindex := 1;
DownIndex := 2;
Caption := 'test';
OnClick := MyOnClick;
Width := Imagelist1.Width;
Height := Imagelist1.Height;
Font.Size := 12;
Font.Style := [fsBold];
end;
end;
和代码:
unit ImageButton;
// 2013 bummi
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
ExtCtrls, StdCtrls,ImgList;
Type
TState = (MouseIn, MouseOut, Pressed);
TImageButton = class(TGraphicControl)
private
FChangeLink:TChangeLink;
FImages: TCustomImageList;
FDownIndex: Integer;
FIndex: Integer;
FHoverIndex: Integer;
FState: TState;
FCaption: String;
FOwner: TComponent;
FAutoWidth: Boolean;
procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
procedure CMTextChanged(var Message: TMessage); message CM_TEXTCHANGED;
procedure CMFontChanged(var Message: TMessage); message CM_FONTCHANGED;
procedure WMLBUTTONDOWN(var Message: TMessage); message WM_LBUTTONDOWN;
procedure WMLBUTTONUP(var Message: TMessage); message WM_LBUTTONUP;
procedure SetDownIndex(const Value: Integer);
procedure SetHoverIndex(const Value: Integer);
procedure SetIndex(const Value: Integer);
procedure SetImages(const Value: TCustomImageList);
procedure SetCaption(const Value: String);
procedure ImagelistChange(Sender: TObject);
procedure SetAutoWidth(const Value: Boolean);
procedure CheckAutoWidth;
protected
procedure Paint; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; Override;
published
property AutoWidth:Boolean read FAutoWidth Write SetAutoWidth;
property Caption;
property DownIndex: Integer read FDownIndex Write SetDownIndex;
property Font;
property HoverIndex: Integer read FHoverIndex Write SetHoverIndex;
property Images: TCustomImageList read FImages write SetImages;
property Index: Integer read FIndex Write SetIndex;
End;
procedure Register;
implementation
procedure TImageButton.ImagelistChange(Sender:TObject);
begin
invalidate;
CheckAutoWidth;
end;
Constructor TImageButton.create(AOwner: TComponent);
begin
inherited Create(AOwner);
FOwner := AOwner;
FState := MouseOut;
Width := 200;
Height := 200;
FChangeLink:=TChangeLink.Create;
FChangeLink.OnChange := ImagelistChange;
end;
Destructor TImageButton.Destroy;
begin
if Assigned(FImages) then FImages.UnRegisterChanges(FChangeLink);
FChangeLink.Free;
inherited Destroy;
end;
procedure TImageButton.Paint;
var
ico: TIcon;
idx: Integer;
DestRect: TRect;
L_Caption: String;
begin
inherited;
idx := -1;
if Assigned(FImages) then
begin
case FState of
MouseIn:
if FImages.Count > HoverIndex then
idx := HoverIndex;
MouseOut:
if FImages.Count > Index then
idx := Index;
Pressed:
if FImages.Count > DownIndex then
idx := DownIndex;
end;
if idx > -1 then
try
ico := TIcon.create;
FImages.GetIcon(idx, ico);
Canvas.Draw(0, 0, ico);
finally
ico.Free;
end;
end
else
begin
Canvas.Rectangle(ClientRect);
end;
Canvas.Brush.Style := bsClear;
DestRect := ClientRect;
L_Caption := Caption;
Canvas.Font.Assign(Font);
Canvas.TextRect(DestRect, L_Caption, [tfVerticalCenter, tfCenter, tfSingleLine]);
end;
procedure TImageButton.CheckAutoWidth;
begin
if FAutoWidth and Assigned(FImages) then
begin
Width := FImages.Width;
Height := FImages.Height;
end;
end;
procedure TImageButton.SetAutoWidth(const Value: Boolean);
begin
FAutoWidth := Value;
CheckAutoWidth;
end;
procedure TImageButton.SetCaption(const Value: String);
begin
FCaption := Value;
Invalidate;
end;
procedure TImageButton.SetDownIndex(const Value: Integer);
begin
FDownIndex := Value;
Invalidate;
end;
procedure TImageButton.SetHoverIndex(const Value: Integer);
begin
FHoverIndex := Value;
Invalidate;
end;
procedure TImageButton.SetImages(const Value: TCustomImageList);
begin
if Assigned(FImages) then FImages.UnRegisterChanges(FChangeLink);
FImages := Value;
if Assigned(FImages) then
begin
FImages.RegisterChanges(FChangeLink);
FImages.FreeNotification(FOwner);
CheckAutoWidth;
end;
Invalidate;
end;
procedure TImageButton.SetIndex(const Value: Integer);
begin
FIndex := Value;
Invalidate;
end;
procedure TImageButton.WMLBUTTONDOWN(var Message: TMessage);
begin
inherited;
FState := Pressed;
Invalidate;
end;
procedure TImageButton.WMLBUTTONUP(var Message: TMessage);
begin
inherited;
FState := MouseIn;
Invalidate;
end;
procedure TImageButton.CMFontChanged(var Message: TMessage);
begin
Invalidate;
end;
Procedure TImageButton.CMMouseEnter(var Message: TMessage);
Begin
inherited;
if (csDesigning in ComponentState) then
Exit;
if FState <> MouseIn then
begin
FState := MouseIn;
Invalidate;
end;
end;
Procedure TImageButton.CMMouseLeave(var Message: TMessage);
Begin
inherited;
if (csDesigning in ComponentState) then
Exit;
if FState <> MouseOut then
begin
FState := MouseOut;
Invalidate;
end;
end;
procedure TImageButton.CMTextChanged(var Message: TMessage);
begin
invalidate;
end;
procedure Register;
begin
RegisterComponents('Own', [TImageButton])
end;
end.
如果与 PNG 和 Imagelist cd32Bit 一起使用,将尊重透明胶片
您可以从 TBitBtn 继承并覆盖 CN_DRAWITEM 消息处理程序 - 这将创建一个完全正常的具有焦点的按钮、您需要的任何图片作为背景以及按钮需要的所有窗口消息(请参阅 BM_XXX 消息)。您还可以实现一个虚拟方法来执行其他类型的按钮,只需覆盖此方法。
像这样的东西:
TOwnerDrawBtn = class(TBitBtn)
private
procedure CNDrawItem(var Message: TWMDrawItem); message CN_DRAWITEM;
procedure CMFocusChanged(var Message: TMessage); message CM_FOCUSCHANGED;
protected
procedure DrawButton(const DrawItemStruct: TDrawItemStruct); virtual;
end;
procedure TOwnerDrawBtn.CNDrawItem(var Message: TWMDrawItem);
begin
DrawButton(Message.DrawItemStruct^);
Message.Result := Integer(True);
end;
procedure TOwnerDrawBtn.CMFocusChanged(var Message: TMessage);
begin
inherited;
Invalidate;
end;
procedure TOwnerDrawBtn.DrawButton(const DrawItemStruct: TDrawItemStruct);
var
Canvas: TCanvas;
begin
Canvas := TCanvas.Create;
try
Canvas.Handle := DrawItemStruct.hDC;
//do any drawing here
finally
Canvas.Handle := 0;
Canvas.Free;
end;
end;
您可以简单地TJvTransparentButton
从JEDI-Project JVCL中使用。
使用此组件,您可以将单个图像列表用于所有事件和所有其他按钮,更多事件与图像状态,更多样式,Caption,Glyph,PressOffset 和...。