VC++开发垃圾文件清理软件(下)

转自:http://www.cnblogs.com/JczmDeveloper/archive/2013/03/22/2974716.html

1. 绘制对话框的背景位图

  绘制对话框背景位图本文采用的是处理对话框的WM_PAINT消息,该消息初始化时候对对话框进行绘制,从而绘制背景位图。绘制背景位图的主要代码如下:

CRect   rect;CPaintDC   dc(this);GetClientRect(&rect); //获取客户区
//设置对话框背景颜色
dc.FillSolidRect(rect,RGB(14,94,157));   //设置为窗口背景

2. 在指定的区域中输出位图

  为了能够在指定的区域中输出位图,需要使用设备上下文CDC类的StretchBlt方法。由于我们需要在窗口的非客户区域绘制位图,因此需要使用CWindowDC类的StretchBlt方法, CWindowDC类派生与CDC类,它提供了在窗口非客户区域绘制位图的功能。该方法数从源矩形中复制一个位图到目标矩形,必要时按目前目标设备设置的模式进行图像的拉伸或压缩。输出位图的主要实现代码如下:

    CRect winRC;CDC* pDC=GetWindowDC();//获取窗口设备上下文
    CDC memDC;memDC.CreateCompatibleDC(pDC);//创建兼容内存位图
    BITMAPINFO bmpInfo;CBitmap bmp;    //定义位图对象GetWindowRect(&winRC);bmp.LoadBitmap(nID);//加载位图bmp.GetObject(sizeof(BITMAPINFO),&bmpInfo);//获取位图信息int nBmpCX = bmpInfo.bmiHeader.biWidth;//获取位图宽度int nBmpCY = bmpInfo.bmiHeader.biHeight;//获取位图高度memDC.SelectObject(bmp);//选中位图对象pDC->StretchBlt(x,y,w,h,&memDC,0,0,nBmpCX,nBmpCY,SRCCOPY);//在窗口中绘制位图bmp.DeleteObject();//释放位图对象ReleaseDC(pDC);//释放DC

3. 对话框界面设计与绘制的实现:

  在对话框重绘的设计与实现过程中,一般需要绘制的对话框区域主要有标题部分、边框部分和客户区部分。具体的区域划分如下图所示。

  既然要对多个区域进行位图显示输出,所以我们先封装一个bmp位图显示输出函数如下:

void CClearTmpFileDlg::DisplayBmp(int x,int y,int w,int h,int nID)
{//nID 表示位图资源的ID
    CRect winRC;CDC* pDC=GetWindowDC();CDC memDC;memDC.CreateCompatibleDC(pDC);BITMAPINFO bmpInfo;CBitmap bmp;    GetWindowRect(&winRC);bmp.LoadBitmap(nID);bmp.GetObject(sizeof(BITMAPINFO),&bmpInfo);int nBmpCX = bmpInfo.bmiHeader.biWidth;int nBmpCY = bmpInfo.bmiHeader.biHeight;memDC.SelectObject(bmp);pDC->StretchBlt(x,y,w,h,&memDC,0,0,nBmpCX,nBmpCY,SRCCOPY);//在窗口中绘制位图
    bmp.DeleteObject();ReleaseDC(pDC);
}

  然后就是对各个区域进行位图输出重绘。由于标题栏以及边框主要都是非客户区域绘制,因此应该在WM_NCPAINT 消息中绘制。当然得先通过添加资源的方式将所用到的bmp位图资源导入到项目中。

  在 WM_NCPAINT消息对于的 方法OnNcPaint()中调用对话框绘制方法DrawDialog()。该方法的功能就是绘制对话框各个区域的位图。主要代码如下:

