Button自绘恐怕是WTL-自绘系列中最简单的一个了。下图所示是我依照win7的登录界面做的一个对话框,里面用刷新按钮演示按钮自绘。大家可以从文章最后的链接下载工程源码,按自己喜好画出完整的一个界面。
如本系列文章开头所述,我们在绘制时要找到控件的DC和Rect。按钮自绘也是如此。原理与WTL-Menu自绘是一样的。唯一不同的是Button自绘时,windows不发送WM_MEASUREITEM消息,我们也就不用响应它了。响应好WM_DRAWITEM消息就行了。
代码如下:
LRESULT CMainDlg::OnDrawItem( UINT uMsg,WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
LPDRAWITEMSTRUCT lpdis =(LPDRAWITEMSTRUCT)lParam;
if (lpdis->CtlID != IDC_BUTTON1)
{
return FALSE;
}
CDCHandle hdc = lpdis->hDC;
CRect itemRect = lpdis->rcItem;
CDC memDc;
memDc.CreateCompatibleDC(hdc);
CBitmap bmpBtn;
if (lpdis->itemState & ODS_SELECTED)
{
bmpBtn.LoadBitmap(IDB_BMP_NOR);
}
else
{
bmpBtn.LoadBitmap(IDB_BMP_HOVER);
}
HBITMAP hOldBmp =memDc.SelectBitmap(bmpBtn);
CSize bmpSize;
bmpBtn.GetSize(bmpSize);
hdc.StretchBlt(itemRect.left, itemRect.top,itemRect.Width(), itemRect.Height(), memDc, 0, 0,bmpSize.cx, bmpSize.cy,SRCCOPY);
TCHAR tchWindowText[16] = {0};
::GetWindowText(lpdis->hwndItem,tchWindowText, _countof(tchWindowText));
hdc.SetBkMode(TRANSPARENT);
hdc.DrawText(tchWindowText,_tcslen(tchWindowText), itemRect, DT_SINGLELINE|DT_CENTER|DT_VCENTER);
memDc.SelectBitmap(hOldBmp);
return TRUE;
}
本例画的是一个双态按钮(正常、被按下),更丰富一点儿的是三态(正常、鼠标悬停、被按下),甚至四态(三态基础上,加一个输入焦点)。大家可以按个人喜好选择,本示例工程就不做那么多功能了,主要让大家快速明白Button自绘的要点就行了。
判断鼠标是否悬停在按钮上,需要捕捉鼠标的位置,google一下能找到很多现成的代码,都是比较套路化的东西,大同小异,本文就不介绍了。
按钮自绘就介绍到这儿。结束。
工程源码链接:http://pan.baidu.com/s/1dDy5htv