需求:

QQ我的资料中基本资料窗体中的文本框:

正常状态下,文本框只有一条看起来只有一个像素的边框,边框的颜色从上到下由深到浅的渐变,当鼠标定位到该文本框时,其边框会变粗,而且边框的颜色加亮显示

如下图所示:

实现思路:

一、准备两个边框素材图片,

一个是正常状态下的边框素材,

比如:

另一个是鼠标进入到文本框内的边框素材

比如:

二、需要的参数

首先是边框素材的绘制边距,分为左边距,右边距,上边距,下边距

边框素材根据边距的设置,使用九宫格缩放绘制到界面上

其次是边框的边距,也为左边距,右边距,上边距,下边框

代表的是文本框客户区(即输入区)的大小

默认的,边框素材的绘制边距和边框的边距是一样的

三、消息处理

边框属于文本框的非客户区域,在文本框的WM_NCPAINT中绘制

文本框的边框风格有两种:bsNone和bsSingle

bsNone即为无边框样式,不需要绘制边框,而且文本框的大小就是客户区的大小

bsSingle为单边框样式,默认边框为两个像素的宽

如果需要自定义文本框的边框宽度,那么需要处理WM_NCCALCSIZE消息

通过WM_NCCALCSIZE消息,使边框扩展为自己所设置的宽度

例(边框扩展一个像表):

procedure TSkinNormalEdit.WMNCCalcSize(varMessage: TWMNCCalcSize);

var

NCCalcSizeParams: PNCCalcSizeParams;

begin

Inherited;

if(BorderStyle=bsNone) then

begin

end

else

begin

NCCalcSizeParams:=Message.CalcSize_Params;

Inc(NCCalcSizeParams.rgrc0.Top,1);

Inc(NCCalcSizeParams.rgrc0.Left,1);

Dec(NCCalcSizeParams.rgrc0.Right,1);

Dec(NCCalcSizeParams.rgrc0.Bottom,1);

end;

end;

四、边框绘制时机

边框有两种状态,鼠标进入到文本框中和鼠标离开文本框

所以,要判断这两种状态

像一般的从TCustomControl或TGraphicControl继承过来的控件,

我们可以通过Delphi内部的管理消息CM_MOUSEENTER和CM_MOUSELEAVE消息处理

但是文本框包含非客户区(边框)和客户区

CM_MOUSEENTER和CM_MOUSELEAVE消息只是鼠标进入或是离开客户区才会响应

所以接下来要处理如何判断鼠标在非客户区中

非客户区的鼠标移动消息主要有三个

WM_NCMOUSEMOVE:非客户区鼠标移动

WM_NCHITTEST:非客户区鼠标移动在控件的哪个部位(标题栏?边框?边角?客户区等等)

WM_NCMOUSELEAVE:鼠标离开非客户区(但是文本框不触发这个消息)

综上,没有一个消息可以简单的标识鼠标是否在控件中

CM_MOUSEENTER可以判断鼠标进入控件的客户区

WM_NCHITTEST可以判断鼠标在控件的非客户区

CM_MOUSELEAVE不能判断鼠标离开控件的客户区

所以,用一个定时器加一个判断鼠标在客户区的过程组合

WM_NCHITTEST消息中,判断当鼠标进入第一次非客户区时,响应鼠标进入消息,重绘边框,设置定时器,判断鼠标是否会在100毫秒内离开文本框

CM_MOUSEENTER消息中,鼠标已经进入客户区了,重绘边框

CM_MOUSELEAVE 消息中,只是表明了鼠标离开客户区,所以要启动定时器,每100毫秒判断鼠标是否在文本框中,如果检测到鼠标离开文本框,那么需要响应鼠标离开,重绘边框

五、边框绘制

边框为非客户区,在文本框的WM_NCPAINT消息中绘制

比如:

procedure TSkinNormalEdit.WMNCPaint(varMessage: TWMNCPaint);

var

tmpWindowDC:HDC;

