• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > MFC绘制不规则窗体的方法

MFC绘制不规则窗体的方法

作者:惟愿莲心不染尘 字体:[增加 减小] 来源:互联网 时间:2017-05-28

惟愿莲心不染尘 通过本文主要向大家介绍了mfc窗体,mfc窗体应用程序,c mfc窗体,mfc 隐藏窗体,mfc关闭窗体等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文实例讲述了MFC 绘制不规则窗体的方法。分享给大家供大家参考。具体分析如下:

实现过程:

1、首先创建基于DLG的MFC应用程序,命名为:tryBGDlg,并将DLG的属性设置为:Title Bar :False ,其它设置不变

2、制作两幅图像,其中的一幅黑白图像,是根据播放器外观来制作的,其中白色区域是要保留的最终在桌面上显示的区域。将这两幅图像添加到工程中,第一个ID号设置为IDB_INTERFACE,第二个ID号设置为:IDB_MASK

3、在CtryBGDlg类中添加一个在函数:

函数说明:cBitmap是要传入的掩码位置变量,这里是指IDB_MASK创建的对象,TransColor是指要设为透明相素的RGB值

void CtryBGDlg::SetupRegion( CDC *pDC, CBitmap &cBitmap, COLORREF TransColor ) 
{ 
  CDC memDC; 
  memDC.CreateCompatibleDC(pDC); 
  CBitmap *pOldMemBmp=NULL; 
  pOldMemBmp=memDC.SelectObject(&cBitmap); 
  BITMAP bit; 
  cBitmap.GetBitmap (&bit); 
  CRgn crRgn, crRgnTmp; 
  crRgn.CreateRectRgn(0, 0, 0, 0);//创建一个空区域 
  int iX = 0;int iY = 0; 
  for (iY = 0; iY < bit.bmHeight; iY++) 
  { 
    do 
    { 
      //skip over transparent pixels at start of lines. 
      while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) == TransColor) 
        iX++; 
      //remember this pixel 
      int iLeftX = iX; 
      //now find first non transparent pixel 
      while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) != TransColor) 
        ++iX; 
      //create a temp region on this info 
      crRgnTmp.CreateRectRgn(iLeftX, iY, iX, iY+1); 
      //combine into main region. 
      crRgn.CombineRgn(&crRgn, &crRgnTmp, RGN_XOR); 
      //delete the temp region for next pass (otherwise you'll get an ASSERT) 
      crRgnTmp.DeleteObject(); 
    }while(iX < bit.bmWidth); 
    iX = 0; 
  } 
  SetWindowRgn(crRgn, TRUE); 
  iX = (GetSystemMetrics(SM_CXSCREEN))-700; 
  iY = (GetSystemMetrics(SM_CYSCREEN)) / 2 - (bit.bmHeight / 2); 
  SetWindowPos(&wndTop, iX, iY, bit.bmWidth, bit.bmHeight, NULL);  
  // Free resources. 
  memDC.SelectObject(pOldMemBmp);
  // Put the original bitmap back (prevents memory leaks) 
  memDC.DeleteDC(); 
  crRgn.DeleteObject(); 
}
</div>

4、在BOOL CtryBGDlg::OnInitDialog()函数中添加如下代码:

CBitmap bmp; 
bmp.LoadBitmapW(IDB_MASK); 
this->SetupRegion(this->GetWindowDC(),bmp,RGB(0,0,0));

</div>

5、添加对WM_ERASEBKGND消息响应,并在BOOL CtryBGDlg::OnEraseBkgnd(CDC* pDC)函数中添加如下代码

BOOL CtryBGDlg::OnEraseBkgnd(CDC* pDC) 
{ 
  // TODO: 在此添加消息处理程序代码和/或调用默认值 
  CRect rect; 
  this->GetWindowRect(&rect); 
  CDC memDC; 
  CBitmap bmp; 
  CBitmap *pOldBmp=NULL; 
  bmp.LoadBitmapW(IDB_INTERFACE); 
  memDC.CreateCompatibleDC(pDC); 
  pOldBmp=memDC.SelectObject(&bmp); 
  pDC->BitBlt(0,0,rect.Width(),rect.Height(),&memDC,0,0,SRCCOPY); 
  if(pOldBmp) 
  { 
    memDC.SelectObject(pOldBmp); 
  } 
  return true; 
// return CDialog::OnEraseBkgnd(pDC); 
}

</div>

到此就实现了不规则窗体的创建,创建后的视图如开头所示。

