VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

有编程疑问吗?还请到提问专区发帖提问!
搜索
查看: 369|回复: 0

VC++高级班之窗口篇-[15]实现不规则半透明的窗口

[复制链接]
51_avatar_middle
online_admins Syc 发表于 2018-3-6 01:26:02 | 显示全部楼层 |阅读模式
------------------------------------------ Begin ----------------------------------------
①、简介:
在大多数的 Windows 应用程序中,窗体都是使用正规的矩形窗体,例如我们常用的:记事本,浏览器,等等。矩形窗体,具有编程实现简单,风格简洁的优点。
但在某些娱乐游戏程序中使用就略显呆板些了,这时若用不规则窗体替代原先的矩形窗体,将会使这类程序更添情趣。典型的例子有 Windows 自代的 Media Player!
===================================================
②、原理:
所有的 Windows 窗体都位于一个称为“region”的区域中,窗体的大小如果超出“region”的范围,Windows 会自动裁剪超出范围的那部分窗体,使其不可见。
所以,要创建不规则窗体有两个步骤:第一步就是创建不规则区域;第二步就是将窗体放到创建的“region”区域中!
===================================================
③、创建不规则区域:
  1. BOOL CRgn::CreateRectRgn( int x1, int y1, int x2, int y2 ); //创建矩形的“region”
  2. BOOL CRgn::CreateEllipticRgn( int x1, int y1, int x2, int y2 ); //创建圆形或椭圆形“region”
  3. BOOL CRgn::CreateRoundRectRgn( int x1, int y1, int x2, int y2, int x3, int y3 ); //创建圆角矩形“region”
  4. BOOL CRgn::CreatePolygonRgn( LPPOINT lpPoints, int nCount, int nMode ); //创建多边形“region”
复制代码

===================================================
④、代码实现:
  1. CRect mRect;
  2. GetWindowRect(&mRect);
  3. CRgn rgn1, rgn2, rgn3;
  4. rgn1. CreateEllipticRgn(0, 0, mRect.Width(), mRect.Height());
  5. rgn2. CreateRoundRectRgn(0, 0, mRect.Width(), mRect.Height(), 25, 25);

  6. rgn3.CreateRectRgn(0, 0, 0, 0);
  7. rgn3.CombineRgn(&rgn1, &rgn2, RGN_XOR);
  8. SetWindowRgn(rgn3, TRUE);
复制代码

///////////////////////////////////////////////////////////////////////////

  1. void CDrawTestDlg::DisplayMyWnd()
  2. {
  3.         HRGN wndRgn;
  4.         CClientDC clientDc(this);
  5.         CFont mFont;

  6.                 mFont.CreateFont(
  7.                         100, 40, 0, 0, FW_HEAVY, TRUE, FALSE,
  8.                         0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
  9.                         CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
  10.                         DEFAULT_PITCH | FF_SWISS, _T("宋体"));

  11.                 clientDc.BeginPath();       
  12.                 clientDc.SetBkMode(TRANSPARENT);

  13.                 CFont *pOldFont = NULL;
  14.                 pOldFont = clientDc.SelectObject( &mFont );
  15.                 clientDc.TextOut(0, 0, _T("CcTry.CoM"));
  16.                 clientDc.SelectObject( pOldFont );
  17.                 clientDc.EndPath();

  18.                 wndRgn = ::PathToRegion(clientDc.m_hDC);
  19.                 SetWindowRgn(wndRgn, TRUE);
  20. }
复制代码

===================================================
⑤、拖动时的边框问题解决:
  1. BOOL bEnabled = FALSE;
  2. ::SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &bEnabled, 0);
  3. if( !bEnabled ) {
  4.         ::SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
  5. }
复制代码

===================================================
⑥、半透明窗体的实现:
  1. //条件:_WIN32_WINNT >= 0x0500
  2. ModifyStyleEx(0, WS_EX_LAYERED);
  3. SetLayeredWindowAttributes(0, 100, LWA_ALPHA);
复制代码

////////////////////////////////////////////////////////////////////////////
  1. BOOL SetMyWindowAttributes(HWND hWnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags)
  2. {
  3.         ASSERT(IsWindow(hWnd));
  4.         BOOL bRet = FALSE;
  5.         SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE)^0x80000);
  6.         HINSTANCE hInst = LoadLibrary(_T("User32.DLL"));
  7.         if(hInst) {
  8.                 typedef BOOL (WINAPI *MYFUNC)(HWND, COLORREF, BYTE, DWORD);
  9.                 MYFUNC myFunc = NULL;
  10.                 myFunc = (MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");
  11.                 if(myFunc) {
  12.                         bRet = myFunc(hWnd, crKey, bAlpha, dwFlags);
  13.                 }
  14.                 FreeLibrary(hInst);
  15.         }
  16.         return bRet;
  17. }
复制代码

===================================================
⑦、透明度的动态调节:
1、拖入 Slider Control 控件并绑定控件类型变量:CSliderCtrl m_Slider;
2、初始化滑块范围:
  1. m_Slider.SetRange(0, 255);
  2. m_Slider.SetPos(100);
复制代码

3、响应 NM_CUSTOMDRAW 消息,进行透明度的动态调节:
  1. int nPos = m_Slider.GetPos();
  2. SetMyWindowAttributes(m_hWnd, 0, nPos, 2);
复制代码

===================================================
※※※ 小作业:
------------------------------------- End -------------------------------------------------

相关课程演示细节还请观看视频教程!
本套教程由VC驿站原创,提供视频教程+售后答疑服务!
教程介绍及详情请见:https://www.cctry.com/static/vip/index.html
VC驿站Vip会员详情请见:https://www.cctry.com/static/vip/index.html




上一篇:VC++高级班之窗口篇-[14]双缓冲讲解及界面贴图
下一篇:VC++高级班之窗口篇-[16]实现对话框的自适应最大化功能

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你已经在论坛发帖求助,并且从坛友或者管理的回复中解决了问题,请编辑帖子并把分类改成【已解决】

如何回报帮助你解决问题的坛友?可以给对方加【热心】【驿站币】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2018-12-15 20:55

Powered by Discuz! X3.4

© 2009-2018 cctry.com

快速回复 返回顶部 返回列表