实现类QQ的编辑框
第一步,平面效果。Windows系统有几个消息专门用来处理Windows组件的边框部位,那就是WM_NCCALCSIZE和WM_NCPAINT这两个消息,从消息名字看来NC这个就代表着No Client也就是非客户区域,NCCALCSIZE也就是说明了计算非客户区和客户区的消息,而WM_NCPAINT消息,也就是非客户区域的绘制触发消息,所以就要截获这两个消息来绘制自己的边框取代Windows系统的绘制方式。在Delphi中拦截系统消息非常简单,直接在消息的处理过程后面跟一个message关键字,然后加上消息常量就可以了!不像MFC要搞消息映射那么麻烦,声明代码如下
procedure WMNcCalcSize(var msg: TWMNCCalcSize);message WM_NCCALCSIZE;
msg参数为TWMNCCalcSize结构,其实也就是TMessage结构,可以相互转化的,这个结构为

TWMNCCalcSize = packed record
Msg: Cardinal;
CalcValidRects: BOOL;
CalcSize_Params: PNCCalcSizeParams;
Result: Longint;
end;

这个结构体中msg就是WM_NCCALCSize的消息
CalcValidRects表示是否计算客户区的有效区域,如果为True,此时CalcSize_Params为一个rgrc: array[0..2] of TRect;的结构体,
rgrc[0]指向的是新的windows的RECT,rgrc[1]是之前的windows的RECT,rgrc[2]传入的是move/resize前的client rect。
如果本值为false的时候,指向的rect和TRUE时的rgrc[0]功能相同
CalcSize_Params是一结构体,这个结构体上面介绍CalcValidRects已经说明,Result指定消息返回值
关于本消息的详细解释清参考MSDN或者这个帖子,然而本篇,我们可以不用这个拦截这个消息,因为Delphi的Edit有一个BorderStyle属性默认为bsSingle也就是是有边框的,所以我们只用拦截WM_NCPaint这个消息,然后自己处理边框的绘制就OK了。
第二步,平面效果绘制过程,也不多说了,直接给出代码更加直观,下面给出代码实现过程

procedure TEdit1.WMNCPAINT(var msg: TWMNCPaint);
var
DC: HDC;
BorderBrush: HBRUSH;
R: TRect;
begin
DC := GetWindowDC(Handle);
try
SetRect(R,0,0,Width,Height);
if FMouseIn then
begin
BorderBrush := CreateSolidBrush(RGB(123,228,255));//创建画刷
FrameRect(Dc, R, BorderBrush);//绘制外部的高亮边框
DeleteObject(BorderBrush);
InflateRect(R,-1,-1);
end
else
begin
InflateRect(R,-1,-1);
BorderBrush := CreateSolidBrush(ColortoRGB(Color));
FrameRect(Dc, R, BorderBrush);//这个是因为如果鼠标不在上面,就要用本身的颜色填充内部线框
DeleteObject(BorderBrush);
InflateRect(R,1,1);
end;
BorderBrush := CreateSolidBrush(RGB(78,160,209));
FrameRect(Dc, R, BorderBrush);//绘制默认的边线框
DeleteObject(BorderBrush);
finally
ReleaseDC(Handle,DC)
end;
end;

这个绘制过程就完成了,但是这个还不够,运行就会发现,此时只有一个平面效果,鼠标移动上去和离开没有任何效果的,所以此时还要加上鼠标的处理效果,有两个消息CM_MOUSEENTER和CM_MOUSELEAVE表示鼠标进入控件和鼠标离开控件时候触发!所以我们拦截这两个消息,然后鼠标进入的时候改变一个状态,然后发送一个重新绘制边线框的消息让它触发WM_NCPaint消息,于是我实现一个过程发送边框重绘消息
procedure TEdit1.InvalidateNC;
begin
if Parent = nil then Exit;
SendMessage(Handle, WM_NCPAINT, 0, 0);
end;
,然后就是两个鼠标消息的处理了

procedure TEdit1.CMMouseEnter(var msg: TMessage);
begin
inherited;
FMouseIn := True;
InvalidateNC;
end; procedure TEdit1.CMMouseLeave(var msg: TMessage);
begin
inherited;
FMouseIn := False;
InvalidateNC;
end;

