在成长的过程中收集了几种圆角的方法,现在贡献给大家。
方法一:
void CDlgBase::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if (!IsIconic())
{
if (m_bIsImageStyle)
{
BOOL bIsMaximize = IsZoomed();
int border_offset[] = {3, 2, 1};
if (bIsMaximize)
{
SetupRegion(border_offset, 0);
}
else
{
SetupRegion(border_offset, 3);
}
}
else
{
int border_offset[] = {5, 3, 2, 1, 1};
SetupRegion(border_offset, 5);
}
}
CRect rc;
GetClientRect(&rc);
OnSize(rc);
InvalidateRect(NULL);
}
// 设置窗口区域
void CDlgBase::SetupRegion(int border_offset[], int nSize)
{
CDC* pDC = GetDC();
CRect rc;
GetWindowRect(rc);
rc.OffsetRect(-rc.left, -rc.top);
CRgn rgn;
rgn.CreateRectRgn(0, 0, rc.Width(), rc.Height());
CRgn rgn_xor;
CRect rcXor;
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(0, y, border_offset[y], y + 1);
rgn_xor.CreateRectRgn(0, y, border_offset[y], y + 1);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(rc.right - border_offset[y], y, rc.right, y + 1);
rgn_xor.CreateRectRgn(rc.right - border_offset[y], y, rc.right, y + 1);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
if(m_bIsImageStyle)
{
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(0, rc.bottom - y - 1, border_offset[y], rc.bottom - y);
rgn_xor.CreateRectRgn(0, rc.bottom - y - 1, border_offset[y], rc.bottom - y);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(rc.right - border_offset[y], rc.bottom - y - 1, rc.right,
rc.bottom - y);
rgn_xor.CreateRectRgn(rc.right - border_offset[y], rc.bottom - y - 1,
rc.right,rc.bottom - y);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
HWND hWnd = GetSafeHwnd();
SetWindowLong(hWnd,GWL_EXSTYLE,GetWindowLong(hWnd,GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(RGB(255, 0, 255), 0, LWA_COLORKEY );
}
SetWindowRgn((HRGN)rgn, TRUE);
m_Rgn.DeleteObject();
m_Rgn.Attach(rgn.Detach());
ReleaseDC(pDC);
}
方法二: 此方法是收集DirectUI里面的一种
上面圆角 下面不圆角
void CDlg::OnSize(UINT nType, int cx, int cy) //画圆角
{
CDialog::OnSize(nType, cx, cy);
CSize szRoundCorner;
szRoundCorner.cx=szRoundCorner.cy=7; //赋值越大 圆角度越大
if( !::IsIconic(*this) && (szRoundCorner.cx != 0 || szRoundCorner.cy != 0) ) {
RECT rcClient;
::GetClientRect(*this, &rcClient);
RECT rc = { rcClient.left, rcClient.top + szRoundCorner.cx, rcClient.right,
rcClient.bottom };
HRGN hRgn1 = ::CreateRectRgnIndirect( &rc );
HRGN hRgn2 = ::CreateRoundRectRgn(rcClient.left, rcClient.top, rcClient.right + 1,
rcClient.bottom+1 , szRoundCorner.cx,szRoundCorner.cy);
::CombineRgn( hRgn1, hRgn1, hRgn2, RGN_OR );
::SetWindowRgn(*this, hRgn1, TRUE);
::DeleteObject(hRgn1);
::DeleteObject(hRgn2);
}
m_bMoveFirst=TRUE;
Invalidate();
}
四个角都是圆角
void CDlg::OnSize(UINT nType, int cx, int cy) //画圆角
{
CDialog::OnSize(nType, cx, cy);
CSize szRoundCorner;
szRoundCorner.cx=szRoundCorner.cy=7; //赋值越大 圆角度越大
if( !::IsIconic(*this) && (szRoundCorner.cx != 0 || szRoundCorner.cy != 0) ) {
RECT rcClient;
::GetClientRect(*this, &rcClient);
RECT rc = { rcClient.left, rcClient.top + szRoundCorner.cx, rcClient.right,
rcClient.bottom };
HRGN hRgn1 = ::CreateRectRgnIndirect( &rc );
HRGN hRgn2 = ::CreateRoundRectRgn(rcClient.left, rcClient.top, rcClient.right + 1,
rcClient.bottom+1 , szRoundCorner.cx,szRoundCorner.cy);
::CombineRgn( hRgn1, hRgn1, hRgn2, RGN_OR );
::SetWindowRgn(*this, hRgn1, TRUE);
::SetWindowRgn(*this, hRgn2, TRUE);
::DeleteObject(hRgn1);
::DeleteObject(hRgn2);
}
m_bMoveFirst=TRUE;
Invalidate();
}
区别就一个地方 添加 ::SetWindowRgn(*this, hRgn2, TRUE);
方法三:直接用圆角函数 里面的参数 自己研究吧
CRgn rgn;
rgn.CreateRoundRectRgn(nBorder,nCaption+nBorder,
rect.right-nBorder, rect.bottom-nBorder, 10,10);
this->SetWindowRgn((HRGN)rgn.m_hObject, TRUE);
rgn.DeleteObject();
还有很多,比如金山的界面库,其它的界面库都有方法,大家好好研究啊,一起进步。
透明就一个函数而与! 本人在其它的界面库看到过比较炫丽的半透明的效果,但貌似不是它,有时间我得研究研究。
typedef BOOL (FAR PASCAL * FUNCTransparent)(
HWND hwnd, // handle to the layered window
COLORREF crKey, // specifies the color key
BYTE bAlpha, // value for the blend function
DWORD dwFlags // action
);
void CBaseDlg::SetTrans(int itrans) //窗体透明
{
HMODULE hModule = GetModuleHandle(_T("user32.dll"));
FUNCTransparent SetLayeredWindowAttributes;
SetLayeredWindowAttributes= (FUNCTransparent)GetProcAddress(hModule,"SetLayeredWindowAttributes");
// 设置分层扩展标记
SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,GetWindowLong(GetSafeHwnd(),GWL_EXSTYLE)|0x80000L);
// 70% alpha
SetLayeredWindowAttributes(GetSafeHwnd(), 0, (255 * itrans) / 100, 0x2);
}
源码下载地址:
http://download.youkuaiyun.com/detail/banketree/4235674
加油 加油 加油
方法一:
void CDlgBase::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if (!IsIconic())
{
if (m_bIsImageStyle)
{
BOOL bIsMaximize = IsZoomed();
int border_offset[] = {3, 2, 1};
if (bIsMaximize)
{
SetupRegion(border_offset, 0);
}
else
{
SetupRegion(border_offset, 3);
}
}
else
{
int border_offset[] = {5, 3, 2, 1, 1};
SetupRegion(border_offset, 5);
}
}
CRect rc;
GetClientRect(&rc);
OnSize(rc);
InvalidateRect(NULL);
}
// 设置窗口区域
void CDlgBase::SetupRegion(int border_offset[], int nSize)
{
CDC* pDC = GetDC();
CRect rc;
GetWindowRect(rc);
rc.OffsetRect(-rc.left, -rc.top);
CRgn rgn;
rgn.CreateRectRgn(0, 0, rc.Width(), rc.Height());
CRgn rgn_xor;
CRect rcXor;
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(0, y, border_offset[y], y + 1);
rgn_xor.CreateRectRgn(0, y, border_offset[y], y + 1);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(rc.right - border_offset[y], y, rc.right, y + 1);
rgn_xor.CreateRectRgn(rc.right - border_offset[y], y, rc.right, y + 1);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
if(m_bIsImageStyle)
{
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(0, rc.bottom - y - 1, border_offset[y], rc.bottom - y);
rgn_xor.CreateRectRgn(0, rc.bottom - y - 1, border_offset[y], rc.bottom - y);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
for (int y = 0; y < nSize; ++y)
{
rcXor.SetRect(rc.right - border_offset[y], rc.bottom - y - 1, rc.right,
rc.bottom - y);
rgn_xor.CreateRectRgn(rc.right - border_offset[y], rc.bottom - y - 1,
rc.right,rc.bottom - y);
rgn.CombineRgn(&rgn, &rgn_xor, RGN_XOR);
rgn_xor.DeleteObject();
}
HWND hWnd = GetSafeHwnd();
SetWindowLong(hWnd,GWL_EXSTYLE,GetWindowLong(hWnd,GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes(RGB(255, 0, 255), 0, LWA_COLORKEY );
}
SetWindowRgn((HRGN)rgn, TRUE);
m_Rgn.DeleteObject();
m_Rgn.Attach(rgn.Detach());
ReleaseDC(pDC);
}
方法二: 此方法是收集DirectUI里面的一种
上面圆角 下面不圆角
void CDlg::OnSize(UINT nType, int cx, int cy) //画圆角
{
CDialog::OnSize(nType, cx, cy);
CSize szRoundCorner;
szRoundCorner.cx=szRoundCorner.cy=7; //赋值越大 圆角度越大
if( !::IsIconic(*this) && (szRoundCorner.cx != 0 || szRoundCorner.cy != 0) ) {
RECT rcClient;
::GetClientRect(*this, &rcClient);
RECT rc = { rcClient.left, rcClient.top + szRoundCorner.cx, rcClient.right,
rcClient.bottom };
HRGN hRgn1 = ::CreateRectRgnIndirect( &rc );
HRGN hRgn2 = ::CreateRoundRectRgn(rcClient.left, rcClient.top, rcClient.right + 1,
rcClient.bottom+1 , szRoundCorner.cx,szRoundCorner.cy);
::CombineRgn( hRgn1, hRgn1, hRgn2, RGN_OR );
::SetWindowRgn(*this, hRgn1, TRUE);
::DeleteObject(hRgn1);
::DeleteObject(hRgn2);
}
m_bMoveFirst=TRUE;
Invalidate();
}
四个角都是圆角
void CDlg::OnSize(UINT nType, int cx, int cy) //画圆角
{
CDialog::OnSize(nType, cx, cy);
CSize szRoundCorner;
szRoundCorner.cx=szRoundCorner.cy=7; //赋值越大 圆角度越大
if( !::IsIconic(*this) && (szRoundCorner.cx != 0 || szRoundCorner.cy != 0) ) {
RECT rcClient;
::GetClientRect(*this, &rcClient);
RECT rc = { rcClient.left, rcClient.top + szRoundCorner.cx, rcClient.right,
rcClient.bottom };
HRGN hRgn1 = ::CreateRectRgnIndirect( &rc );
HRGN hRgn2 = ::CreateRoundRectRgn(rcClient.left, rcClient.top, rcClient.right + 1,
rcClient.bottom+1 , szRoundCorner.cx,szRoundCorner.cy);
::CombineRgn( hRgn1, hRgn1, hRgn2, RGN_OR );
::SetWindowRgn(*this, hRgn1, TRUE);
::SetWindowRgn(*this, hRgn2, TRUE);
::DeleteObject(hRgn1);
::DeleteObject(hRgn2);
}
m_bMoveFirst=TRUE;
Invalidate();
}
区别就一个地方 添加 ::SetWindowRgn(*this, hRgn2, TRUE);
方法三:直接用圆角函数 里面的参数 自己研究吧
CRgn rgn;
rgn.CreateRoundRectRgn(nBorder,nCaption+nBorder,
rect.right-nBorder, rect.bottom-nBorder, 10,10);
this->SetWindowRgn((HRGN)rgn.m_hObject, TRUE);
rgn.DeleteObject();
还有很多,比如金山的界面库,其它的界面库都有方法,大家好好研究啊,一起进步。
透明就一个函数而与! 本人在其它的界面库看到过比较炫丽的半透明的效果,但貌似不是它,有时间我得研究研究。
typedef BOOL (FAR PASCAL * FUNCTransparent)(
HWND hwnd, // handle to the layered window
COLORREF crKey, // specifies the color key
BYTE bAlpha, // value for the blend function
DWORD dwFlags // action
);
void CBaseDlg::SetTrans(int itrans) //窗体透明
{
HMODULE hModule = GetModuleHandle(_T("user32.dll"));
FUNCTransparent SetLayeredWindowAttributes;
SetLayeredWindowAttributes= (FUNCTransparent)GetProcAddress(hModule,"SetLayeredWindowAttributes");
// 设置分层扩展标记
SetWindowLong(GetSafeHwnd(),GWL_EXSTYLE,GetWindowLong(GetSafeHwnd(),GWL_EXSTYLE)|0x80000L);
// 70% alpha
SetLayeredWindowAttributes(GetSafeHwnd(), 0, (255 * itrans) / 100, 0x2);
}
源码下载地址:
http://download.youkuaiyun.com/detail/banketree/4235674
加油 加油 加油