笔记GDI+

SelectObject() //该函数选择一个对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象。
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混合功能


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值