tmpBorderImage:IGPBitmap;

tmpWindowCanvas:TCanvas;

tmpBitmapGraphics:IGPGraphics;

begin

ifSelf.BorderStyle=bsNone then

begin

Inherited;

end

else

begin

tmpWindowDC:=GetWindowDC(Handle);

Try

if tmpWindowDC<>0 then

begin

tmpWindowCanvas:=TCanvas.Create;

Try

tmpWindowCanvas.Handle:=tmpWindowDC;

FParentBackGroundBitmap.SetSize(Width,Height);

if FIsBroderTransparent then

begin

//绘制文本框背景

DrawParentImageDefault(Self,FParentBackGroundBitmap.Canvas.Handle);

end;

//边框为png素材,使用GDI+绘制,需要获取绘制接口,需要引用gdiplus和gdiplushelpers单元

tmpBitmapGraphics:=FParentBackGroundBitmap.Canvas.ToGPGraphics;

//根据鼠标状态判断边框图片

if Self.MouseInClient or CursorInControl then

begin

tmpBorderImage:=Self.FHoverBorderBitmap;

end

else

begin

tmpBorderImage:=Self.FNormalBorderBitmap;

end;

//再绘制背景

if tmpBorderImage<>nil then

begin

//九宫格绘制边框素材

TSkinHelper.StretchDrawImageBorderInRectByMargins(tmpBitmapGraphics,

tmpBorderImage,TGPRect.Create(0,0,Width,Height),

Self.FBorderDrawMargins.Left,

Self.FBorderDrawMargins.Top,

Self.FBorderDrawMargins.Right,

Self.FBorderDrawMargins.Bottom);

end;

//绘制最外的边框

//左边框

BitBlt( tmpWindowDC,0,0,Self.FBorderMargins.Left,Height,

FParentBackGroundBitmap.Canvas.Handle,0,0,SRCCOPY  );

//右边框

BitBlt( tmpWindowDC,Width-Self.FBorderMargins.Right,0,Self.FBorderMargins.Right,Height,

FParentBackGroundBitmap.Canvas.Handle,Width-Self.FBorderMargins.Right,0,SRCCOPY  );

//上边框

BitBlt( tmpWindowDC,0,0,Width,Self.FBorderMargins.Top,

FParentBackGroundBitmap.Canvas.Handle,0,0,SRCCOPY  );

//下边框

BitBlt( tmpWindowDC,0,Height-Self.FBorderMargins.Bottom,Width,Self.FBorderMargins.Bottom,

FParentBackGroundBitmap.Canvas.Handle,0,Height-Self.FBorderMargins.Bottom,SRCCOPY  );

Finally

FreeAndNil(tmpWindowCanvas);

End;

end;

Finally

ReleaseDC(Handle,tmpWindowDC);

End;

end;

end;

