自绘按钮的问题,创建了一个按钮区域保存在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的坐标对取按钮的区域大小是没关系的,为什么 ??

解决方案 »

  1.   

    按钮的区域在OnInitDialog()中创建好,如下: HRGN r;
    r=CreateRectRgn(0,0,166,51);//创建按钮的区域
    m_Btn1.Create("Btn 1",WS_CHILD | WS_VISIBLE,CPoint(0,0),r,this,IDMYBU_BTN2,2,GetSysColor(COLOR_BTNFACE),
    RGB(0,255,0),RGB(255,0,0),GetSysColor(COLOR_3DDKSHADOW));
    DeleteObject(r);
      

  2.   

    这是微软实现问题。因为不规则图形单独绘制实现有困难,而且每次都不知道用户需求如何。反而Rgn这个类似蒙版功能,是规则图形组合而成的,不规则图形,就比较容易算法实现。
      

  3.   

    那用m_hRgn直接粉刷按理来说
    那用m_hRgn在PaintRgn()函数直接粉刷按理来说应该行的呀...
      

  4.   

    m_hRgn = CreateRectRgn(0, 0, 31, 31);
    CRect box(0, 0, 0, 0);
    if (m_hRgn != 0) 
    CombineRgn(m_hRgn, hRgn, 0, RGN_COPY);
    而且为什么改变m_Rgn所创建的区域对按钮的区域没影响???还有,为什么在PaintRgn()函数中对局部的hRgn获取的区域就是按钮区域,如下: HRGN hRgn = CreateRectRgn(0, 0, 0, 0);
    GetWindowRgn(hRgn);//为什么这样获取的就是按钮的区域????
      

  5.   

    GetWindowRgn函数,是获取你之前SetWindowRgn所设置的那个区域.参考:
    CWnd::GetWindowRgn
    int GetWindowRgn( HRGN hRgn )const;返回值:
    返回值指定了该函数获得的区域的类型。可以是下列值之一: · NULLREGION 区域为空。  
    · SIMPLEREGION 区域是一个简单的矩形。  
    · COMPLEXREGION 区域包括多于一个矩形。  
    · ERROR 发生了错误,区域没有受到影响。参数hRgn窗口区域的句柄。  参数: hRgn 窗口区域的句柄。  说明:
    调用这个成员函数以获得窗口的窗口区域。窗口区域确定了操作系统允许画出窗口的区域。操作系统不会在窗口区域之外显示窗口的任何部分。窗口的窗口区域的坐标是相对于窗口的的左上角的,不是窗口的客户区域。要设置窗口的窗口区域,调用CWnd::SetWindowRgn。
      

  6.   


    那为什么改变HRGN hRgn=CreateRectRgn(0,0,0,0)的坐标对按钮的区域没所谓的呢??例如我改成HRGN hRgn=CreateRectRgn(0,0,31,31),这样获取的按钮的区域是不变的,为什么??
    而且为什么要在PaintRgn()函数中创建一个局部的hrgn,而不能直接用成员变量m_hrgn???
      

  7.   

    1.CreateRectRgn之后你要SetWindowRgn,下次GetWindowRgn才会对应
    2.GetWindowRgn传递的那个hRgn不需要创建
    3.m_hrgn无效很可能是你在什么地方DeleteObject了
      

  8.   


    第一点我做到了。
    第二点的话一定要在PaintRgn()函数中创建,也就是说一样要有HRGN hRgn = CreateRectRgn(0, 0, 0, 0);这条语句,不然就传进出的画刷就粉刷不了区域为什么一定要创建一个局部的呀??实在搞不懂
    第三点我只是在析构函数中DeleteObject m_hrgn;
      

  9.   

    我在OnCreate()函数把SetWindowRgn(m_hRgn, true)注释掉,然后在其他函数函数中都用m_hRgn代替
    hRgn,那样的话又行了哦,又可以粉刷了哦,为什么???
    这个SetWindowRgn(m_hRgn, true);不是一定要的吗???
    int CMybutton::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
    if (CButton::OnCreate(lpCreateStruct) == -1)
    return -1; // assign new region to a window
    m_bNeedBitmaps = true;
    // SetWindowRgn(m_hRgn, true); return 0;
    }