SetWindowRgn 只能调一次
void CMyButton::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
CRect rect;// = btnrect;
GetWindowRect(rect);
rect.OffsetRect(-rect.left,-rect.top);
CRgn rgn;
rgn.CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,Radius,Radius);
SetWindowRgn((HRGN)rgn.m_hObject,TRUE);
rgn.DeleteObject();
// CButton::PreSubclassWindow();
}
void CMyButton::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
CRect rect;// = btnrect;
GetWindowRect(rect);
rect.OffsetRect(-rect.left,-rect.top);
CRgn rgn;
rgn.CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,Radius,Radius);
SetWindowRgn((HRGN)rgn.m_hObject,TRUE);
rgn.DeleteObject();
// CButton::PreSubclassWindow();
}
{ CRect rect;
GetWindowRect(rect);
rect.OffsetRect(-rect.left,-rect.top);
CRgn rgn;
rgn.CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,ioffset,ioffset);
SetWindowRgn((HRGN)rgn.m_hObject,TRUE);
rgn.DeleteObject();
UINT uStyle = GetButtonStyle();
ModifyStyle(0,uStyle | BS_OWNERDRAW);
CButton::PreSubclassWindow();
}
这样改之后,刚开始界面就有圆角白色的,之前是点击之后才有的。
需要在创建完成后马上改变. 你可以放到WM_SIZE消息或者WM_CREATE消息中再试试RECT rcWnd;
::GetWindowRect(*this, &rcWnd);
OffsetRect(&rcWnd,-rcWnd.left, -rcWnd.top);
rcWnd.right++; rcWnd.bottom++;
HRGN hRgn1 = ::CreateRoundRectRgn(0, 0, rcWnd.right, rcWnd.bottom/3*2, roundTop, roundTop);
HRGN hRgn2 = ::CreateRoundRectRgn(0, rcWnd.bottom/3, rcWnd.right, rcWnd.bottom, roundBottom, roundBottom);
HRGN hRgn = hRgn1;
::CombineRgn(hRgn,hRgn1,hRgn2,RGN_OR); ::SetWindowRgn(*this, hRgn, TRUE);
::DeleteObject(hRgn1);
::DeleteObject(hRgn2);
::DeleteObject(hRgn);
ModifyStyle(0,uStyle | BS_OWNERDRAW);可以在属性中设置。Draw 时 不必 考虑 园角, rgn 外的 自动 会 Clip 掉。测试过的代码 没问题的
按你的方法测试了,依旧不行,总感觉SetwindowRgn没有起作用,能不能将这个类发给你,帮我看下。
把 SetWindowRgn 那句 改成:dc.SelectClipRgn
After a successful call to SetWindowRgn, the system owns the region specified by the region handle hRgn. The system does not make a copy of the region. Thus, you should not make any further function calls with this region handle. In particular, do not delete this region handle. The system deletes the region handle when it no longer needed.你应该用rgn.Detach();
rgn.CreateRoundRectRgn(),SetWindowRgn()后千万别rgn.DeleteObject()!!! 而是应该用rgn.Detatch()和内部的HRGN脱离关系。
#pragma once// CUIButton .henum BTN_COLOR{BTN_ENABLE,BTN_DISABLE,BTN_ON,BTN_OFF,BTN_CUSTOM};
class CUIButton : public CButton
{
DECLARE_DYNAMIC(CUIButton)
public:
CUIButton();
virtual ~CUIButton();protected:
DECLARE_MESSAGE_MAP()
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void PreSubclassWindow();
BTN_COLOR m_btncolor;
public:
COLORREF m_BkColor_Enable;
COLORREF m_BkColor_Disable;
COLORREF m_BkColor_On;
COLORREF m_BkColor_Off;
COLORREF m_TextColor_On;
COLORREF m_TextColor_Off;
COLORREF m_TextColor_Enalbe;
COLORREF m_TextColor_Disable; COLORREF m_TextColor_Custom;
COLORREF m_BkColor_Color;
static const int ioffset = 5; int m_Iconid;
CString m_szText;
void Set_Back_Color(COLORREF bkColor);
void Set_Text_Color(COLORREF textcolor);
void Set_Icon_ID(int iconid);
void Set_Window_Text(CString & sztext);
void Set_BTN_COLOR(BTN_COLOR nstate);
BTN_COLOR Get_BTN_COLOR();
};// UIButton.cpp : 实现文件
//#include "stdafx.h"
#include "UIButton.h"
// CUIButtonIMPLEMENT_DYNAMIC(CUIButton, CButton)CUIButton::CUIButton()
{
//m_BkColor_Enable = RGB(120, 171, 233);
m_BkColor_Enable = RGB(117, 174, 17);
m_BkColor_Disable = RGB(160, 193, 242);
m_TextColor_Enalbe = RGB(229, 252, 195);
m_TextColor_Disable = RGB(0,0,255);
m_BkColor_On = RGB(174, 223, 167);
m_BkColor_Off = RGB(197, 221, 0);
m_TextColor_On = RGB(100,21,240);
m_TextColor_Off = RGB(0, 110, 100);
m_TextColor_Custom = RGB(193, 221, 239);
m_BkColor_Color = RGB(92, 136, 201);
m_Iconid = 0; m_btncolor = BTN_CUSTOM;}CUIButton::~CUIButton()
{
}
BEGIN_MESSAGE_MAP(CUIButton, CButton)
END_MESSAGE_MAP()// CUIButton 消息处理程序void CUIButton::PreSubclassWindow()
{ /*CRect rect;
GetWindowRect(rect);
rect.OffsetRect(-rect.left,-rect.top);
CRgn rgn;
rgn.CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,ioffset,ioffset);
SetWindowRgn((HRGN)rgn.m_hObject,TRUE);
rgn.DeleteObject();*/
UINT uStyle = GetButtonStyle();
ModifyStyle(0,uStyle | BS_OWNERDRAW);
CButton::PreSubclassWindow();
}void CUIButton::Set_Back_Color(COLORREF bkColor)
{
//m_BkColor = bkColor;
Invalidate();
}
void CUIButton::Set_Text_Color(COLORREF textcolor)
{
//m_TextColor = textcolor;
Invalidate();
}
void CUIButton::Set_Icon_ID(int iconid)
{
m_Iconid = iconid;
Invalidate();
}
void CUIButton::Set_Window_Text(CString & sztext)
{
m_szText = sztext;
Invalidate();
}
void CUIButton::Set_BTN_COLOR(BTN_COLOR nstate)
{
m_btncolor = nstate;
Invalidate();
}BTN_COLOR CUIButton::Get_BTN_COLOR()
{
return m_btncolor;
}void CUIButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CRect rect = lpDrawItemStruct->rcItem;
UINT state = lpDrawItemStruct ->itemState;
CDC * pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRgn rgn;
rgn.CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,ioffset,ioffset);
SetWindowRgn((HRGN)rgn.m_hObject,TRUE);
CBrush brushBackGround,*pOldBrush;
CPen pen,* pOldPen; if(m_btncolor == BTN_ENABLE)
{
brushBackGround.CreateSolidBrush(m_BkColor_Enable);
pen.CreatePen(PS_SOLID,1,m_BkColor_Enable);
pDC->SetTextColor(m_TextColor_Enalbe);
}
else if(m_btncolor == BTN_DISABLE)
{
brushBackGround.CreateSolidBrush(m_BkColor_Disable);
pen.CreatePen(PS_SOLID,1,m_BkColor_Disable);
pDC->SetTextColor(m_TextColor_Disable);
}
else if (m_btncolor == BTN_ON)
{
brushBackGround.CreateSolidBrush(m_BkColor_On);
pen.CreatePen(PS_SOLID, 1, m_BkColor_On);
pDC->SetTextColor(m_TextColor_On);
}
else if (m_btncolor == BTN_OFF)
{
brushBackGround.CreateSolidBrush(m_BkColor_Off);
pen.CreatePen(PS_SOLID, 1, m_BkColor_Off);
pDC->SetTextColor(m_TextColor_Off);
}
else
{
brushBackGround.CreateSolidBrush(m_BkColor_Color);
pen.CreatePen(PS_SOLID, 1, m_BkColor_Color);
pDC->SetTextColor(m_TextColor_Custom);
} pOldPen = pDC ->SelectObject(&pen);
pOldBrush = pDC -> SelectObject(&brushBackGround);
pDC ->RoundRect(&rect,CPoint(ioffset,ioffset));
CFont font, *pOldfont;
font.CreatePointFont(120, _T("微软雅黑"), pDC);
pOldfont = pDC->SelectObject(&font); if (m_Iconid != 0)
{
HICON hicon = (HICON)LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(m_Iconid), IMAGE_ICON, 48, 48, LR_DEFAULTCOLOR);
ICONINFO iconinfo;
GetIconInfo(hicon, &iconinfo);
HBITMAP hBitmap = iconinfo.hbmMask;
BITMAP bmp;
GetObject(hBitmap, sizeof(bmp), &bmp);
int xpos, ypos;
xpos = rect.right - bmp.bmHeight - ioffset;
ypos = (rect.Height() - bmp.bmHeight) / 2; DrawIconEx(pDC->m_hDC, xpos, ypos, hicon, bmp.bmWidth, bmp.bmHeight, 0, NULL, DI_NORMAL);
CString szText;
GetWindowText(szText);
if (szText.IsEmpty())
szText = m_szText;
CSize szExtent = pDC->GetTextExtent(szText);
CPoint pt((rect.right - bmp.bmWidth - szExtent.cx - ioffset) / 2, (rect.Height() - szExtent.cy ) / 2);
//pDC->SetTextColor(m_TextColor_Enalbe);
pDC->SetBkMode(TRANSPARENT);
pDC->TextOut(pt.x, pt.y, szText);
}
else
{
CString szText;
GetWindowText(szText);
if (szText.IsEmpty())
szText = m_szText;
CSize szExtent = pDC->GetTextExtent(szText);
CPoint pt((rect.right - szExtent.cx) / 2, (rect.Height() - szExtent.cy)/ 2);
pDC->SetBkMode(TRANSPARENT);
pDC->TextOut(pt.x, pt.y, szText);
}
if (state & ODS_FOCUS) // 具有焦点时,画一圈小虚线
{
rect.DeflateRect(3, 3);
pDC->DrawFocusRect(&rect);
}
if (state & ODS_SELECTED)
{
rect.DeflateRect(-2, -2);
pDC->InvertRect(&rect);
}
pDC->SelectObject(pOldfont);
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
brushBackGround.DeleteObject();
pen.DeleteObject();
font.DeleteObject();
//rgn.DeleteObject();
}
以上是我类的全部代码,很多if只是画不同状态。另附一个链接,感觉都差不多,为什么不行?http://bbs.csdn.net/topics/340257193
千万不要被误导,SetWindowRgn调用之后其里面的参数HRGN是可以DeleteObject的。
千万不要被误导,SetWindowRgn调用之后其里面的参数HRGN是可以DeleteObject的。删不删除这都不是关键,资源泄漏什么没关系,关键是这个问题没解决,效果不好看。看很多帖子都成功了。
BOOL CUIButton::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return TRUE;
return CButton::OnEraseBkgnd(pDC);
}
{
// TODO: Add your code to draw the specified item
CRect btnrect = lpDrawItemStruct->rcItem;
UINT state = lpDrawItemStruct ->itemState;
CDC * pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CRect rect = btnrect;
CRgn rgn;
rgn.CreateRoundRectRgn(rect.left,rect.top,rect.right,rect.bottom,Radius,Radius);
pDC->SelectClipRgn(&rgn,TRUE);
pDC ->FillSolidRect(&rect,RGB(255,0,0));
pDC ->FillSolidRect(&rect,RGB(255,255,255));
那就会不是RoundRect
因为:
pDC->SelectClipRgn(&rgn,TRUE);
没起作用:
但可以把
pDC->SelectClipRgn(&rgn,TRUE);
放OnEraseBkgnd 中.
再pDC ->FillSolidRect(&rect,RGB(255,255,255));
其实是round rect !