自绘按钮的问题,创建了一个按钮区域保存在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的坐标对取按钮的区域大小是没关系的,为什么 ??
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的坐标对取按钮的区域大小是没关系的,为什么 ??
解决方案 »
- 关于非模态对话框的问题
- sqldmo.dll和sqldmo.rll有和不同
- 关于用CFileDialog打开多文件的问题~
- 一个有些难度的问题,如果解决,保证送分100。在线等,如果需要更多,还可多给
- *如何在单文档中实现多视之间的切换*
- 有关windows核心编程中的问题
- Debug时无错误提示,Release时却有个警告,大家帮我看看是什么意思
- 如何在捕捉编辑框的“回车”事件(消息)?
- 请问:在ATL中ATL:: 与 :: 与 std::有何区别????
- 如何在VC打开的文件中随机删除一些数据,数据以二维表形式呈现
- 抽屉的效果是什么控件????
- vs2008资源文件已损坏或这种类型文件的编辑器不可用。。。
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);
那用m_hRgn在PaintRgn()函数直接粉刷按理来说应该行的呀...
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);//为什么这样获取的就是按钮的区域????
CWnd::GetWindowRgn
int GetWindowRgn( HRGN hRgn )const;返回值:
返回值指定了该函数获得的区域的类型。可以是下列值之一: · NULLREGION 区域为空。
· SIMPLEREGION 区域是一个简单的矩形。
· COMPLEXREGION 区域包括多于一个矩形。
· ERROR 发生了错误,区域没有受到影响。参数hRgn窗口区域的句柄。 参数: hRgn 窗口区域的句柄。 说明:
调用这个成员函数以获得窗口的窗口区域。窗口区域确定了操作系统允许画出窗口的区域。操作系统不会在窗口区域之外显示窗口的任何部分。窗口的窗口区域的坐标是相对于窗口的的左上角的,不是窗口的客户区域。要设置窗口的窗口区域,调用CWnd::SetWindowRgn。
那为什么改变HRGN hRgn=CreateRectRgn(0,0,0,0)的坐标对按钮的区域没所谓的呢??例如我改成HRGN hRgn=CreateRectRgn(0,0,31,31),这样获取的按钮的区域是不变的,为什么??
而且为什么要在PaintRgn()函数中创建一个局部的hrgn,而不能直接用成员变量m_hrgn???
2.GetWindowRgn传递的那个hRgn不需要创建
3.m_hrgn无效很可能是你在什么地方DeleteObject了
第一点我做到了。
第二点的话一定要在PaintRgn()函数中创建,也就是说一样要有HRGN hRgn = CreateRectRgn(0, 0, 0, 0);这条语句,不然就传进出的画刷就粉刷不了区域为什么一定要创建一个局部的呀??实在搞不懂
第三点我只是在析构函数中DeleteObject 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;
}