源代码吐血大放送(分太少啦):(实现该功能的组件源代码,完全有本人攥写,还可以继续扩展)unit Unit_ESTipsImageBtn;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;type //图片按钮
TesTipsImageBtn=class(TGraphicControl)
private
{ Private declarations }
//按钮被选择
FDown:Boolean;
//缺省按钮图片
FImage:TBitMap;
//指示当前使用的是第几幅图片
//所加载图片将被缺省的分成四幅
//0:Up 正常
//1:Disabled 禁止
//2:Clicked 移动或焦点
//3:Down 选中
FImageIndex:0..3;
//鼠标进入控件的事件
FOnMouseEnter:TNotifyEvent;
//鼠标离开控件的事件
FOnMouseLeave:TNotifyEvent;
protected
{ Protected declarations }
//文本变化消息处理
procedure CMTextChanged(var Message:TMessage);Message CM_TEXTCHANGED;
//鼠标进入控件消息处理
procedure WMMouseEnter(var Message:TMessage);Message CM_MOUSEENTER;
//鼠标在控件中移动消息处理
procedure WMMouseMove(var Message:TMessage);Message WM_MOUSEMOVE;
//鼠标离开控件消息处理
procedure WMMouseLeave(var Message:TMessage);Message CM_MOUSELEAVE;
//装载按钮图片
procedure SetImage(const Value:TBitMap);
//设置按纽按下
procedure SetDown(const Value:Boolean);
//
procedure paint;override;
public
{ Public declarations }
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
published
{ Published declarations }
//当鼠标进入控件时发生
property OnMouseEnter:TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
//当鼠标离开控件时发生
property OnMouseLeave:TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
//按钮图片
property Image:TBitMap read FImage write SetImage;
//表示按纽被按下
property Down:Boolean read FDown write SetDown;
//
property Visible;
//
property Enabled;
//鼠标单击事件
property OnClick;
//鼠标双击事件
property OnDblClick;
//鼠标按纽按下事件
property OnMouseDown;
//鼠标按纽提起事件
property OnMouseUp;
//鼠标移动事件
property OnMouseMove; end;
procedure Register;implementation
procedure Register;
begin
RegisterComponents('ESTips', [TesTipsImageBtn]);
end;
{ TesTipsImageBtn }constructor TesTipsImageBtn.Create(AOWner:TComponent);
begin
inherited Create(AOwner);
Width:=32;
Height:=32;
FImage:=TBitMap.Create;
FDown:=False;
FImageIndex:=0;
FImage.Transparent := True;
FImage.TransParentColor := FImage.Canvas.Pixels[0,Height];
FImage.TransparentMode := tmAuto;end;//文本变化消息处理
procedure TesTipsImageBtn.CMTextChanged(var Message:TMessage);
begin
inherited;
invalidate;
end;//鼠标进入事件处理
procedure TesTipsImageBtn.WMMouseEnter(var Message:TMessage);
begin
inherited;
//若鼠标进入前为图标0,则换成2
if ((not FDown)and(FImageIndex<>2))then
begin
FImageIndex:=2;
Invalidate;
end;
end;//鼠标在控件中移动消息处理
procedure TesTipsImageBtn.WMMouseMove(var Message:TMessage);
begin
if ((not FDown)and(FImageIndex<>2))then
begin
FImageIndex:=2;
Invalidate;
end;
end;//鼠标离开事件处理
procedure TesTipsImageBtn.WMMouseLeave(var Message:TMessage);
begin
inherited;
//若鼠标进入前为图标0,则换成3
if FDown then FImageIndex:=3 else FImageIndex:=0;
Invalidate;
end;procedure TesTipsImageBtn.SetImage(const Value:TBitMap);
begin
//if Assigned(Value) then FImage.Assign(Value);
FImage.Assign(Value);
Invalidate;
end;//设置按纽按下
procedure TesTipsImageBtn.SetDown(const Value:Boolean);
begin
FDown:=Value;
if Value then FImageIndex:=3 else FImageIndex:=0;
Invalidate;
end;
procedure TesTipsImageBtn.paint;
var
MyBitMap:TBitMap;
MyRect:TRect;
MyImageIndex:integer;
begin
inherited; //若图象为空则退出
if ((FImage.Width=0)or(FImage.Height=0))then Exit;
if Enabled then MyImageIndex:=FImageIndex else MyImageIndex:=1;
MyRect:=Rect(0+MyImageIndex*FImage.Width div 4,0,
(MyImageIndex+1)*FImage.Width div 4,FImage.Height);
//从图片中分解出指定索引号码的图片,并设置为透明色
MyBitMap:=TBitMap.Create;
MyBitMap.Width:=MyRect.Right-MyRect.Left;
MyBitMap.Height:=MyRect.Bottom-MyRect.Top;
MyBitMap.Canvas.CopyRect(Rect(0,0,MyBitMap.Width,MyBitMap.Height),FImage.Canvas,MyRect);
MyBitMap.Transparent := True;
MyBitMap.TransParentColor := FImage.Canvas.Pixels[0,Height];
MyBitMap.TransparentMode := tmAuto;
//写画布
Canvas.Lock;
Canvas.Draw(0,0,MyBitMap);
Canvas.Unlock;
//释放
MyBitMap.Free;
end;destructor TesTipsImageBtn.Destroy;
begin
FImage.Free;
inherited;
end;
end.
由菜单Component->Install Component...导入该新组件。
解决方案 »
- 如何获取鼠标状态(按下弹起)?
- Delphi7做的程序Vista下能用吗?
- 动态链接库问题,请教高手
- 小问题急!!!
- 很简单的一个关于IntraWeb的问题,郁闷,大哥大姐,帮帮忙啊!在线等待!!!!!
- 散分。字符串的简单问题!!!
- [ 菜鸟 P Z C ] 一个非常简单的问题 关于MDICHILD窗体的
- 好惨啊!硬盘出问题了。几个月的心血全部付之东流了!谁救救我?
- *********还是相同的问题,请大家帮帮忙!***********
- Stringgrid中怎样像EHLIB控件中的表格控件那样做竖行统计?
- 在线程的主程序中使用了同步,如何在线程的执行中再执行其他的操作。
- 我想取得DBGrid中被选中的某行某列的单元的值该怎么办?
在image的onmousemove里和form的onmousemove里分别处理就可以了。
(iamge放在form上)
mousemove消息,当它离开时必然触发另一个mousemove消息(一般是这样)
TO lance,我开始就想用你说的办法,但是,只要鼠标在Form里一移动,就会调用form的onmouseMove事件,这样图片会闪烁得很厉害,所以我就想用OnMouseEnter和OnMouseLeave
事件(ONMouseEnter和OnmouseLeave不是Windows的标准消息,是Borland自定义的,我在一本书上看到的)。
通里也可做成Tshape等的移动问题
我的意思是能否在一个Unit里定义并且使用。因为我刚学,又不懂,所以我想用一个简单得例子学习类,还有继承等等。
哦!这样啊! 我以前发过一帖,不知道你能否“细细”看完? 如果“能”,我相信你必定会有收获的! :)http://www.csdn.net/expert/topic/129/129319.shtm :)
看他人源代码也是学习啊,不一定要完全跟你的要求一样,否则,你就没有自己练习的机会了。
enlightenment(阿明--平均睡眠时间<6h/d的超人)很不容易啊,贴了这么多,建议分全给他了。
实际情况是:没有CMMouseMove,至少我没找到。CM(VCL control message)和WM(Window Messages)我一直混用,到目前还没有出过什么娄子。至于在画布重画时,在LOCK以后操作再UNLOCK,应该不会有问题。我还做过(用画布和定时器共同作用显示简单动画的)控件,倒也没什么闪烁! 当然,绘写画布时,绘写流程、算法该精简的还是要精简,特别是在同一次绘写当中(譬如Paint函数中如果发生前后绘写内容重叠,则产生闪烁的可能性很大)。