这段时间用MFC做完了项目里的一个对图像处理(字迹匹配)的软件,通过项目的具体要求的一步一步的实现,我也学习到了很多以前困惑很久的问题,算是对自己的一个提高吧,把一些有技巧性的操作记在这里,给以后的自己留一份存档也是不错的。

一、关于窗口绘制

1.添加窗口背景图片

MFC创建的窗口的确有点丑,如果不做美化的话做出来的软件也会看着都没有想用的欲望。闲话不多说,直接开始添加背景图片的步骤吧

(1)找到自己想作为背景的图片,并转换为bmp格式,复制到当前项目的资源文件夹res下

(2)对于对话框:

  在XXXDlg.cpp的OnPaint()中把else中的语句改为:

else{
//CDialogEx::OnPaint();
CBitmap bmpBackground;
bmpBackground.LoadBitmap(IDB_BITMAP1);//IDB_BITMAP是自己的图对应的ID
CRect rc;//表示对话框的大小尺寸
GetClientRect(&rc);
CPaintDC dc(this);
BITMAP bm;
bmpBackground.GetBitmap(&bm);
int width = bm.bmWidth, height = bm.bmHeight;
for(int y=;y < rc.Height();y += height)
{
for(int x=;x < rc.Width();x += width)
{
CDC memDC;
CBitmap *oldMemBitmap; memDC.CreateCompatibleDC(&dc);
oldMemBitmap=memDC.SelectObject(&bmpBackground); dc.StretchBlt( x, y, width, height, &memDC, , , width, height, SRCCOPY );
memDC.SelectObject(oldMemBitmap);
}
}
}

对于单文档:
<1>在XXXView.h中添加定义:

afx_msg BOOL OnEraseBkgnd(CDC* pDC);
DECLARE_MESSAGE_MAP()

<2>在XXXView.cpp中的BEGIN_MESSAGE_MAP(...)与END_MESSAGE_MAP()之间添加ON_WM_ERASEBKGND(),即:

BEGIN_MESSAGE_MAP(...)
  ON_WM_ERASEBKGND()
END_MESSAGE_MAP()

<3>在XXXView类的构造函数中载入位图资源:LoadBitmap(IDB_BITMAP);

<4>实现函数BOOL XXXView::OnEraseBkgnd(CDC* pDC);

{
CBitmap bmpBackground;
bmpBackground.LoadBitmap(IDB_BITMAP1);//IDB_BITMAP是自己的图对应的ID
   //载入位图如果放在这里也可以,不过会重复载入,影响效率
CRect rc;//表示对话框的大小尺寸
GetClientRect(&rc);
CPaintDC dc(this);
BITMAP bm;
bmpBackground.GetBitmap(&bm);
int width = bm.bmWidth, height = bm.bmHeight;
for(int y=;y < rc.Height();y += height)
{
for(int x=;x < rc.Width();x += width)
{
CDC memDC;
CBitmap *oldMemBitmap;
memDC.CreateCompatibleDC(&dc);
oldMemBitmap=memDC.SelectObject(&bmpBackground);
dc.StretchBlt( x, y, width, height, &memDC, , , width, height, SRCCOPY );
memDC.SelectObject(oldMemBitmap);
}
}
}

背景图片现在就可以正常显示了,但是可能会出现按钮被图片覆盖的情况,如果发生了也不要急,只要进行一点小小的操作就可以解决:

在对话框点击右键->属性,将WS_CLIPCHILDREN(裁剪子窗口)设为True,这样子窗口区域(按钮部分)就不会被背景的绘制而覆盖

  回头来看时发现这个有点复杂了,多说一句,其实这个OnEraseBkgnd(...)消息响应函数也可以根据下面的类向导那样直接添加响应函数,而不需要手工添加。

2.更改静态文本框背景

从上个图片中也可以看到,中间那一行静态文本很扎眼,因为在绘制时字本身有背景颜色(单一颜色)把图片的那一块给挡住了。我们为了能让字只显示它本身的部分,而不绘制字的背景色则需要进行下面的一些操作:

<1>在主窗口点击右键->类向导,在“消息”下面找到“WM_CTLCOLOR”,然后选择“添加处理程序”->“编辑代码”:

HBRUSH C常用操作Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
// 对特定的控件做修改
if (nCtlColor == CTLCOLOR_STATIC) //修改静态文本框
{
pDC->SetTextColor(RGB(,,)); //设置字体颜色
pDC->SetBkMode(TRANSPARENT);//设置背景为透明
static HBRUSH B = (HBRUSH)GetStockObject(NULL_BRUSH);//获取画笔颜色混合后的画笔,完成透明
return B; //返回画刷句柄
}
return CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
}

<2>到对话框中,点击对应的静态文本框,在属性中把“透明”调为True,好了,大功告成!

3.重绘窗口(防止重影)——此节将在下面细细道来...

二、编辑框部分

1.让编辑框自动滚动显示

  当一个编辑框中需要显示的数据较多时,我们需要设置多行属性:把对应编辑框的Multiline和Verticle scroll属性均设置为True,如果不允许被修改,可以把Read only属性也设置为True。

  在处理完编辑框IDC_value1对应的变量value1之后再使用以下代码即可实现自动向下滚动显示:

SetDlgItemText(IDC_value1,value1);//分别为编辑框的ID和对应的变量
CEdit* pEdit = ((CEdit*)GetDlgItem(IDC_value1));
pEdit->LineScroll(pEdit->GetLineCount());//设置完成后不需要调用UpdateData(0)

很明显,滚动条可以自动向下滚动了,但是仔细的朋友会看到,编辑框内却出现了重影现象(这就是上一节提到的却还没解决的问题)

2.处理重影现象

重影现象其实也不是很好解决的说,很惭愧,我在做项目期间,这个重影问题困扰了我的软件好几个版本,直到最后几个快要终结的版本才基本上处理掉了这个麻头的问题

最新文章

  1. 如何让用户只能访问特定的数据库(MSSQL)
  2. Oracle创建表空间和用户
  3. 互联网4.0时代需要商业智能BI
  4. Python和Django在Windows上的环境搭建
  5. 查看mssql死锁的详细信息(存储过程)
  6. Android开发了解——Dalvik
  7. Python读入与写出中文时出现乱码
  8. 02-4. BCD解密(10)
  9. 第二节 EAN 8 码 / EAN 13 码
  10. int_float_double数据类型的存储格式。
  11. 《神秘的程序员们》漫画26~28:《万年坑系列》 I、II、III(转)
  12. Andrew Ng机器学习课程笔记--week7(SVM)
  13. Netty——高级发送和接收数据handler处理器
  14. 简述ADO.NET的连接层
  15. 【原创】sqlite ef6 踩坑
  16. java保留小数后两位的四种写法
  17. [JAVA]字节流拷贝文件
  18. ADO.Net操作数据库的方式
  19. CUDA Fortran for Scientists and Engineers第二版翻译
  20. GCC online documentation

热门文章

  1. WPF产生不重复的随机数
  2. sublime text3 英文版转为中文版
  3. Uva 11491 暴力贪心
  4. [USACO12FEB]牛券Cow Coupons
  5. Vision-Based Positioning for Internet-of-Vehicles
  6. 【洛谷P1879】玉米田Corn Fields
  7. Android学习笔记_65_登录功能本身没有任何特别
  8. docker官方文档翻译5
  9. SpringBoot非官方教程 | 第十五篇:Springboot整合RabbitMQ
  10. iOS | CAShapeLayer转场动画