文中均以Delphi XE 10.3平台为例。
前面重绘TEdit仔细的人发现了,TEditEx1中存在着黑色阴影,如图:

现在我们把阴影去掉、并加上鼠标进入高亮显示、且边框颜色可以直接在属性栏进行修改。先看下效果图:

这里需要响应鼠标进入或离开控件的方法;老版本Delphi没有MouseEnter与MouseLeave的事件(新版本Delphi虽然有这2个事件,却是静态方法不能被覆盖),但可以使用delphi VCL自己定义的消息 响应CM_MOUSEENTER和CM_MOUSELEAVE消息来实现。
procedure CMMouseEnter(var msg: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var msg: TMessage); message CM_MOUSELEAVE;
属性的写法:
属性必写在 published 这样在属性列表中才可见。
在写属性时,写完 property BordColor: Tcolor; 这时按 Ctrl + Shift + c 来快速补全代码。

完整代码:
unit EditEx1;
interface
uses
System.SysUtils, System.Classes, Vcl.Controls, Vcl.StdCtrls, WinApi.Windows, WinApi.Messages,
Vcl.Graphics;
type
TEditEx1 = class(TEdit)
private
FMouseIn: Boolean;
FBordColor: TColor;
FEnterBordColor: TColor;
procedure SetBordColor(const Value: TColor);
procedure SetEnterBordColor(const Value: TColor);
protected
procedure InvalidateNC;
procedure WMNCPAINT(var msg: TWMNCPaint); message WM_NCPAINT;
procedure CMMouseEnter(var msg: TMessage); message CM_MOUSEENTER;
procedure CMMouseLeave(var msg: TMessage); message CM_MOUSELEAVE;
public
{ Public declarations }
published
constructor Create(AOwner: TComponent); override; //构造函数 相当于窗体的 Form1.Create。可无
destructor Destroy; // 析构函数 相当于窗体的 Form1.Destroy。可无
property BordColor: TColor read FBordColor write SetBordColor;
property EnterBordColor: TColor read FEnterBordColor write SetEnterBordColor;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Standard', [TEditEx1]);
end;
procedure TEditEx1.InvalidateNC;
begin
if Parent = nil then Exit;
SendMessage(Handle, WM_NCPAINT, 0, 0);
end;
procedure TEditEx1.SetBordColor(const Value: TColor);
begin
FBordColor := Value;
end;
procedure TEditEx1.SetEnterBordColor(const Value: TColor);
begin
FEnterBordColor := Value;
end;
procedure TEditEx1.CMMouseEnter(var msg: TMessage);
begin
inherited;
FMouseIn:= True;
InvalidateNC;
end;
procedure TEditEx1.CMMouseLeave(var msg: TMessage);
begin
inherited;
FMouseIn:= False;
InvalidateNC;
end;
constructor TEditEx1.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
DoubleBuffered:= True; // 开启双缓冲区,可解决绘图闪烁的问题
FMouseIn:= False; // 初始化鼠标进入状态
FBordColor:= RGB(78,160,209); // 初始化边框色
FEnterBordColor:= RGB(123,228,255); // 初始化高亮边框色
end;
destructor TEditEx1.Destroy;
begin
inherited Destroy;
end;
procedure TEditEx1.WMNCPAINT(var msg: TWMNCPaint);
var
DC: HDC;
BorderBrush: HBRUSH;
R: TRect;
begin
inherited;
DC:= GetWindowDC(Handle);
try
SetRect(R,0,0,Width,Height);
if Enabled then
begin
if FMouseIn then
begin
BorderBrush:= CreateSolidBrush(FEnterBordColor);//创建画刷
FrameRect(Dc, R, BorderBrush);//绘制外部的高亮边框
DeleteObject(BorderBrush);
InflateRect(R,-1,-1);
end
else
begin // 内部阴影线框处理
InflateRect(R,-1,-1);
BorderBrush:= CreateSolidBrush(ColortoRGB(Color)); // Color 为Edit的背景色,也就是属性中的Color
FrameRect(Dc, R, BorderBrush);
DeleteObject(BorderBrush);
InflateRect(R,1,1);
end;
BorderBrush:= CreateSolidBrush(FBordColor);
FrameRect(Dc, R, BorderBrush);//绘制默认的边线框
DeleteObject(BorderBrush);
end
else
begin
// 内部阴影线框处理
InflateRect(R,-1,-1);
BorderBrush:= CreateSolidBrush(ColortoRGB(Color));
FrameRect(Dc, R, BorderBrush);
DeleteObject(BorderBrush);
InflateRect(R,1,1);
// 边框
BorderBrush:= CreateSolidBrush(ColortoRGB(clWindowFrame));
FrameRect(Dc, R, BorderBrush);
DeleteObject(BorderBrush);
end;
finally
ReleaseDC(Handle,DC)
end;
end;
end.
自定义属性图:





