HRESULT OnDraw(ATL_DRAWINFO& di)//改用双缓冲绘制,消除闪烁
{
RECT& rc = *(RECT*)di.prcBounds;
HDC& hdc = (HDC)di.hdcDraw; // 将剪辑区域设置为 di.prcBounds 指定的矩形
HRGN hRgnOld = NULL;
if (GetClipRgn(hdc, hRgnOld) != 1)
hRgnOld = NULL;
bool bSelectOldRgn = false; HRGN hRgnNew = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom); if (hRgnNew != NULL)
{
bSelectOldRgn = (SelectClipRgn(hdc, hRgnNew) != ERROR);
} //begin:
static HDC hdcmem = NULL;
static HBITMAP hbmp= NULL;
static HBITMAP holdbmp=NULL; int w = rc.right - rc.left;
int h = rc.bottom - rc.top; hdcmem = CreateCompatibleDC(hdc);
hbmp = CreateCompatibleBitmap(hdc,w,h);
holdbmp = (HBITMAP)SelectObject(hdcmem,(HGDIOBJ)hbmp);
//1:区域划分
SetRect(&rtcaption,rc.left,rc.top,rc.right,rc.top + ncaption);
SetRect(&rttop,rc.left+nleft ,rtcaption.bottom,rc.right-nright,rtcaption.bottom+ntop);
SetRect(&rtleft,rc.left,rtcaption.bottom,rc.left+nleft,rc.bottom);
SetRect(&rtright,rc.right- nright,rtleft.top,rc.right,rtleft.bottom);
SetRect(&rtbottom,rtleft.right,rc.bottom-nbottom,rtright.left,rc.bottom);
SetRect(&rtfill,rtleft.right ,rttop.bottom,rtright.left,rtbottom.top);
//2:坐标系定义
xyo.x = rtfill.left + 4;
xyo.y = rtfill.bottom - 4;
xyx.x = rtfill.right - 3;
xyx.y = xyo.y;
xyy.x = xyo.x;
xyy.y = rtfill.top + 3; //3:画背景
DrawBkGnd(hdcmem,rc); //4:区域渲染m_clrBackColor
DrawBorder(hdcmem,rc); //5:标题绘制
DrawTitle(hdcmem,rc); //6:曲线辅助网格
DrawGrid(hdcmem,rc); //7:XY坐标轴和XY轴文本
DrawXYName(hdcmem,rc);
//8:曲线
DrawCurve(hdcmem,rc);
BitBlt(hdc,0,0,w,h,hdcmem,0,0,SRCCOPY); SelectObject(hdcmem,(HGDIOBJ)holdbmp);
DeleteObject(hbmp);
ReleaseDC(hdcmem);
//end. if (bSelectOldRgn)
SelectClipRgn(hdc, hRgnOld); //DeleteObject(hRgnOld);
DeleteObject(hRgnNew); return S_OK;
}
{
RECT& rc = *(RECT*)di.prcBounds;
HDC& hdc = (HDC)di.hdcDraw; // 将剪辑区域设置为 di.prcBounds 指定的矩形
HRGN hRgnOld = NULL;
if (GetClipRgn(hdc, hRgnOld) != 1)
hRgnOld = NULL;
bool bSelectOldRgn = false; HRGN hRgnNew = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom); if (hRgnNew != NULL)
{
bSelectOldRgn = (SelectClipRgn(hdc, hRgnNew) != ERROR);
} //begin:
static HDC hdcmem = NULL;
static HBITMAP hbmp= NULL;
static HBITMAP holdbmp=NULL; int w = rc.right - rc.left;
int h = rc.bottom - rc.top; hdcmem = CreateCompatibleDC(hdc);
hbmp = CreateCompatibleBitmap(hdc,w,h);
holdbmp = (HBITMAP)SelectObject(hdcmem,(HGDIOBJ)hbmp);
//1:区域划分
SetRect(&rtcaption,rc.left,rc.top,rc.right,rc.top + ncaption);
SetRect(&rttop,rc.left+nleft ,rtcaption.bottom,rc.right-nright,rtcaption.bottom+ntop);
SetRect(&rtleft,rc.left,rtcaption.bottom,rc.left+nleft,rc.bottom);
SetRect(&rtright,rc.right- nright,rtleft.top,rc.right,rtleft.bottom);
SetRect(&rtbottom,rtleft.right,rc.bottom-nbottom,rtright.left,rc.bottom);
SetRect(&rtfill,rtleft.right ,rttop.bottom,rtright.left,rtbottom.top);
//2:坐标系定义
xyo.x = rtfill.left + 4;
xyo.y = rtfill.bottom - 4;
xyx.x = rtfill.right - 3;
xyx.y = xyo.y;
xyy.x = xyo.x;
xyy.y = rtfill.top + 3; //3:画背景
DrawBkGnd(hdcmem,rc); //4:区域渲染m_clrBackColor
DrawBorder(hdcmem,rc); //5:标题绘制
DrawTitle(hdcmem,rc); //6:曲线辅助网格
DrawGrid(hdcmem,rc); //7:XY坐标轴和XY轴文本
DrawXYName(hdcmem,rc);
//8:曲线
DrawCurve(hdcmem,rc);
BitBlt(hdc,0,0,w,h,hdcmem,0,0,SRCCOPY); SelectObject(hdcmem,(HGDIOBJ)holdbmp);
DeleteObject(hbmp);
ReleaseDC(hdcmem);
//end. if (bSelectOldRgn)
SelectClipRgn(hdc, hRgnOld); //DeleteObject(hRgnOld);
DeleteObject(hRgnNew); return S_OK;
}
void DrawBkGnd(HDC& hdc,RECT& rc)//画背景
{
COLORREF clbk;
OleTranslateColor(m_clrBackColor,NULL,&clbk);
HBRUSH hbr;
hbr = CreateSolidBrush(clbk); FillRect(hdc,&rc,hbr); DeleteObject(hbr);
}
void DrawBorder(HDC& hdc,RECT& rc)//画四周边框
{
HBRUSH hbr;
hbr = CreateSolidBrush(RGB(192,192,192)); FillRect(hdc,&rtcaption,hbr);
FillRect(hdc,&rttop,hbr);
FillRect(hdc,&rtleft,hbr);
FillRect(hdc,&rtright,hbr);
FillRect(hdc,&rtbottom,hbr);
DeleteObject(hbr);
COLORREF cl;
OleTranslateColor(m_clrFillColor,NULL,&cl);
hbr = CreateSolidBrush(cl);
FillRect(hdc,&rtfill,hbr);
DeleteObject(hbr);
}
void DrawTitle(HDC& hdc,RECT& rc)//画标题
{
USES_CONVERSION; SetBkMode(hdc,1);//文字透明背景模式 COLORREF cltitle,clold;
OleTranslateColor(m_CaptionColor,NULL,&cltitle);
clold = SetTextColor(hdc,cltitle);
HFONT hft,holdft; hft = CreateFont(int((ncaption)*70/100),0,0,0,600,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"楷体_GB2312");
holdft = (HFONT)SelectObject(hdc,HGDIOBJ(hft)); DrawText(hdc,OLE2CT(m_bstrCaption),lstrlen(OLE2CT(m_bstrCaption)),&rtcaption,DT_CENTER|DT_SINGLELINE|DT_VCENTER);
SelectObject(hdc,HGDIOBJ(holdft));
DeleteObject(hft); SetTextColor(hdc,clold);
}
void DrawXYName(HDC& hdc,RECT& rc)//XY坐标轴和Y轴文本
{
USES_CONVERSION; char str[12];
RECT rttemp;
COLORREF cltemp,clold;
SIZE sz; HPEN hpxy,hpold;
HFONT hft,holdft; int cx = xyx.x-xyo.x;
int cy = xyo.y - xyy.y ; OleTranslateColor(m_XYAxisColor,NULL,&cltemp);//XY轴及刻度Y文本
hpxy = CreatePen(PS_SOLID,m_LineWidth+1,cltemp);
hpold = (HPEN)SelectObject(hdc,(HGDIOBJ)hpxy); //XY轴线
MoveToEx(hdc,xyo.x ,xyo.y ,NULL);
LineTo(hdc,xyx.x,xyx.y);
MoveToEx(hdc,xyo.x ,xyo.y ,NULL);
LineTo(hdc,xyy.x,xyy.y); //刻度
for(int i=0;i<m_XPrValue;++i)//x
{
MoveToEx(hdc,xyo.x + (i+1)*(cx)/m_XPrValue+1,xyo.y,NULL);
LineTo(hdc,xyo.x + (i+1)*(cx)/m_XPrValue+1,xyo.y - 3);
}
for(int j=0;j<m_YPrValue;++j)//y
{
MoveToEx(hdc,xyo.x,xyo.y - (j+1)*(cy)/m_YPrValue, NULL);
LineTo(hdc,xyo.x+ 3,xyo.y - (j+1)*(cy)/m_YPrValue);
} SelectObject(hdc,(HPEN)hpold);
DeleteObject(hpxy);
//XY轴文本
hft = CreateFont(int((ntop)*85/100),0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"宋体_GB2312");
if(!hft)
{
return;
}
holdft = (HFONT)SelectObject(hdc,HGDIOBJ(hft)); if(S_OK == OleTranslateColor(m_XYNameColor,NULL,&cltemp))
{
clold = SetTextColor(hdc,cltemp);
}
else
{
clold = SetTextColor(hdc,RGB(255,255,255));
} DrawText(hdc,OLE2CT(m_YName),lstrlen(OLE2CT(m_YName)),&rttop,DT_LEFT|DT_SINGLELINE|DT_VCENTER); GetTextExtentPoint(hdc,OLE2CT(m_XName),lstrlen(OLE2CT(m_XName)),&sz);
rttemp.left = rtbottom.right - 3*sz.cx/2;
rttemp.bottom = rtbottom.bottom - 6;
rttemp.top = rttemp.bottom - sz.cy;
rttemp.right = rtbottom.right -6;
DrawText(hdc,OLE2CT(m_XName),lstrlen(OLE2CT(m_XName)),&rttemp,DT_CENTER|DT_SINGLELINE|DT_VCENTER);
SelectObject(hdc,HGDIOBJ(holdft));
DeleteObject(hft);
//Y轴刻度文本
for(int j=0;j<m_YPrValue+1;++j)
{
if(j%m_YnShow == 0)
{
wsprintf(str,"%d",j*m_YRange/m_YPrValue);
GetTextExtentPoint(hdc,str,strlen(str),&sz);
rttemp.left = rtleft.left;
rttemp.right =rtleft.right;
rttemp.top = xyo.y - j*(cy)/m_YPrValue +sz.cy/2;
rttemp.bottom = xyo.y - j*(cy)/m_YPrValue -sz.cy/2;
DrawText(hdc,str,strlen(str),&rttemp,
DT_RIGHT|DT_SINGLELINE|DT_VCENTER);
}
}
SetTextColor(hdc,clold);
}
void DrawXYAxis(HDC& hdc,RECT& rc)//画XY轴
{
}
void DrawGrid(HDC& hdc,RECT& rc)//画辅助网格
{
HPEN hpgrid,hpgridold;
COLORREF grid;
int cx = xyx.x-xyo.x;
int cy = xyo.y - xyy.y; if(S_OK == OleTranslateColor(m_GridLineColor,NULL,&grid))
{
hpgrid = CreatePen(PS_DOT,1,grid);
}
else
{
hpgrid = CreatePen(PS_DOT,1,RGB(255,255,255));
} if(hpgrid)
{
hpgridold = (HPEN)SelectObject(hdc,(HGDIOBJ)hpgrid); for(int m=0;m<m_XPrValue;++m)//垂直线
{
MoveToEx(hdc,xyo.x + (m+1)*(cx)/m_XPrValue ,xyo.y,NULL);
LineTo(hdc,xyo.x + (m+1)*(cx)/m_XPrValue ,xyy.y);
}
for(int n=0;n<m_YPrValue;++n)//水平线
{
MoveToEx(hdc,xyo.x,xyo.y - (n+1)*(cy)/m_YPrValue,NULL);
LineTo(hdc,xyx.x,xyo.y - (n+1)*(cy)/m_YPrValue);
}
SelectObject(hdc,(HGDIOBJ)hpgridold);
DeleteObject(hpgrid);
}
}
void DrawCurve(HDC& hdc,RECT& rc)//画曲线
{
USES_CONVERSION; char str[12];
COLORREF cltemp,clold;
SIZE sz;
RECT rttemp;
HFONT hft,holdft;
HPEN hpxy,hpold; int cx = xyx.x-xyo.x;
int cy = xyo.y - xyy.y; hft = CreateFont((ntop)*85/100,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,"宋体_GB2312");
holdft = (HFONT)SelectObject(hdc,HGDIOBJ(hft));
OleTranslateColor(m_XYNameColor,NULL,&cltemp);
clold = SetTextColor(hdc,cltemp); //本地时间
SYSTEMTIME systm;
GetLocalTime(&systm);
char tm[60];
if(m_bDynamic == VARIANT_TRUE)
{
wsprintf(tm,"Dynamic:%2d:%2d:%2d count=%d",systm.wHour,systm.wMinute,systm.wSecond,count);
DrawText(hdc,tm,lstrlen(tm),&rttop,DT_RIGHT|DT_SINGLELINE|DT_VCENTER);
}
SelectObject(hdc,HGDIOBJ(holdft));
DeleteObject(hft); //X轴刻度文本
for(int k=0;k<m_XPrValue+1;++k)
{
if(k%m_XnShow == 0)
{
wsprintf(str,"%d",k*m_XRange/m_XPrValue);
GetTextExtentPoint(hdc,str,strlen(str),&sz);
rttemp.left = xyo.x + (k)*(cx)/m_XPrValue+1 - sz.cx/2;
rttemp.right =xyo.x + (k)*(cx)/m_XPrValue+1 + sz.cx/2;
rttemp.top = rtbottom.top;
rttemp.bottom =rtbottom.bottom;
DrawText(hdc,str,strlen(str),&rttemp,
DT_CENTER|DT_SINGLELINE|DT_TOP);
}
}
SetTextColor(hdc,clold);
//:去掉无用点
int vptcount=0;
for(int d=0;d<m_XPrValue*m_XnDots;++d)
{
if(m_xypt[d].x == 1)
{
++vptcount;
}
} POINT pt[256];// = new POINT[vptcount];
int nptcount = 0;
for(int r=0;r<m_XPrValue*m_XnDots;++r)
{
if(m_xypt[r].x == 1)
{
pt[nptcount].x = r;
pt[nptcount].y = m_xypt[r].y;
++nptcount;
}
} for(int k=0;k<vptcount;++k)
{
pt[k].x = xyo.x + pt[k].x*(xyx.x - xyo.x)/(m_XPrValue*m_XnDots);
pt[k].y = xyo.y - pt[k].y*(xyo.y - xyy.y)/m_YRange;
}
if(S_OK == OleTranslateColor(m_LineColor,NULL,&cltemp))
{
hpxy = CreatePen(PS_SOLID,m_LineWidth,cltemp);
}
else
{
hpxy = CreatePen(PS_SOLID,m_LineWidth,RGB(255,255,255));
}
hpold = (HPEN)SelectObject(hdc,(HGDIOBJ)hpxy);
Polyline(hdc,pt,vptcount);
SelectObject(hdc,(HGDIOBJ)hpold);
DeleteObject(hpxy); //delete []pt;
}
即使把里面DrawX都注释掉还是漏,
{
// RECT& rc = *(RECT*)di.prcBounds;
// HDC& hdc = (HDC)di.hdcDraw; // 将剪辑区域设置为 di.prcBounds 指定的矩形
HRGN hRgnOld = NULL;
if (GetClipRgn(hdc, hRgnOld) != 1)
hRgnOld = NULL;
bool bSelectOldRgn = false;
HRGN hRgnNew = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
if (hRgnNew != NULL)
{
bSelectOldRgn = (SelectClipRgn(hdc, hRgnNew) != ERROR);
}
//begin:
static HDC hdcmem = NULL;
static HBITMAP hbmp= NULL;
static HBITMAP holdbmp=NULL;
int w = rc.right - rc.left;
int h = rc.bottom - rc.top;
hdcmem = CreateCompatibleDC(hdc);
hbmp = CreateCompatibleBitmap(hdc,w,h);
holdbmp = (HBITMAP)SelectObject(hdcmem,(HGDIOBJ)hbmp);
BitBlt(hdc,0,0,w,h,hdcmem,0,0,SRCCOPY);
::SelectObject(hdcmem,(HGDIOBJ)holdbmp);
::DeleteObject(hbmp);
::ReleaseDC(hwnd,hdcmem);
//end.
if (bSelectOldRgn)
SelectClipRgn(hdc, hRgnOld);
//DeleteObject(hRgnOld);
DeleteObject(hRgnNew);
return S_OK;
}