CreateRectRgn() //创建一个矩形区域,存储在CRgn对象
GetWindowRgn() //获得一份窗口区域的一个窗口
CreateSolidBrush() //创建一个已指定颜色的画刷
FrameRgn() //用指定刷子 围绕指定区域 画一个外框
Rectangle() //使用该函数画一个矩形
DeleteObject() //
CombineRgn() //用两个区域合成新的区域
HRGN
Region
CBrush
CRgn //GDI区域接口
FillSolidRect() //改变窗口背景色
圆角对话框/控件例子:
CRgn m_rgn;
CRect rc;
m_StaMarketing.GetWindowRect(&rc);
ScreenToClient(rc);
rc -= rc.TopLeft();
m_rgn.CreateRoundRectRgn(0, rc.top, 303,rc.top + 48 , 10,10);
::SetWindowRgn(m_StaMarketing.m_hWnd,m_rgn, TRUE);
不规则圆角对话框/控件:
CRgn m_rgn,m_rgnFrame;
CRect rect;
CRgn rgnTemp;
GetClientRect(rect);
m_rgn.CreateRoundRectRgn(0, -100,rect.Width()+1,rect.Height()+1, 120, 120);
rgnTemp.CreateRoundRectRgn(0, 0,rect.Width()+1,rect.Height()+1, 0, 0);
m_rgnFrame.CreateRoundRectRgn(0,0,rect.Width()+1,rect.Height()+1, 0, 0);
m_rgnFrame.CombineRgn(&m_rgn, &rgnTemp, RGN_AND);
::SetWindowRgn(m_hWnd, m_rgnFrame, TRUE);
抗锯齿
dc->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE,GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^0x80000);
HINSTANCE hInst = LoadLibrary(_T("User32.DLL"));
if (hInst){
typedef BOOL (WINAPI * MYFUNC)(HWND,COLORREF,BYTE,DWORD);
MYFUNC fun = NULL;
fun = (MYFUNC)GetProcAddress(hInst,"SetLayeredWindowAttributes");
if (fun)
fun(this->GetSafeHwnd(),0,/*m_nClarity*/100,2);
FreeLibrary(hInst);
}
改变对话框背景色:
在onPaint()
CRect rect;
CPaintDC dc(this);
GetClientRect(rect);
dc.FillSolidRect(rect,RGB(255,255,255));
//窗口透明两种方式,不规则窗口,窗口阴影
SetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE,GetWindowLong(this->GetSafeHwnd(),GWL_EXSTYLE)^WS_EX_LAYERED);
::SetLayeredWindowAttributes(this->m_hWnd,GetSysColor(COLOR_BTNFACE),200,LWA_COLORKEY);
采用 WS_EX_LAYERED 扩展属性 + UpdateLayeredWindow + PNG图片 + GdiPlus 可以实现很强大的不规则窗体,而不用像利用 BMP 图去抠每一个像素点。不过利用分层窗口实现有一个很大的缺陷,就是分层窗口不能是子窗口,分层之后的窗口的子控件(包括子窗口)不会再显示了,虽然控件仍然可以响应到消息。
解决办法有两个:
1. 附加一个POPUP的窗口专门用来放置窗口,并且该窗口可以用 SetLayeredWindowAttributes 将该POPUP窗口也透明一些,然后这两个窗口同时移动即可(这可能要用到DeferWindowPos来同步移动窗口)。
2. 采用DirectUIHWND的方法,由自己来绘制所有的控件,这个工作量很大,但效果是最好的。但是对于一些特殊控件,如IE Webbrowser,则只能采用第1种方法了;Windowless RichEidt如果在分层窗口中绘制的话,TxDraw函数的HDC来源也是一个比较麻烦的事:用GDI的HDC,则没有Alpha channel,还需要在绘制完之后去填充一下Alpha通道(Win7下可以考虑下BufferedPaintSetAlpha,还没试过),用Gdiplus的GetHDC函数,则效率太低,不能满足。
UpdateLayeredWindow函数使用介绍:
SetLayeredWindowAttributes与UpdateLayeredWindow的区别:
前者只能将整个对话框透明(包括上面的子窗口与控件),而后者的强大之处在于可以自定义每一个像素点的alpha值,实现任意效果.
UpdateLayeredWindow 函数的使用其实有点类似于 SetWindowPos,没用过的时候看起来很复杂。UpdateLayeredWindow 可以设置分层窗口的坐标和大小(想想SetWindowPos的作用,利用这一点我们可以实现完全无闪烁的窗口拉伸。不知道为什么QQ没有实现这一点)。
该函数的参数分析如下:
BOOL UpdateLayeredWindow(
HWND hwnd, // 窗口句柄 HDC hdcDst, // 取 NULL 即可 POINT *pptDst, // 分层窗口的新位置。不改变位置时可设置为NULL.建议保存为一个成员变量 SIZE *psize, // 分层窗口的新大小。不改变位置时可设置为NULL.建议保存为一个成员变量 HDC hdcSrc, // 内存HDC句柄,该HDC的HBITMAP中保存了分层窗口的内容。 POINT *pptSrc, // 设置为POINT pt = {0,0}; 即可 COLORREF crKey, // 一种使用关键色来实现透明的方法。一般都使用alpha来实现,这里设置0即可 BLENDFUNCTION *pblend, // 混合参数 DWORD dwFlags); // 取ULW_ALPHA。
这里面最关键的就是HDC hdcSrc了。
HDC可以用CreateCompatibalDC(NULL)来创建,但选进HDC中的HBITMAP则必须创建为32位色,使其能够带alpha channel。例如:
CImage image;
image.Create( rc.Width(), -rc.Height(), 32, CImage::createAlphaChannel );
BLENDFUNCTION结构的设置可以参考如下:
BLENDFUNCTION bf;
bf.BlendOp = AC_SRC_OVER ;
bf.AlphaFormat = AC_SRC_ALPHA;
bf.BlendFlags = 0; // Must be zero.
bf.SourceConstantAlpha = 255; // 0~255 透明度,这里的效果类似于SetLayeredWindowAttributes函数。取255即可,因为我们使用hdcSrc中的alpha值。
WS_EX_TRANSPARENT,加上该属性就能实现“鼠标穿透”效果。窗口周围的阴影肯定也是需要加上该属性的。
// 鼠标拖动窗口效果
UINT OnNcHitTest(CPoint point)
{
return HTCAPTION;
}
参考::http://www.rosoo.net/a/201004/9274.html
http://tech.ddvip.com/2008-11/122653928091905.html
http://bbs.csdn.net/topics/390345613
http://www.cnblogs.com/ztercel/archive/2011/09/08/2171783.html
http://hi.baidu.com/uileeihcy/item/d3d860c05ec4e952ad00ef3f
//颜色渐变
Graphics graphics(dc);
// CRect rc;
// GetClientRect(&rc);
// LinearGradientBrush linGrBrush(Point(100,0),Point(100,rc.Height()/2),Color(255,255,0,0),Color(255,0,0,255));
// Color colors[] = {
// Color(255, 0, 255, 0), // red
// Color(RGB(255,255,255)), //yellow
// Color(RGB(255,255,255)), // blue
// Color(255, 0, 255, 0)}; // green
// REAL positions[] = {
// 0.0f,
// 0.33f,
// 0.66f,
// 1.0f};
// linGrBrush.SetInterpolationColors(colors, positions,4);
// graphics.FillRectangle(&linGrBrush,rc.Width()/2,0,80,rc.Height()/2);
===============================================OpenGL库==============================================
OpenGL实现反走样需要满足两个条件:一是启用混合,二是启用针对几何图元的反走样处理。
glEnable(GL_BLEND); //启用OpenGL混合功能
glDisable(GL_BLEND);//关闭OpenGL混合功能