MFC自己做按钮(自定义Button)[转]
最近老板要玩花哨,要做“糖豆”按钮。
先是下载了个CrystalButton,现在还没破解的2.8,不过PCHome上有2.7的破解版,下下来用还不错。
老板觉得挺满意,说:这个软件不错,大家没事做按钮玩啊!◎_◎崩溃!
自己做了一套风格的按钮,还行,可是不会在MFC上面贴。
下面搜集了一个不错的教程,自己写的时候用重载函数用了网上其他的例子。跟大家分享
(代码排版原来是好的,贴上来就成这样了,将就着看咯)
--------------------------------------------------------------
创建一个名叫CColorButton的类来学习这种方法。
虽然这是一个功能非常简单的类,通过调用成员函数ChangeColor可改变其颜,鼠标点中时则高亮边框表示选中。
但利用这种思路我们只需添加几个数据成员和重载一个函数就可以方便地实现你所需要的功能。
在创建这个类之前,我们必须先了解WM_DRAWITEM消息。
当按钮、组合框、列表框或菜单的某一视觉状况发生变化时,系统就会发送一条WM_DRAWITEM消息给这些控制的拥有者窗口。
这个消息的wParam指出这个控制的 id 号,而IParam则是一个指向DRAWITEMSTRUCT结构的指针,该结构存放有关要绘制的项的信息以及绘制所需的类型。
DRAWITEM STRUCT结构具有如下格式。
typedef struct tagDRAWITEM STRUCT{
UINT CtlType; // 控制类型
UINT CtlID; // 控制的ID号
UNIT itemID; //菜单项的索引
UINT itemAction; // 说明需要的绘图操作
UINT itemState; // 指明绘图后的可见状态
HWND hwndItem; // 控制的窗口句柄
HDC hDC; // 相关的设备环境
RECT rcItem; // 被画控制的边框
DWORD itemData; // 指定与菜单项相联系的应用程序定义的32位值
}DRAWITEMSTRUCT;
其中itemAction 和 itemState决定了需要的绘图操作。itemAction 说明需要的绘图操作,可为下列值中的一个或多个;
值 含 义
ODA_DRAWENTIRE 需要重来全部控制时 怎样写代码 自己做编程
ODA_FOCUS 获得或失去输入焦点
ODA_SELECT 选择状态改变
itemState指明当前绘图动作发生之后,项的可见状态。下面是状态标志:
值 含 义
ODS_CHECKD 只用于菜单中
ODS_DISABLE 该项被屏蔽
ODS_FOCUS 该项具有输入焦点
ODS_GRAYED 只用于菜单中
ODS_SELECT 该项处于被选中状态
用VC++实现自绘按钮控制
利用VC++编程会发现,当按钮控制接收到WM_DRMAWITEM消息时会调用Cbotton类的DrawItem函数。
因此我们要做的就是利用C++的多态性通过重载CButton类的Drawitem函数来响应MW_DRAWITEM消息。
下面我们就实际构造一个CColorButton类。
class ccolorButton:public CButton
{
private:
COLORREF m_color:
public:
CColorButton():CButton(),m_color(0){}; //构造函数
void ChangeColor(COLORREF color); //改变颜
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);//重载的函数
};
//重载的虚函数
void CColorButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC dc;
dc.Attach(lpDrawItemStruct->hDC); //得到绘制的设备环境CDC
VERIFY( lpDrawItemStruct->CtlType==ODT_BUTTON);
if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE)
{
//重绘整个控制
CBrush brush(m_Color);
dc.FillRect(&(lpDrawItemstruct->reItem), &brush);
}
if ((lpDrawItemStruct->itemstate & ODS_SELECTED) &&
(lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
{
//选中了本控制===>高亮边框
COLORREF fc=RGB(255_GetRvalue(m_color), 255_GetGValue(m_color), 255_GetBValue(m_color));
CBrush brush(fc);
dc.FrameRect(&(lpDrawItemStruct->rcItem), &brush );
}
if (!(lpDrawItemStruct->itemState & ODS_SELECTED) &&
(lpDrawItemStruct->itemAction & ODA_SELECT))
{
//控制的选中状态结束===>去掉边框
CBrush brush(m_color);
dc.FrameRect(&lpDrawItemStruct->rcItem, &brush);
}
dc.Detach();
}
//用于改变颜的成员函数
void CColorButton::ChangeColor(COLORREF color)
{
CRect rect;
m_color=color;
GetClientRect(&rect);
}
m_colorChangeColor(COLORREF color)color,WM_DRAWITEM上面代码中数据成员m_color和来保存按钮的颜。
ChangeColor(COLORREF color)函数负责改变按钮颜值为color,然后通过使控制的客户
区无效而激发WM_DRAWITEM消息。
现在这个按钮控制类就算搭好了。下面我们把它加入到对话框中来试验一下(中) 用VC++实现自绘按钮控制
1.首先通过AppWizard创建一个单文档的应用。
2.紧接着启动AppStadio创建一个对话框。添加一个按钮控制,
并将其ID设置为 IDC_COLORBUTTON。最后一定要记住将push Button Properties对话框中的Owner Draw检查框置上检查标志。
3.在AppStadio内运行ClassWizzard来产生CTestDialog类。
然后在CTestdialog类中加入数据成员,在CTestDialog类说明加入如下的private型数据成员:
private:
CColorButton m_ColorButton;
4.现在剩下的问题是到底要怎样才能使m_ColorButton的DrawItem函数能响应系统发往ID值为IDC_COLORBUTTON的按钮控制的WM_DRAWITEM消息。
这时就要用到CWnd类的成员函数BOOL CWnd::SubclassDlgItem(UINT nID,CWnd *pParent)。
通过调用这个函数,我们可以动态地接管从对话框模板产生的控制,并把它隶属于CWnd对象。
即用当前的CWnd对象接管发向隶属于pParent的ID号为nID的控制的一切消息。
对于按钮控制而言,它把当前的按钮控制的位置和大小也清成和nID对应的按钮控制一样。
于是我们对CTestDialog的源文件进行如下的编辑:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论