自绘控件和hRgn的有关问题
自绘控件和hRgn的问题
自绘按钮的问题,创建了一个按钮区域保存在CMybutton类的成员变量m_hRgn中,如下:
class CMybutton : public CButton{
...
private:
HRGN m_hRgn;
...
};
BOOL CMybutton::Create(LPCTSTR lpszCaption, DWORD dwStyle, const CPoint point, const HRGN hRgn, CWnd* pParentWnd, UINT nID)
{
// store region in member variable
DeleteObject(m_hRgn);
m_hRgn = CreateRectRgn(0, 0,31,31);
//改m_hRgn的坐标也没关系的,为什么??
CRect box(0, 0, 0, 0);
if (m_hRgn != 0)
CombineRgn(m_hRgn, hRgn, 0, RGN_COPY);
// make sure that region bounding rect is located in (0, 0)
GetRgnBox(m_hRgn, &box);
OffsetRgn(m_hRgn, box.left, box.top);
GetRgnBox(m_hRgn, &box);
// update position of region center for caption output
m_CenterPoint = CPoint(box.left+box.Width()/2 , box.top + box.Height() /2);
box.OffsetRect(point);
return CButton::Create(lpszCaption, dwStyle, box, pParentWnd, nID);
}
然后在CMybutton::PaintRgn()函数中粉刷 按钮区域,如下:
void CMybutton::PaintRgn(CDC * pDC, CDC * pMemDC, CBitmap * pBitmap, COLORREF color, CRect * pRect, BOOL bEnabled, BOOL bSunken)
{
// c创建位图
pBitmap -> CreateCompatibleBitmap(pDC, pRect -> Width(), pRect -> Height());
CBitmap * pOldBitmap = pMemDC -> SelectObject(pBitmap);
// 准备路径
HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
GetWindowRgn(hRgn);
// 用传进来的颜色填充按钮路径区域
HBRUSH hBrush = CreateSolidBrush(color);
pMemDC -> FillSolidRect(pRect, RGB(250,250, 250));
FillRgn(pMemDC -> GetSafeHdc(), m_hRgn, hBrush);
DeleteObject(hBrush);
// 绘制按钮标题及3D边框
DrawButtonCaption(pMemDC -> GetSafeHdc(), pRect, bEnabled, bSunken);
FrameRgn3D(pMemDC -> GetSafeHdc(), m_hRgn, bSunken);
// 释放资源
DeleteObject(hRgn);
pMemDC -> SelectObject(pOldBitmap);
}
我不明白的是,为什么不能直接用画刷粉刷m_hRgn,这样的话粉刷不了的,为什么??而是要创建一个局部的hRgn,然后粉刷...而且改hRgn的坐标对取按钮的区域大小是没关系的,为什么 ??
------解决方案--------------------
这是微软实现问题。
因为不规则图形单独绘制实现有困难,而且每次都不知道用户需求如何。
反而Rgn这个类似蒙版功能,是规则图形组合而成的,不规则图形,就比较容易算法实现。
------解决方案--------------------
GetWindowRgn函数,是获取你之前SetWindowRgn所设置的那个区域.
参考:
CWnd::GetWindowRgn
int GetWindowRgn( HRGN hRgn )const;
返回值:
自绘按钮的问题,创建了一个按钮区域保存在CMybutton类的成员变量m_hRgn中,如下:
class CMybutton : public CButton{
...
private:
HRGN m_hRgn;
...
};
BOOL CMybutton::Create(LPCTSTR lpszCaption, DWORD dwStyle, const CPoint point, const HRGN hRgn, CWnd* pParentWnd, UINT nID)
{
// store region in member variable
DeleteObject(m_hRgn);
m_hRgn = CreateRectRgn(0, 0,31,31);
//改m_hRgn的坐标也没关系的,为什么??
CRect box(0, 0, 0, 0);
if (m_hRgn != 0)
CombineRgn(m_hRgn, hRgn, 0, RGN_COPY);
// make sure that region bounding rect is located in (0, 0)
GetRgnBox(m_hRgn, &box);
OffsetRgn(m_hRgn, box.left, box.top);
GetRgnBox(m_hRgn, &box);
// update position of region center for caption output
m_CenterPoint = CPoint(box.left+box.Width()/2 , box.top + box.Height() /2);
box.OffsetRect(point);
return CButton::Create(lpszCaption, dwStyle, box, pParentWnd, nID);
}
然后在CMybutton::PaintRgn()函数中粉刷 按钮区域,如下:
void CMybutton::PaintRgn(CDC * pDC, CDC * pMemDC, CBitmap * pBitmap, COLORREF color, CRect * pRect, BOOL bEnabled, BOOL bSunken)
{
// c创建位图
pBitmap -> CreateCompatibleBitmap(pDC, pRect -> Width(), pRect -> Height());
CBitmap * pOldBitmap = pMemDC -> SelectObject(pBitmap);
// 准备路径
HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
GetWindowRgn(hRgn);
// 用传进来的颜色填充按钮路径区域
HBRUSH hBrush = CreateSolidBrush(color);
pMemDC -> FillSolidRect(pRect, RGB(250,250, 250));
FillRgn(pMemDC -> GetSafeHdc(), m_hRgn, hBrush);
DeleteObject(hBrush);
// 绘制按钮标题及3D边框
DrawButtonCaption(pMemDC -> GetSafeHdc(), pRect, bEnabled, bSunken);
FrameRgn3D(pMemDC -> GetSafeHdc(), m_hRgn, bSunken);
// 释放资源
DeleteObject(hRgn);
pMemDC -> SelectObject(pOldBitmap);
}
我不明白的是,为什么不能直接用画刷粉刷m_hRgn,这样的话粉刷不了的,为什么??而是要创建一个局部的hRgn,然后粉刷...而且改hRgn的坐标对取按钮的区域大小是没关系的,为什么 ??
------解决方案--------------------
这是微软实现问题。
因为不规则图形单独绘制实现有困难,而且每次都不知道用户需求如何。
反而Rgn这个类似蒙版功能,是规则图形组合而成的,不规则图形,就比较容易算法实现。
------解决方案--------------------
GetWindowRgn函数,是获取你之前SetWindowRgn所设置的那个区域.
参考:
CWnd::GetWindowRgn
int GetWindowRgn( HRGN hRgn )const;
返回值: