16,472
社区成员
发帖
与我相关
我的任务
分享
CPoint m_ArySin[1000];//存放sin曲线点坐标的数组,X:0~2PI,Y:-1~+1
void CPage1::OnTimer(UINT_PTR nIDEvent)
{
// TODO: Add your message handler code here and/or call default
switch (nIDEvent)
{
case 1:
CBitmap memBitmap;//内存绘图
CBitmap* pOldBmp = NULL;//内存绘图
CRect rect; //控件区域
//获取空间区域DC
CWnd* pWnd = GetDlgItem(IDC_STATIC1);//控件窗口
pWnd->GetClientRect(&rect);//控件客户区
m_pDC = pWnd->GetDC();//获取控件DC
//坐标转换
m_pDC->SetMapMode(MM_ANISOTROPIC);//设置map模式
m_pDC->SetWindowExt(rect.right, -rect.bottom);//设置窗口尺寸,逻辑单位
m_pDC->SetViewportExt(rect.right, rect.bottom);//设置视口尺寸,物理单位
m_pDC->SetViewportOrg(0, rect.bottom/2);//设置设备坐标原点
//m_pDC->SetWindowOrg(0, rect.bottom/2);//设置逻辑坐标原点
//创建内存绘图设备
m_memDC.CreateCompatibleDC(m_pDC);
memBitmap.CreateCompatibleBitmap(m_pDC,rect.right,rect.bottom);
pOldBmp = m_memDC.SelectObject(&memBitmap);
/*
//坐标转换
m_memDC.SetMapMode(MM_ANISOTROPIC);//设置map模式
m_memDC.SetWindowExt(rect.right, rect.bottom);//设置窗口尺寸,逻辑单位
m_memDC.SetViewportExt(rect.right, -rect.bottom);//设置视口尺寸,物理单位
m_memDC.SetViewportOrg(0, rect.bottom/2);//设置设备坐标原点
//m_memDC.SetWindowOrg(0, rect.bottom/2);//设置逻辑坐标原点
*/
//绘图
CPen Pen;
CPen* pOldPen;
Pen.CreatePen(PS_SOLID, 1, RGB(255,255,0));
pOldPen = m_memDC.SelectObject(&Pen);
//画线
m_memDC.Polyline(m_ArySin, m_nTime1Cnt);
m_memDC.SelectObject(pOldPen);
Pen.DeleteObject();
//内存拷贝到屏幕
m_pDC->BitBlt(0,0,rect.right,rect.bottom,&m_memDC,0,0,SRCCOPY);
//析构
m_memDC.SelectObject(pOldBmp);
m_memDC.DeleteDC();
memBitmap.DeleteObject();
m_nTime1Cnt += 1;
if(m_nTime1Cnt==165)
{
KillTimer(1);
}
break;
}
CDialogEx::OnTimer(nIDEvent);
}
//逻辑坐标系和设备坐标系比例1:1,Y轴方向相反
//设备坐标系原点设为(0, rect.bottom/2),也就是设备坐标系向下平移rect.bottom/2个单位。
m_pDC->SetWindowExt(rect.right, -rect.bottom);//设置窗口尺寸,逻辑单位
m_pDC->SetViewportExt(rect.right, rect.bottom);//设置视口尺寸,物理单位
m_pDC->SetViewportOrg(0, rect.bottom/2);//设置设备坐标原点
那这个时候要把memDC的图拷贝到pDC中是,BitBlt函数就应该这样写:
m_pDC->BitBlt(0,-rect.bottom/2,rect.right,rect.bottom,&m_memDC,0,-rect.bottom/2,SRCCOPY);
注意观察红色部分的参数,按照MSDN的解释,第一个红色参数应该是目标DC的左上角的逻辑Y坐标,因为在坐标变换中我并没有改动逻辑坐标的原点,所以我本来以为这里设置为0,但是实际操作下来如果设为0就错了,只有设为-rect.bottom/2才能正确动作,那这个-rect.bottom/2明显是一个负数,看上去其实更像设备坐标系下的坐标,而且是目标DC的左下角的Y坐标,由此可以推断,如果你做了坐标变换,那么BitlBlt的坐标参数应该是设备坐标系下的,起始点的参数。换句话说,如果你设备坐标系的Y轴是向上的,那么X,Y就应该是左下角的坐标,而不是左上角的。不知道我说清楚了没有,自己都晕了,唉。。。
//绘制坐标X轴.
POINT ps = {100,200};
dc.MoveTo(ps);
ps.x = 500;
ps.y = 200;
dc.LineTo(ps);
for(double i=0; i<360; i+=1.0f)
{
int y = sin(i*3.14159f/180.0f)*100.0f; //把0-1扩展到0-100;
int x = (int)i;
dc.SetPixel(x+100, -y+200, RGB(255,0,0)); //原点移动到屏幕 100,200处
}
m_pDC->BitBlt(0,0,rect.right,rect.bottom,&m_memDC,0,0,SRCCOPY);
第二个参数是目标DC的Y坐标,个人感觉这里应该是0,因为我并没有改变逻辑坐标呵,当然应该从Y=0的位置开始覆盖呵,但是实际效果貌似并非如此,这是为什么呢?
3,为什么内存DC里负数部分没有被画出来?