自己动手做按钮

现在网上发布的自制按钮很多,实际上其制作方法都很类似,以下给出几个关键步骤,具体细节你大可以发挥你的想象力,制作出你想要的各种按钮。

一、用ClassWizard生成一个新类,名字假设起为CMyButton,基类选为CButton;

二、在新类中用ClassWizard添加函数:PreSubclassWindow()、DrawItem()、OnMouseMove()、OnLButtonDown()、OnLButtonUp();

① PreSubclassWindow()函数在绘制按钮前执行,在这里我只做了一个工作:
void CMyButton::PreSubclassWindow()
{
CButton::PreSubclassWindow();
ModifyStyle( 0, BS_OWNERDRAW ); //设置按钮属性为自画式
}
这样你就无需在放置按钮时非得设置按钮属性为“OwnerDraw”了。

② DrawItem()函数是最重要的函数,所有自己绘制按钮的工作都在这里进行,它的作用类似于View类中的OnDraw()函数。
例:
void CMyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC *pDC = CDC::FromHandle( lpDrawItemStruct->hDC );
m_ButRect = lpDrawItemStruct->rcItem; //获取按钮尺寸
GetWindowText( m_strText ); //获取按钮文本
CPoint m_ptCentre = m_ButRect.CenterPoint(); //求按钮中心点
CSize Extent = pDC->GetTextExtent( m_strText ); //求文本尺寸
m_textPt = CPoint( m_ptCentre.x - Extent.cx/2,
m_ptCentre.y - Extent.cy/2 ); //设置文本坐标
int nSavedDC = pDC->SaveDC();
VERIFY( pDC );

if( !(::GetWindowLong(m_hWnd,GWL_STYLE) & WS_DISABLED) )
{
if( !b_Flag )
{
NormalButton( pDC ); //画正常按钮
}
else
{
PassButton( pDC ); //画鼠标经过时的按钮
}
}
else
{
LockButton( pDC ); //画锁定的按钮
}

pDC->RestoreDC( nSavedDC );
}
其中的变量在CMyButton.h中定义:
BOOL b_Flag; //按钮状态(false-正常,true-当前)
BOOL b_InRect; //鼠标进入标志
CString m_strText; //按钮文字
COLORREF m_ForeColor; //文本颜色
COLORREF m_BkColor; //背景色
COLORREF m_LockForeColor; //锁定按钮的文字颜色
CRect m_ButRect; //按钮尺寸
CPoint m_textPt; //文字坐标(左上角)
具体绘制按钮的函数是另外定义的,只要你会用VC绘图,就可随心所欲的画出你想要的任何形态按钮,这里我定义了三种情况的按钮:
绘制正常状态下的按钮:
void CMyButton::NormalButton(CDC *pDC)
{
……
}
绘制鼠标进入按钮区域后的按钮:
void CMyButton::PassButton(CDC *pDC)
{
……
}
绘制锁定(变灰)状态下的按钮:
void CMyButton::LockButton(CDC *pDC)
{
……
}
有些人还希望绘制“鼠标按下时的按钮”、“拥有焦点的按钮”使效果更好,可在相应位置做如下修改:
int b_Flag; //0-正常、1-鼠标进入、2-鼠标按下、3-拥有焦点

switch(b_Flag)
{
case 0:画正常按钮;break;
case 1:画鼠标进入后的按钮;break;
case 2:画鼠标按下后的按钮;break;
case 3:画拥有焦点的按钮;break;
}
而b_Flag的值在鼠标消息函数中进行修改。

③ OnMouseMove()函数用于判定鼠标是否在按钮上:
void CMyButton::OnMouseMove(UINT nFlags, CPoint point)
{
CButton::OnMouseMove(nFlags, point);

if( !b_InRect || GetCapture()!=this ) //鼠标进入按钮
{
b_InRect = true;
SetCapture();
b_Flag = true;
Invalidate(); //重绘按钮
}
else
{
CRect rc;
this->GetClientRect( &rc );
if ( !rc.PtInRect(point) ) //鼠标离开按钮
{
b_InRect = false;
ReleaseCapture();
b_Flag = false;
Invalidate(); //重绘按钮
}
}
}
变量b_InRect用于判定鼠标是进入了按钮区还是从按钮中离开,b_Flag决定了绘制何种按钮,Invalidate()函数调用DrawItem()函数重绘按钮。

④ OnLButtonDown()函数和OnLButtonUp()函数与OnMouseMove()函数类似,用于鼠标按下和弹起时重绘按钮。
void CMyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
b_Flag = false;
if (GetFocus()!=this)
{
this->SetFocus();
}
CButton::OnLButtonDown( nFlags, point );
Invalidate(); //重绘按钮
}
本例中我在鼠标按下时绘制的是“正常状态”的按钮。
void CMyButton::OnLButtonUp(UINT nFlags, CPoint point)
{
b_Flag = true;
if (GetFocus()!=this)
{
this->SetFocus();
}
CButton::OnLButtonUp( nFlags, point );
Invalidate(); //重绘按钮
}
我在鼠标弹起后绘制的是“鼠标进入按钮区状态”的按钮。

三、在CMyButton类的构造函数中设置变量的初值:
CMyButton::CMyButton()
{
b_InRect = false;
b_Flag = false;
}
这样一个新的按钮类的核心部分就完成了

时间: 01-17

自己动手做按钮的相关文章

动手做第一个Chrome插件

