MFC绘制门电路
1. 设计内容、方法与难点
本课题设计的内容包括了基本门电路中与门和非门的绘制、选中以及它们之间的连接。具体采用的方法是在OnDraw函数里面进行绘制,并设计元器件基类,派生出与门和非门,并组合了一个引脚类,在这些类中进行移动、选中、连线的绘图刷新。
课题的难点有两个方面,一是绘制,对于不同的元器件,大多数的方法都是一致的,所以应该考虑继承于一个元器件基类;但是,每一种元器件的绘制方法不一样,那么就可以考虑用到多态的思想,即构造一个绘制的纯虚函数,可以实现绘制的统一性。除此之外,元器件都应该包含有自身的输入输出引脚,所以元器件基类应该与引脚类组合使用。
二是图像刷新时的闪烁问题。对于元器件的移动、连线等动作,都会使得全屏重绘一次,所以就会出现图像的闪烁问题。解决方案:
- 刚开始,我在所有鼠标事件响应函数末尾都加了重绘函数,所以就算鼠标只是在界面上移动不做任何点击操作都会出现闪烁问题,所以后来我在只有要进行操作、需要重绘的时候才加了重绘函数。
- 在用鼠标拖动选中的元器件时,记录下上次的矩形选中框和现在这次的矩形选中框,从这两个矩形共8个顶点中选出最左上角和最右下角的顶点得到一个同时包含两个矩形的矩形框(否则就选最左下角和最右上角的顶点),然后调用InvalidateRect函数只绘制该矩形框区域,也可以改善闪烁问题。
2. 作品特色
本作品的特点一是界面美观整洁;二是解决了拖动元器件时鼠标始终在元器件左上角的问题,计算鼠标移动的偏移量来计算元器件的偏移量,用这种方法来解决此问题;三是改善了绘制闪烁的问题。
3. 项目类设计
4. 重点函数简介
左键点击响应函数:主要实现了选中元器件和引脚以及引脚之间的连线。
void CGateCircuitDemoView::OnLButtonDown(UINT nFlags, CPoint point)
{
//当前已选中引脚,若鼠标又点击另一个元电器的引脚,则将两引脚连线
LineToPin(point);
if (m_flag)
{
m_flag = false;
return;
}
//根据鼠标点击的位置判断是否选中元器件或元器件上的引脚
SelectGateAndPin(point);
CView::OnLButtonDown(nFlags, point);
}
5. 运行结果
运行界面美观简洁,包括与门和非门的添加、选中、移动及引脚的连线等内容。
6. 有待解决的问题
- 已经连上的线不能取消
- 引脚之间只能通过直线连接,不能自动变成折线