6、一般我们还要实现对窗体的托动操作,实现方法如下:
添加对WM_NCHITTEST消息的响应,并在生成的LRESULT CtryBGDlg::OnNcHitTest(CPoint point)函数中添加如下代码:

LRESULT CtryBGDlg::OnNcHitTest(CPoint point) 
{ 
  // TODO: 在此添加消息处理程序代码和/或调用默认值 
  CRect rc; 
  GetClientRect(&rc); 
  ClientToScreen(&rc); 
  return rc.PtInRect(point) ? HTCAPTION : CDialog::OnNcHitTest(point); 
// return CDialog::OnNcHitTest(point); 
}
</div>

至此就完全实现了,不规则窗体的创建和对窗体托动消息的响应部分。

下面将细致的讲解具体实现原理及部分的代码的解析:

总原理:这个程序的原理主要是先用IDB_MASK图像计算出要设定的窗体的轮廓,然后利用SetWindowRgn()函数来对其进行更改。最后在窗体重绘的时候响应WM_ERASEBKGND消息,将窗体背景图片IDB_INTERFACE贴到窗体上。
 
利用IDB_MASK图像计算窗体轮廓的原理:

计算窗体轮廓的代码主要靠SetupRegion()函数来实现,考虑到窗体的不规则,应采取掩模位图的方式来对其进行描述,对于本例,其白色区域为要保留的不规则窗体的轮廓区域。这段代码首先是用crRgn.CreateRectRgn(0, 0, 0, 0)创建一个空的区域,然后对IDB_MASK图像的像素信息进行一列一列的枚举,计算出每列中不设为透明的区域,然后跟crRgn合并,所以最后的crRgn就是所要设定的区域。

核心代码为:

CRgn crRgn, crRgnTmp; 
  //创建一个空区域 
  crRgn.CreateRectRgn(0, 0, 0, 0); 
  int iX = 0;int iY = 0; 
  for (iY = 0; iY < bit.bmHeight; iY++) 
  { 
    do 
    { 
      //skip over transparent pixels at start of lines. 
      //以一个相素列为单位,找到在这一个相素列中,第一个不是要设为透明相素的点iX。 
      //然后再找到以这个iX为起点的,在这个一个相素列中最后跟他临近的最后一个不是透明的点。 
      //然后将他们一起合并到crRgn中。 
      while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) == TransColor) 
        iX++;//在iY和iY+1这个相索列中,第一个不设为透明的点的X坐标 
      int iLeftX = iX;//保存这个点的坐标 
      while (iX <= bit.bmWidth && memDC.GetPixel(iX, iY) != TransColor) 
        ++iX;//这是找到在iX最临近的不透明的X坐标 
      crRgnTmp.CreateRectRgn(iLeftX, iY, iX, iY+1);//这四个点连在一起就是现在刚找到的不透明的区域 
      //合并区域 
      crRgn.CombineRgn(&crRgn, &crRgnTmp, RGN_OR); 
      //记得最终要手动删除crRgnTmp对象 
      crRgnTmp.DeleteObject(); 
    }while(iX < bit.bmWidth);
    //如果iX没有达到图片的末尾,说明还没有枚举完这一行,则在iY和iY+1这个行上,进行下一轮的//枚举 
    iX = 0; 
}

</div>

希望本文所述对大家的MFC程序设计有所帮助。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • MFC控件大小随窗体大小而改变
  • MFC绘制不规则窗体的方法
  • 构建mfc窗体的简单示例

相关文章

  • 2017-05-28关于C语言指针赋值的问题详解
  • 2017-05-28详解C++编程中向函数传递引用参数的用法
  • 2017-05-28C/C++动态分配与释放内存的区别详细解析
  • 2017-05-28C++封装线程类的实现方法
  • 2017-05-28如何实现循环队列
  • 2017-05-28成员初始化列表与构造函数体中的区别详细解析
  • 2017-05-287种排序算法的实现示例
  • 2017-05-28C++ boost 时间与日期处理详细介绍
  • 2017-05-28C++ 反射机制详解及实例代码
  • 2017-05-28C++实现ping程序实例

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 合并排序(C语言实现)
    • c++将引用或者是指针作为函数参数实现实参的运算
    • C语言顺序表实现代码排错
    • 浅谈C语言中结构体的初始化
    • C和MFC巧妙获取外网IP的两种实现方法
    • 详细对比C语言中的chmod()函数和fchmod()函数
    • 浅谈Linux环境下并发编程中C语言fork()函数的使用
    • C语言二维数组的处理实例
    • C语言求连续最大子数组和的方法
    • 基于errno返回值的对应错误码的详细介绍

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有