MFC-对话框绘图

和绘图效率的一个重要相关因素是绘图引擎。Windows环境下二维绘图引擎有多种选择:GDI、GDI+、DirectDraw、QT、Agg、Cairo、skia、Direct2D、Direct3D、OpenGL等

使用 CDC 绘图

添加一个 Picture Control 设置 Notify 属性为 True

class My_Draw : public CStatic 
{

}

使用自定义控件

创建一个自定义控件,然后绑定一个 Wnd 子类,在子类里面绘图

填充背景

RECT rcClient;
GetClientRect(&rcClient);
// 填充客户区颜色
dc.FillSolidRect(&rcClient, RGB(0x99,0x99,0x99));

绘制矩形

矩形框,内部不填充

m_memDC.FrameRect(&m_rc_measure, m_spBrushWhite.get());

绘制多个点连线

if (FALSE == m_memDC.PolylineTo(&it.pt[0], it.pt.size()))
{
ASSERT(FALSE);
}

脏矩形

就是每次画面的刷新只更新需要更新的那一块区域

实际上,在OnDraw(CDC *pDC)中绘制的图并不是所有都显示了的,例如:你 在OnDraw中画了两个矩形,在一次重绘中虽然两个矩形的绘制函数都有执行,但是很有可能只有一个显示了,这是因为MFC本身为了提高重绘的效率设置了裁剪区。裁剪区的作用就是:只有在这个区内的绘图过程才会真正有效,在区外的是无效的,即使在区外执行了绘图函数也是不会显示的。因为多数情况下窗口重绘的产生大多是因为窗口部分被遮挡或者窗口有滚动发生,改变的区域并不是整个图形而只有一小部分,这一部分需要改变的就是pDC中的裁剪区了。因为显示(往内存或者显存都叫显示)比绘图过程的计算要费时得多,有了裁剪区后显示的就只是应该显示的部分,大大提高了显示效率。但是这个裁剪区是MFC设置的,它已经为我们提高了显示效率,在进行复杂图形的绘制时如何进一步提高效率呢?那就只有去掉在裁剪区外的绘图过程了。可以先用pDC->GetClipBox()得到裁剪区,然后在绘图时判断你的图形是否在这个区内,如果在就画,不在就不画。 如果你的绘图过程不复杂,这样做可能对你的绘图效率不会有提高。

invalidaterect()
想产生“区域无效”的系统消息的话,可以用GDI的,InvalidateRect或者ValidateRgn

闪烁问题

当窗口由于任何原因需要重绘时,总是先用背景色将显示区清除,然后才调用OnPaint进行重绘,而背景色往往与绘图内容反差很大,这样在短时间内背景色与显示图形的交替出现,使得显示窗口看起来在闪。

当窗口中有控件时,需要把窗口对话框属性Clip Children设置为True,这样在重绘父窗口时就不会刷新子控件的背景,否则界面重绘时控件由于重绘还是会发生闪烁。

然后重载窗口的OnEraseBkgnd()函数,使背景刷变成透明的,实现代码如下:

BOOL OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}

设置颜色

// 设置文字背景色
SetBkColor(hdc, RGB(0,0,0));
// 设置文字颜色
SetTextColor(hdc, RGB(255,255,255));

文本背景透明

SetBkMode(m_memDC, TRANSPARENT);

输出文本

// 居中显示
pDC->SetTextAlign( TA_BASELINE | TA_CENTER );
pDC->TextOut( rect.right / 2, rect.bottom / 2, s, s.GetLength() );

获取坐标值

POINT point;
// 获取鼠标指针位置(屏幕坐标)
GetCursorPos(&point);
// 将鼠标指针位置转换为窗口坐标
this->ScreenToClient(&point);

判断点是否在矩形内

if (PtInRect(&rc, itData.pt[i]));
{
//测试框内的数据

}