Chrome插件是令人惊讶的简单,一旦你弄懂它的工作和实现原理.它是由一部分HTML,一部分Js,然后混合了一个叫做manifest.json的Json文件组合而成的整体.这意味着你可以使用你最擅长的js框架去实现它. 如果你还是一个Chrome插件的新手并且想尝试写一个的话,下面的文章将会带领大家并且尝试让大家理解Chrome插件的工作机制.这篇文章将会讲述每一块架构,以及相互之间的联系和插件的一般化形式. 架构 Chrome插件中的文件大体上可以分成2部分:Chrome插件中确确实实存在的文

自己动手做个智能小车(3)

自己动手做个智能小车(3) --让小电脑运行程序吧 通了电源,也有了初步的规划,我们就把主芯片给接上,并让其工作起来. 这个主芯片就是89C52单片机,有人说,单片机没学过啊,怎么没,没关系,在里,我们就从最简单的入手,然后再慢慢加功能.我们知道学个新程序,一般从HelloWord开始,那单片机同样,也从其本的开始. 51单片机,有40个引脚,其中,芯片从一个U口的左侧开始计数,然后一圈编号,40脚与20脚接电源的正负极.其中,1~8 0~17 39~32 1~28 为单片机的P1 P3 P0

自己动手做AI:Google AIY开发工具包解析

2018年国际消费性电子展(CES)上,最明显的一个趋势是Amazon与Google的语音技术进驻战,如AmazonAlexa进驻到Acer笔电内,Google Assist进驻到KIA汽车内,其他如智能电视.智能喇叭,乃至传统数字录放机TiVo都成为抢占进驻的对象. Google Assistant 语音识别进驻大战 这是一波新的抢滩战,过去Google具有PC上网的搜寻入口优势,使Google赚取庞大的广告中介收益.但上网的形式在改变,包含走动时对手机「说」.客厅躺卧时对智慧喇叭「说」.或开

自己动手做聊天机器人教程

自己动手做聊天机器人 一-涉及知识(2016-06-09) 自己动手做聊天机器人 二-初识NLTK库(2016-06-10) 自己动手做聊天机器人 三-语料与词汇资源(2016-06-12) 自己动手做聊天机器人 四-何须动手?完全自动化对语料做词性标注(2016-06-17) 自己动手做聊天机器人 五-自然语言处理中的文本分类(2016-06-21) 自己动手做聊天机器人 六-教你怎么从一句话里提取出十句话的信息(2016-06-22) 自己动手做聊天机器人 七-文法分析还是基于特征好啊(20

自己动手做个智能小车(1)

自己动手做个智能小车(1) --介绍及工具材料准备 目前物联网发展很迅速,软硬结合也越来越流行.对硬件有些兴趣的我,也想来做点业余玩具. 这是个业余小作品,可以学习一些基本硬件.单片机,底层软件,Android编程等知识,同时不失趣味性. 直接上图: 怎么每张图有个手机?-- 哈哈那是遥控器. 介绍: 这个小车是一个三轮车,为啥采用三轮:方便.灵活.控制简单,比如要转个弯,只需要把这边的轮子速度降下来,就转过去了:还可以原地旋转,两个轮子速度相同,方向相反即可,这是四轮车办不到的. 问,边上的手

不使用物理引擎,自己动手做真实物理的模拟投篮游戏

最近打算做一个2D投篮游戏,由于对于BOX2D等物理引擎并不熟悉,加之一开始低估了游戏所需要的碰撞检测复杂度,认为仅仅涉及4面墙,篮球,篮板,篮筐,篮网的碰撞检测并不复杂.因此决定自己实现所需要的碰撞检测.结果实际开始做时磕磕碰碰遇到了许多问题. 1.如何实现像素级碰撞检测. as3原生的hitTestObject只能检测矩形,对于圆形等其他形状就不适用了:打算用hitTestPoint来检测篮球与篮板四个边角,篮筐前后框点,在实践尝试中发现是有问题的,在涉及物体旋转的情况下检测就不精确了.因此

自己动手做个智能小车(5)

自己动手做个智能小车(5) --用程序来控制轮子 PWM控制电路完工了,接下来得把电路接到单片机,由单片机进行控制了.回想电路图: 这个图中,输入有3根组,A,B,C,其中,A入口,我们可以当成PWM控制线,B,C为正反转.停止控制线,整个状态可以罗列为下面表格: A控制 B控制 C控制 Q1 Q2 Q3 Q4 电机状态 X 0 0 0/导通 0/导通 0/截止 0/截止 刹车 PWM 1 0 1/截止 0/导通 PWM 0/截止 正转 PWM 0 1 0/导通 1/截止 0/截止 PWM 反转

自己动手做个智能小车(2)

自己动手做个智能小车(2) --基本布局及电源部份 上一章中,我们逻列出所有需要的零件,接下来就是我们开始拼装的时候了.电路图... 没有, 没有完整的,我们就一步步做吧,纯手工,焊到哪就是哪,不通了就飞线(注:正常电路从板子下面走,但如果实在有交叉过不去时,就可以在上面用一导线直接相联,叫飞线,正式design好的板子一般都不用飞的咯). 虽说焊到哪是哪,但是还是得稍微布局设计一下. 观察一下小车,电机分布在两边,前面一轮子,后面空, 所以后面空地方肯定不能压重物,不然会压翻掉. 电路板100

cvCreateTrackbar 用进度条做按钮

核心函数: cvCreateTrackbar 程序: 代码: #include "cv.h" #include "cxcore.h" #include "highgui.h" #include <iostream> int ButtonValue=-1; IplImage* src=cvLoadImage("e:\\picture\\11.jpg"); void ButtonCallback(int positio