最近比较忙,一直在做项目,感觉有些东西还是没有弄太懂。
最近买了本windows游戏编程的书,感觉是本入门级的书籍,有很多东西看起来都很赏心悦目。也许是作者讲的比较通俗易懂吧。
本来这阵还在看gdi.plus的东西,但没有找到很好的教程,所以很多东西还是一直不能融会贯通。但对于镂空图来说,Gdi plus就不用太费劲了,直接贴上png就搞定了。
对于gdi,我重载了button类。绘图代码如下:
void CMyButton::PaintImg(CDC *pDC)
{
if(m_bmp.m_hObject==NULL)
{
return ;
}
BITMAP bmp;
m_bmp.GetBitmap(&bmp);
//建立内存DC
CDC dcBmp,dcMask,dcOver;
dcBmp.CreateCompatibleDC(pDC);
dcMask.CreateCompatibleDC(pDC);
dcOver.CreateCompatibleDC(pDC);
//载入图片
dcBmp.SelectObject(m_bmp);
dcMask.SelectObject(m_bmpMask);
dcOver.SelectObject(m_bmpOver);
//开始贴图,镂空
pDC->BitBlt(0,0,bmp.bmWidth,bmp.bmHeight,&dcMask,0,0,MERGEPAINT); //蒙版是白底黑图
pDC->SelectObject(m_bmp);
if(m_bOver)
pDC->BitBlt(0,0,bmp.bmWidth,bmp.bmHeight,&dcOver,0,0,SRCAND); //图片是白底彩图
else
pDC->BitBlt(0,0,bmp.bmWidth,bmp.bmHeight,&dcBmp,0,0,SRCAND);
TRACE("over=%d/n",m_bOver);
}
为了使按钮的有效区域与镂空图片的有效像素大小一致,采用了很笨拙的算法得到区域
void CMyButton::SetWndRgn(CDC *pDC)
{
if(m_bmpMask.m_hObject==NULL)
{
return;
}
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
dcMem.SelectObject(m_bmpMask);
BITMAP bt;
m_bmpMask.GetBitmap(&bt);
CRgn rgn,rgnTmp;
rgn.CreateRectRgn(0,0,bt.bmWidth,bt.bmHeight);
int nWidth,nHeight; //循环扣掉蒙版白色的区域
for(nWidth=0;nWidth<bt.bmWidth;nWidth++)
{
for(nHeight=0;nHeight<bt.bmHeight;nHeight++)
{
if(dcMem.GetPixel(nWidth,nHeight)==RGB(255,255,255))
{
rgnTmp.CreateRectRgn(nWidth,nHeight,nWidth+1,nHeight+1);
rgn.CombineRgn(&rgn,&rgnTmp,RGN_XOR);
rgnTmp.DeleteObject();
}
}
}
m_rgn.CreateRectRgn(0,0,1,1);
m_rgn.CopyRgn(&rgn);
SetWindowRgn((HRGN)rgn,TRUE);
}
为了使图片可以在鼠标滑过的时候切换到over图,应该重载该事件,并设定SetCapture(),但此时可能会发现按钮点击后不能够很好的切换,解决的办法是在单击UP的事件里,重新设定SetCapture()。