</pre><p>由于要读取设备的数据,进而绘出数据的趋势图,所以需要不断的刷新屏幕进而进行读数据。但是由于刷屏一直会造成严重的闪屏,所以参照网上的方法,利用双缓冲技术进行函数重载绘制,但是一直仍旧闪屏,最后找到问题的根源,更改之后的效果确实良好,防止了屏幕出现闪屏,但是我的编码过程中也与网上的方法有稍稍不同,为了防止有人走我的弯路,在此将方法进行说明。首先,思想仍然是双缓冲的技术思想,但是由于要求是在控件中进行重载绘制,因此事不能牵扯到父窗口的绘制的。故此,选择重载函数OnPaint()进行图形的绘制。当进行重载之后,默认是</p><pre><p></p>
void CMY_Static::OnPaint() { CPaintDC dc(this); // device context for painting CRect rect;//设计整个绘图区域大小的矩形 }
<pre name="code" class="cpp">
所有的绘图操作全在其中,于是我们进行创建一个内存DC和一个获取当前控件DC的指针*pDC,当然还有画布MemBitmap;
CDC *pDC; CDC MemDC; //创建兼容的内存DC CBitmap MemBitmap; //创立画布之后由指针获取当前控件的DC
pDC=GetDC(); GetClientRect(&rect); //获取客户端区域大小 pDC=GetDC(); //选定与客户端区域大小相同的位置创建绘制位图 MemDC.CreateCompatibleDC(pDC); MemBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height()); MemDC.SelectObject(&MemBitmap); //将位图选进内存中 MemDC.SelectObject(&pen); MemDC.FillSolidRect(rect,RGB(255,255,255)); //现在开始你的所有绘画操作均可以进行,但是前提都是MemDC进行绘制的。 //设置左上角矩形范围 rect1.top=rect.top; rect1.left=rect.left; rect1.right=rect.left+50; rect1.bottom=rect.top+30; //设置左下角矩形范围 rect2.top=rect.bottom-30; rect2.left=rect.left; rect2.right=rect.left+50; rect2.bottom=rect.bottom; //绘制整个显示范围 // if (m_draw_flag) { //绘制左上角参数 MemDC.SelectStockObject(NULL_PEN); MemDC.Rectangle(rect1); MemDC.SetTextColor(RGB(0,0,255)); MemDC.DrawText(str1,rect1,0); //绘制左下角参数 MemDC.SelectStockObject(NULL_PEN); MemDC.Rectangle(rect2); MemDC.SetTextColor(RGB(255,0,0)); MemDC.DrawText(str2,rect2,0); } //绘制移动游标 CPoint start_point[5]; //游标的起始点 CBrush brush1; brush1.CreateSolidBrush(RGB(255,0,0)); MemDC.SelectObject(&brush1); start_point[0].x=rect.right-15; start_point[0].y=trend[0]*zoomy; start_point[1].x=rect.right-10; start_point[1].y=start_point[0].y-5; start_point[2].x=rect.right; start_point[2].y=start_point[0].y-5; start_point[3].x=rect.right; start_point[3].y=start_point[0].y+5; start_point[4].x=rect.right-10; start_point[4].y=start_point[0].y+5; MemDC.Polygon(start_point,5); //绘制趋势线性图 CPen m_trendpen; //绘制画笔 m_trendpen.CreatePen(PS_SOLID,2,RGB(255,0,0)); MemDC.SelectObject(&m_trendpen); int i=0; while(i<20) { MemDC.MoveTo(rect.right-15-zoomx*10*i,zoomy*trend[i]); MemDC.LineTo(rect.right-15-zoomx*10*(i+1),zoomy*trend[i+1]); i++; } //然后开始讲内存中已经绘制好的一次性全部呈现到屏幕上 pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);
之后是一些资源的删除释放。
整个过程要注意的是,千万不能够以OnPaint函数提供的dc进行绘制图形,否则就不是真正地双缓冲了,通知,创建一个指针指向当前的控件DC相对效率会高一些。
因为我在绘制窗口的时候,采用dc直接进行绘制的时候,发现仍有闪屏,而这点很多双缓冲技术上没有提及的!