delphi 可以自定义边框的文本框TSkinNormalEdit思路(QQ2011风格)的更多相关文章

  1. vue学习(十七) 使用自定义指令 使文本框获得鼠标焦点

    需求:当我们进入某个页面,页面中的第一个input会自动获得焦点 光标闪烁,代表可输入 <div id="app"> //v-focus 是自定义的 <input ...

  2. JavaScript中自定义函数以及文本框、radio、下拉框的值的获取,结合淘宝竞拍案例来理解。。。

    淘宝竞拍案例: HTML部分代码: <form action="#" method="post"> <h2>欢迎进入淘宝竞拍</h ...

  3. [Swift通天遁地]二、表格表单-(15)自定义表单文本框内容的格式

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  4. css装饰文本框input

    在web程序前端页面中,<input>恐怕是用的最多的html元素了,各个需要录入信息的场合都会用到它,一般都会用css来修饰一下使得它更好看. 原始的不加修饰的文本框像下面,有些单调,页 ...

  5. [转]让你的网页文本框增加光晕效果与提示,水印(类似QQ2011)

    本文转自:http://www.cnblogs.com/xiaofengfeng/archive/2013/01/28/2880344.html 让你的网页文本框增加光晕效果(类似QQ2011) 我们 ...

  6. 用MVC的辅助方法自定义了两个控件:“可编辑的下拉框控件”和“文本框日历控件”

    接触MVC也没多长时间,一开始学的时候绝得MVC结构比较清晰.后来入了门具体操作下来感觉MVC控件怎么这么少还不可以像ASP.net form那样拖拽.这样设计界面来,想我种以前没学过JS,Jquer ...

  7. C#Winform使用扩展方法自定义富文本框(RichTextBox)字体颜色

    在利用C#开发Winform应用程序的时候,我们有可能使用RichTextBox来实现实时显示应用程序日志的功能,日志又分为:一般消息,警告提示 和错误等类别.为了更好地区分不同类型的日志,我们需要使 ...

  8. iOS不得姐项目--登录模块的布局,设置文本框占位文字颜色,自定义内部控件竖直排列的按钮

    一.登录模块的布局 将一整部分切割成若干部分来完成,如图分成了三部分来完成 设置顶部状态栏为白色的方法 二.设置文本框占位文字颜色 <1>方法一与方法二实现原理是同一种,都是通过设置pla ...

  9. javascript当文本框获得焦点设置边框

    javascript当文本框获得焦点设置边框:本章节介绍一下当文本框获得焦点以后如何设置文本框的边框样式,本来是一个非常简单的问题,但是有可能前台美工人员对javascript并不是太了解,所以还是通 ...

随机推荐

  1. 获取请求url中的参数

    一.根据request获取参数 假设请求地址是: http://127.0.0.1:8020/books/?title=语文 那么后台的路由配置: re_path('books/$', views.B ...

  2. mongodb4.0数据库权限配置

    今天给大家分享一个关于mongodb数据库权限配置的小知识点,这里呢,我用的是mongodb4.0版本,下载地址:https://www.mongodb.com/download-center/com ...

  3. magento 为用户注册增加一个字段

    步骤 I. 加一个occupation/title字段到用户注册页,差不多在register.html的54行,在email下方加一个Occupation显示代码 代码: <li>< ...

  4. [Android开发] 代码code设置9.png/9-patch 图片背景后,此view中的TextView等控件显示不正常(常见于listview中)

    == 0) { convertView.setBackgroundResource(R.drawable.list_gray_9); } else { convertView.setBackgroun ...

  5. 调用JavaScript实现字符串计算器

    调用JavaScript实现字符串计算器 如果表达式是字符串的形式,那么一般我们求值都会遇到很大的问题.   这里有一种直接调用JavaScript的方法来返回数值,无疑神器. 代码如下: @Fros ...

  6. thinkphp 使用redis 整理(二) mark 一下

    参考手册   http://www.cnblogs.com/weafer/archive/2011/09/21/2184059.html redis  几种数据类型选择,参考 :  https://b ...

  7. Ubuntu下安装Samba服务器

    闲来无聊尝试自己安装下Samba服务器,使本机和虚拟机可以无障碍传输文件(虽然用VMwaretools可传,但总感觉麻烦,而且速度欠佳) 首先,同安装qemu一样,在安装之前要确定你的系统apt列表已 ...

  8. JMeter AI图片识别接口并发量测试

    由于临时接到一个性能测试任务,测试8个独立接口在实验室环境的TPS.响应时间以及服务器性能监控如CPU.内存.IO等,没有明确具体的响应时间与并发数,需求较模糊. 1.软件.硬件环境信息:JMeter ...

  9. ATM+购物车结构

    ATM+购物车 1.需求分析 2.程序设计及目录设计 3.编写程序 4.调试程序

  10. Java类与类的关系、继承与多态、重写与重载

    Java类与类的关系 (1)is-a包括了 继承,实现关系 (2)has-a包括了 关联,聚合,组合关系 (3)use-a包括了 依赖关系 实现关系: 实现指的是一个class类实现interface ...