原文链接: http://blog.csdn.net/jiftlixu/article/details/4893505
今天从CButton派生了一个类CUIButton,主要用于自绘,按照基本的流程,重写DrawItem方法。
步骤如下:点击CUIButton按钮,在右键弹出菜单中选择“add windows message Handler",
找到DrawItem,为其添加消息映射,添加的代码如下:
void CUIButton::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
结果在使用到CUIButton的地方用SubClassDlgItem就会出问题。
后来调试发现,不应该按照上面的添加此消息的映射,而是为CUIButton类重写DrawItem函数,添
加方法:
在类CUIButton右键,在弹出菜单中选择"Add Virtual Function",弹出的添加虚函数框中选
择"DrawItem",向导为我们生成的代码如下:
void CUIButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
在这里添加所需的自绘代码就ok了
附: how to implement control to self-draw
1、从CButton类派生自己的CUIControl类
2、借助于MFC向导生成工具,为期添加虚函数DrawItem()和OnEraseBkgnd()。
注意:DrawItem()是控件重定义的函数,不是OnDrawItem()。
3、在DrawItem()中近控件的自绘处理,这里给出一个实例代码,用于一个自定义Button,在
Button上面绘图:
void CUIButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your message handler code here and/or call default
//CButton::OnDrawItem(nIDCtl, lpDrawItemStruct);
int nCxIcon = ::GetSystemMetrics(SM_CXICON);
int nCyIcon = ::GetSystemMetrics(SM_CYICON);
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(pDC,nCxIcon,nCyIcon);
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
CBitmap *pOldBitmap = (CBitmap *)dcMem.SelectObject(bitmap);
ASSERT(pOldBitmap);
HICON hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
ASSERT(hIcon);
CRect rcClient;
GetClientRect(&rcClient); // get the button's rect
dcMem.StretchBlt(0,0,nCxIcon,nCyIcon,pDC,2,2,rcClient.Width() - CX_SHADOW - 4,
rcClient.Height() - CY_SHADOW - 4,SRCCOPY);
dcMem.DrawIcon(0,0,hIcon);
// draw border around icon
CPen pen;
pen.CreateStockObject(BLACK_PEN);
ASSERT(pDC != NULL);
CPen* pPenOld = pDC->SelectObject(&pen);
pDC->Rectangle(0, 0, rcClient.Width()-CX_SHADOW, rcClient.Height()-CY_SHADOW);
if (pPenOld)
pDC->SelectObject(pPenOld);
//pDC->StretchBlt(0,0,80,80,&dcMem,0,0,nCxIcon,nCyIcon,SRCCOPY);
pDC->StretchBlt(2,2,rcClient.Width() - CX_SHADOW - 4,rcClient.Height() - CY_SHADOW - 4,&dcMem,0,0,nCxIcon,nCyIcon,SRCCOPY);
}
4、为OnEraseBkGround()添加代码。这里很简单,直接返回True即可:
BOOL CUIButton::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return TRUE;
//return CButton::OnEraseBkgnd(pDC);
}
5、在你的对话框中使用CUIButton按钮,首先在dialog资源中添加一个按钮(CButton)。
6、在对话框类的头文件中定义一个成员CUIButton m_CtlUIBtn;注意变量的类型是CUIButton而
不是CButton
7 、在OnInitDialog中用SubClass技术:
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_CtlUIButton.SubclassDlgItem(IDC_UI_BUTTON,this);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
that is OK!