实现过程都很简单仅仅是发送一个WM_NCPAINT消息而已。
现在我们看看实现效果
,可以试试去掉系统的皮肤之后是个什么效果,另外我这个颜色已经写死了,有兴趣的可以试试换换颜色!另外,可以试试WM_NCCALCSIZE中处理一下,然后看看效果!
实现类QQ的编辑框的更多相关文章
- 【MFC】MFC DLEdit 设计属于自己的编辑框_鼠标悬停
MFC DLEdit 设计属于自己的编辑框 2012-02-04 13:00 by 捣乱小子, 3543 阅读, 5 评论, 收藏, 编辑 起因 无意间看到了大牛们写的自定义编辑框控件,于是找了个时间 ...
- MFC编程入门之二十一(常用控件:编辑框Edit Control)
上一节讲了静态文本框,本节讲的是编辑框(Edit Control)同样是一种很常用的控件,我们可以在编辑框中输入并编辑文本.在前面加法计算器的例子中已经演示了编辑框的基本应用.下面具体讲解编辑框的使用 ...
- MFC 编辑框中字体大小改变,行高不能改变,只能显示一半的问题,已解决。
CKagulaCEdit是CEdit的一个继承类,m_edit的CKagulaCEdit类型的一个变量 调用的时候,是这样的: 编辑框中字体大小改变,行高不能改变,只能显示一半的问题,问题如下: 这时 ...
- PropertyGrid—为复杂属性提供下拉式编辑框和弹出式编辑框
零.引言 PropertyGrid中我们经常看到一些下拉式的编辑方式(Color属性)和弹出式编辑框(字体),这些都是为一些复杂的属性提供的编辑方式,本文主要说明如何实现这样的编辑方式. 一.为属性提 ...
- 积累的VC编程小技巧之编辑框
1.如何让对话框中的编辑框接收对话框的消息 ////////////////////////////////////////////////// 如何让对话框中的CEdit控件类接收对话框的消息/// ...
- [Python] wxPython 编辑框组件学习总结 (原创)
1.总结 1.常用4种 编辑框 的构造 1.普通编辑框 单行输入的简单编辑框 (?为所在框的对象,同下) self.textBox = wx.TextCtrl(parent = ?) 2.密码编辑框 ...
- MFC控件编程之 按钮编辑框.静态文本的使用,以及访问控件的七种方法.
MFC控件编程之 按钮编辑框.静态文本的使用以及访问控件的七种方法. 一丶按钮.静态文本的通用属性. 他们都有一个属性.就是可以输入标题内容.以及可以自定义控件ID. 创建一个MFC Dlg对话框. ...
- Duilib Edit编辑框禁止输入中文的方法
转载:http://www.myexception.cn/vc-mfc/300749.html 编辑框是供用户输入的,但有时候我们要限制用户输入的内容,比如我们不让用户输入中文,只能输入字符和数字,因 ...
- VC++实现编辑框输入提示效果
编辑框在第一次输入时最好给出一个虚拟的输入提示信息文本,这样的效果更佳友好.,我在编辑框添加灰色提示字(html+VC)一文中简单介绍了一些方法,但是效果欠佳. 原始的编辑框CEdit类没有这样的功能 ...
随机推荐
- Spring Boot 揭秘与实战(七) 实用技术篇 - StateMachine 状态机机制
文章目录 1. 环境依赖 2. 状态和事件 2.1. 状态枚举 2.2. 事件枚举 3. 状态机配置4. 状态监听器 3.1. 初始化状态机状态 3.2. 初始化状态迁移事件 5. 总结 6. 源代码 ...
- jquery 获取访问当前页面的开源设备信息
<!DOCTYPE html> <html> <head> <title>测试js</title> <meta http-equiv= ...
- [LeetCode&Python] Problem 242. Valid Anagram
Given two strings s and t , write a function to determine if t is an anagram of s. Example 1: Input: ...
- 关于Java堆、栈和常量池的详解
在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译 ...
- 打开视图 :1449 - the user specified as a definer ('root'@'%')does not exist
从一个数据库数据迁移到本地localhost 程序在调用到数据库的视图时报错,直接在数据库中打开视图时也报错,类似: mysql 1449 : The user specified as a ...
- css的标准模型和低版本的IE的盒子模型有什么不同?
1. css的盒子模型:外边距(margin).内边距(padding).边界(border).内容区(width和height) 标准的css盒子模型与低版本的ie盒子模型的不同:宽高不一样 标准的 ...
- 什么是 JVM
什么是 JVM 先来看下百度百科的解释: JVM 是 Java Virtual Machine(Java 虚拟机)的缩写,JVM 是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算 ...
- CentOS右键菜单添加新增文件命令
进入模板文件夹, 增加空白文件即可. cd /home/tom/Templatesvi text01.txt //新增一个名为text01的文本文件. :wq //保存退出. 另外可以用LibreOf ...
- EasyUI datagrid 查询、设置、提交 三
查询 $(“#grid”).datagrid(“load”,{ a: $('#id').val(),b :$('#text').val() }); {} 里面可以 是序列化参数 $(“#grid ...
- 《DSP using MATLAB》Problem 6.3
天不亮又醒了,拍了张景象,这就是黎明前的黑暗吗