void CClearTmpFileDlg::DrawDialog()
{//重绘对话框标题栏、边框、最小化按钮、最大化按钮和关闭按钮等界面m_nFrameCY = GetSystemMetrics(SM_CYFIXEDFRAME);//获取对话框边框的高度m_nFrameCX = GetSystemMetrics(SM_CXDLGFRAME);//获取对话边框的宽度if(GetStyle()&WS_BORDER)//获取对话框是否有边框
    {m_nBorderCY = GetSystemMetrics(SM_CYBORDER) + m_nFrameCY;m_nBorderCX = GetSystemMetrics(SM_CXBORDER) +m_nFrameCX; }else{        m_nBorderCY = m_nFrameCY;m_nBorderCX = m_nFrameCX;}m_nTitleBarCY = GetSystemMetrics(SM_CYCAPTION) + m_nBorderCY;//计算标题栏高度m_nTitleBarCX =m_nBorderCX;CRect winRect,factRect;GetWindowRect(&winRect);factRect.CopyRect(CRect(0,0,winRect.Width(),winRect.Height()));CWindowDC windowsDC(this);//获取窗口设备上下文//获取整个MFC窗口的高度和宽度m_nWinWidth = winRect.Width();//=781m_nWinHeight = winRect.Height();//=459//绘制对话框左标题栏位图    DisplayBmp(0,0,100,m_nTitleBarCY,IDB_LEFTTITLE);//绘制对话框标题栏左端的logo图标DisplayBmp(3,0,26,m_nTitleBarCY,IDB_APPICON);//绘制对话框右标题栏位图    DisplayBmp(m_nWinWidth-100,0,100,m_nTitleBarCY,IDB_RIGHTTITLE);//绘制对话框中标题栏位图    DisplayBmp(100,0,m_nWinWidth-200,m_nTitleBarCY,IDB_MIDTITLE);//绘制对话框左边框位图DisplayBmp(0,m_nTitleBarCY,m_nBorderCX,m_nWinHeight-m_nBorderCY,IDB_LEFTBAR);//绘制对话框底边框位图DisplayBmp(m_nBorderCX,m_nWinHeight-m_nBorderCX,m_nWinWidth-2*m_nBorderCX,m_nBorderCX,IDB_BOTTOMBAR);//绘制对话框左边框位图DisplayBmp(m_nWinWidth-m_nBorderCX,m_nTitleBarCY,m_nBorderCX,m_nWinHeight-m_nBorderCY,IDB_RIGHTBAR);//给对话框绘制最小化按钮DisplayBmp(m_nWinWidth-26*3-5,0,26,26,IDB_MINBTN1);//给对话框绘制最大化按钮DisplayBmp(m_nWinWidth-26*2-5,0,26,26,IDB_MAXBTN1);//给对话框绘制关闭按钮DisplayBmp(m_nWinWidth-26-5,0,26,26,IDB_CLOSEBTN1);ReleaseDC(&windowsDC);//ReleaseDC(&memDC);DrawTitleBarText();//输出标题栏文本
}

  上面代码中最后的绘制对话框标题文本的方法DrawTitleBarText(),主要是用来显示标题栏的文本,其主要代码如下:

CString strTitle ="小蔡垃圾清理器3.0";
CDC* pDC= GetWindowDC();
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(RGB(255,255,255));
pDC->SetTextAlign(TA_CENTER);
CRect rect;
GetClientRect(&rect);
CSize szText = pDC->GetTextExtent(strTitle);
CFont* font,*fOldFont;
font = new CFont;
font->CreateFont(12,0,0,0,FW_BOLD,FALSE,FALSE,0,ANSI_CHARSET,     OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FF_SWISS,_T("宋体"));
fOldFont = pDC->SelectObject(font);
pDC->TextOut(100,6.5,strTitle,18);
pDC->SelectObject(fOldFont);
ReleaseDC(pDC); 

  在完成对话框相应区域的位图后,并没有完成任务,还需要处理标题栏按钮的热点效果,以及按钮的单击事件。首先得处理鼠标在非客户区域移动时的事件,即WM_NCMOUSEMOVE消息,在其消息处理函数中判断当前的鼠标点是否位于标题栏的按钮区域,如果是则设置按钮的热点效果,并且记录当前的按钮状态,及鼠标点在哪个按钮上。同样的,处理对话框非客户区域的单击事件,即WM_NCLBUTTONDOWN消息,在其消息处理函数中完成单击事件操作。这部分的代码比较简单,在此不予显示。

  上面,我简单的说了对话框界面的设计与实现,下面将介绍按钮控件重绘的实现:

  在MFC下编程,很多时候对于标准的按钮控件不是很满意,想要弄的美观些。这就需要按钮重绘。重绘按钮一般的实现方法就是重写CButton类。

首先给工程添加一个自绘按钮类MyDrawButton,基类为CButton。要想让按钮具备自绘功能,就要为按钮添加BS_OWNERDRAW属性。为类CButton重载PreSubclassWindow虚函数。在该函数中添加如下一行代码:

SetButtonStyle(GetButtonStyle() | BS_OWNERDRAW);

  当按钮控件具有了自绘功能之后,每次控件状态改变都会触发DrawItem函数,在该函数中来绘制按钮的形态外观,所以第二步就要重载DrawItem虚函数。在这个函数中就可以自由发挥了,比如绘制背景,底色,按钮标题,绘制文本字体样式等等。

一般都会为按钮定义几种不同状态时的外观,比如光标滑过时的状态,按钮按下时的状态,按钮禁用时的状态,以及按钮的正常状态等等。这就要为新的按钮添加几种重要的消息响应。比如WM_MOUSELEAVE消息,WM_MOUSEHOVER消息和WM_MOUSEMOVE消息等等,值得一提的是前两个消息的响应函数需要自己手动添加,微软提供了一个TrackMouseEvent函数在光标离开一个窗口时投递WM_MOUSELEAVE消息,光标滑过窗口时投递WM_MOUSEHOVER消息。一般来说可以在WM_MOUSEMOVE消息响应函数中调用TrackMouseEvent函数来投递WM_MOUSELEAVE消息和WM_MOUSEHOVER消息。然后在WM_MOUSELEAVE消息的响应函数中标记“光标已经离开按钮”,然后调用InvalidateRect函数让按钮重绘。在WM_MOUSEHOVER消息的响应函数中标记“光标正在按钮上方”,并调用InvalidateRect函数让按钮重绘。

在本文中,重绘按钮分为3个部分。

(1)绘制按钮背景样式,即绘制背景bmp位图,使得按钮具有自定义的样式,同时在绘制按钮背景的输出位图时采用TransparentBlt()函数,该函数的作用是使窗体上显示位图的背景与窗体背景色融为一体,不仅可以显示按钮bmp位图样式,而且还可以使背景透明。

(2)就是绘制按钮上的文本。主要绘制按钮上文本的样式,包括字体大小,字体样式,字体颜色等属性。

(3)实现不同状态下的按钮的外观样式,主要包括WM_MOUSEMOVE和WM_MOUSELEAVE两个消息的消息处理函数。分别实现鼠标在按钮区域上和不在按钮区域上的状态。为了标记鼠标移动到按钮区域内停留,需要用到一个定时器来标记鼠标是否还在按钮区域内停留。在WM_MOUSEMOVE内启动定时器,触发WM_MOUSELEAVE消息时结束定时器即销毁定时器。定时器的主要代码如下:

void MyDrawButton::OnTimer(UINT_PTR nIDEvent)
{// TODO: 在此添加消息处理程序代码和/或调用默认值if(nIDEvent != 24)return;CPoint    point;CRect    rect;GetWindowRect(&rect);    GetCursorPos(&point);// 如果鼠标离开按钮区域,重绘按钮if (!rect.PtInRect(point) && m_bMove){KillTimer (24);m_DrawState=ST_MOVEOUT;m_bMove=FALSE;Draw();}CButton::OnTimer(nIDEvent);
}

  重绘按钮类MyDrawButton的主要实现代码如下:

  定义的一些重绘用到的变量:

    #define ST_MOVEIN        0//绘制状态—在按钮区域上#define ST_MOVEOUT        1 //绘制状态—不在按钮区域上int m_DrawState;//绘制状态    int m_nBmpID;//当前显示的背景bmp位图的资源IDbool m_bMove;//鼠标是否进入按钮区域COLORREF m_clText;//当前文本颜色COLORREF m_clActiveText;//鼠标进入按钮区域时文本颜色COLORREF m_clNormalText;//鼠标离开按钮区域时文本颜色

  消息处理函数和定义的函数以及实现:

void MyDrawButton::PreSubclassWindow()
{SetButtonStyle(GetButtonStyle() | BS_OWNERDRAW);
}
void MyDrawButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{Draw();//绘制按钮
}
void MyDrawButton::Draw()//绘制按钮
{DrawBackground();//绘制按钮bmp位图,并使背景透明化DrawText();//绘制按钮上的文本
}
void MyDrawButton::DrawText()
{//绘制按钮上的文本的字体大小、样式等
    CString        itemString;CRect  clientRect;CClientDC  dc(this);GetClientRect(&clientRect);GetWindowText(itemString);if(itemString){CSize size=dc.GetTextExtent (itemString);//获得所选字体中指定字符串的高度和宽度int rectwidth=clientRect.Width();int rectheight=clientRect.Height();int textwidth=size.cx ;int textheight=size.cy ;        int x,y; // 文本的位置// 计算文本的输出位置x=(rectwidth-textwidth)/2;//水平居中y=(rectheight-textheight)/2;//垂直居中            switch(m_DrawState){case ST_MOVEIN://鼠标进入按钮区域m_clText=m_clActiveText;break;case ST_MOVEOUT://鼠标离开按钮区域m_clText=m_clNormalText;break;default:m_clText=m_clNormalText;break;}dc.SetTextColor(m_clText);dc.SetBkMode(TRANSPARENT);CFont *font ;font =new CFont();int fontSize = 14;       font->CreateFont(fontSize,0,0,0,FW_BOLD,FALSE,FALSE,0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FF_SWISS,_T("宋体"));dc.SelectObject(font);dc.TextOut (x,y,itemString);}
}
void MyDrawButton::SetBkBmp(int nBmpID)
{//设置按钮bmp位图样式m_nBmpID = nBmpID;
}
void MyDrawButton::DrawBackground()
{//绘制按钮bmp位图,并使背景透明化
    CRect winRC;CDC* pDC=GetWindowDC();CDC memDC;memDC.CreateCompatibleDC(pDC);BITMAPINFO bmpInfo;CBitmap bmp;    GetWindowRect(&winRC);bmp.LoadBitmap(m_nBmpID);bmp.GetObject(sizeof(BITMAPINFO),&bmpInfo);int nBmpCX = bmpInfo.bmiHeader.biWidth;int nBmpCY = bmpInfo.bmiHeader.biHeight;memDC.SelectObject(bmp);pDC->TransparentBlt(0,0,nBmpCX,nBmpCY,&memDC,0,0,nBmpCX,nBmpCY,RGB(14,94,157));//在窗口中绘制位图,RGB(14,94,157)是透明色
    bmp.DeleteObject();ReleaseDC(pDC);
}

  到此,按钮的自定义重绘完成了,接下来就可以使用自己重绘的按钮类MyDrawButton了。首先往对话框中添加一个按钮控件(以立即扫描按钮为例),假设它的ID值为IDC_TEST。进入类向导(Class Wizard)的成员变量属性页,为IDC_ BEGIN添加一个变量m_btnBegin。如下:

MyDrawButton m_btnBegin;

  然后就可以调用MyDrawButton的方法来设置按钮的样式了。如下:

m_btnBegin.SetBkBmp(IDB_BTN210x95,IDB_BTN210x95_3);//IDB_BTN210x95,IDB_BTN210x95分别为默认位图和鼠标在按钮区域时的位图。

  到现在为止,按钮类的重绘完成了,可以随意定义自己喜欢的样式的按钮了。现在相对完善成形的一个垃圾清理工具软件就开发完了。

  最后软件的主要成果界面如下:

                                         软件打开准备就绪界面

                                             正在运行截面图

                                              扫描完成界面图:

                                               清理完成界面图

源代码下载地址。

转载于:https://www.cnblogs.com/Dageking/archive/2013/03/22/2975542.html

VC++开发垃圾文件清理软件(下)相关推荐

  1. VC++开发垃圾文件清理软件之三:程序的界面设计与实现----对话框界面

    先说下哈,有人说要源代码,源代码在博文<VC++开发垃圾文件清理软件之四:程序的界面设计与实现----按钮控件界面>的最后给出下载地址供大家下载. 对应用程序界面的设计包括两部分,一部分是 ...

  2. 用C++编写的垃圾文件清理程序,这下电脑速度快多了!

    想必每个人电脑桌面上都会有一个垃圾文件清除器,这使得它很容易快速找到并擦干您计算机上的所有垃圾文件.它快速的扫描您的硬盘,然后显示垃圾文件,这样你就可以决定他们想要删除.程序精确地检测和识别只有垃圾文 ...

  3. CCleaner 垃圾文件清理规则 编写指南

    以下内容的英文版本来源于 CCleaner 官方论坛,仅供参考.欢迎大家编写并分享针对常用国产软件的垃圾文件清理规则! 需要说明的是规则文件(Winapp2.ini)需和程序文件放于同一文件夹下,才能 ...

  4. Windows垃圾文件清理--一键清理系统垃圾

    Windows垃圾文件清理 垃圾文件的定义 1. 软件安装过程中产生的临时文件 许多软件在安装时,首先要把自身的安装文件解压缩到一个临时目录(一般为 Windows文件夹下的Temp目录),如WinZ ...

  5. vc6.0垃圾文件清理工具_干货 | 电脑清理宝典

    是否有过盯着电脑却不见电脑响应, 最后拿电脑没办法的抓狂经历? 什么?电脑慢到你恨不得把它砸了? 且慢且慢, 说不定是电脑里的垃圾文件导致它速度变慢, 且听书先生讲讲清理电脑垃圾文件的方法. 宝典一: ...

  6. Mac重复文件清理软件—Cisdem Duplicate Finder for mac

    对于Mac用户来说,Cisdem Duplicate Finder是一款出色的重复查找工具,可以检测和查找所有重复内容,并批量删除它们以快速释放外部/内部硬盘空间.所有重复的照片,音乐,文档,视频或其 ...

  7. 系统垃圾文件清理器 制作:China Doll (莫增成)

    @echo off ::修正于2018-10-06 color 4a Title 系统垃圾文件清理器 制作:China Doll (莫增成) echo. echo ================== ...

  8. Duplicate File Detective(电脑重复文件清理软件)官方正式版V7.0.78.0 | 电脑怎么扫描重复文件

    Duplicate File Detective 是一款优秀的业务级电脑重复文件清理软件,也叫重复文件侦探,内置不断优化改进的智能多线程分析引擎和文件哈希计算器来计算任何文件的哈希值,能一次查找多个本 ...

  9. python磁盘垃圾文件清理器实验_Deletor(磁盘垃圾文件清理助手)V5.0.3 官方版

    Deletor(磁盘垃圾文件清理助手)是一款很方便好用的磁盘清理辅助工具.如果你需要一款好用的磁盘清理工具,小编带来的这款Deletor软件是很不错的选择,功能强大,操作简单,使用后用户就能轻松便捷的 ...

最新文章

  1. c的开始,求最大数。
  2. 自学python入门-学python入门看什么书
  3. 手把手教你实现基于LSTM的情感分析(LSTM-based Sentiment) Classification
  4. css链接样式_CSS中的样式链接
  5. OpenGL实用开源代码列表
  6. Spark资源调度分配
  7. html中用div做框架的代码,用div和css做框架
  8. python学习笔记011——检查变量类型type()
  9. maven教程一:快速搭建
  10. 蓝牙耳机测试软件apk_延迟测试app下载-蓝牙耳机延迟测试软件下载v1.9.1- 游侠下载站...
  11. 实时增量学习在云音乐直播推荐系统中的工程实践
  12. java将数字转换成大写_Java中金额数字转换为大写数字
  13. matlab与zemax,如何在ZEMAX和MATLAB之间通信
  14. php短信接口开发(http协议)
  15. 产权登记在未成年子女名下,离婚时应如何处理
  16. SpringMVC的基本使用+原理,一篇囊括
  17. 想准确识别各地方言?这套15000小时方言语音数据推荐了解一下
  18. 以一元及二元函数为例,通过多项式的函数图像观察其拟合性能;以及对用多项式作目标函数进行机器学习时的一些理解。
  19. MarkdownPad 2使用教程(语法篇)
  20. 【数据应用案例学习】(一)—— 基于用户画像的腾讯大数据防刷架构

热门文章

  1. 2019年,4亿行代码背后的故事
  2. 【Benewake(北醒) 】中距 TF02-Pro 40m介绍以及资料整理
  3. 工作八年,分享整合初中高级Java面试题合集附答案(2020年最新版)
  4. 在本地实现远程登录阿里云服务器的前提条件
  5. 如何从一个虚拟主机迁移数据到另一个虚拟主机
  6. 无穷小微积分,入门三道坎儿
  7. 搜狐邮箱怎么开启pop3服务器,各大中文邮箱POP3服务开启方法
  8. 可以让男人看一遍哭一遍的文章(转贴)
  9. 三角函数算式的c语言表达式,能计算加减乘除表达式,求添加计算平方、三角函数的功能,...
  10. c语言初学者学习所需软件