MFC中CAD绘制

CAD

绘图时机

当WM_PAINT消息来的时候,会交给onDraw函数来处理绘图消息

双缓冲绘图

概念

先在内存中绘制图片,然后将图片贴到窗口上

  • 目的:为了解决绘图过程中,旧的图像重复擦除,重新绘制时产生的屏幕闪烁问题

绘制流程

  1. 创建一个内存DC,第一个缓冲区
  2. 创建一个内存位图,作为绘图的画布,第二个缓冲区
  3. 将内存位图选入内存DC,把两个内存关联到一起(内存DC的会先在内存位图上绘制
  4. 在内存DC中绘制图形
  5. 贴图,将内存DC中的绘制好的内存位图(图形)贴到窗口

// 1. 创建一个内存DC
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);

//内存中设置透明画刷
dcMem.SelectStockObject(NULL_BRUSH);

//获取客户区的大小
CRect rcClient;
GetClientRect(&rcClient); 

// 2. 创建一个内存位图, 作为绘图的画布
CBitmap bmpMem;
//使用客户区初始化位图
bmpMem.CreateCompatibleBitmap(pDC,
    rcClient.Width(),
    rcClient.Height());

// 3. 将内存位图选入内存DC
dcMem.SelectObject(&bmpMem);

//将内存的背景色设为客户区的背景色
dcMem.FillSolidRect(&rcClient, pDC->GetBkColor());

//根据颜色属性,选择设置内存的背景颜色
//dcMem.FillSolidRect(&rcClient, RGB(0, 255, 0));

// 4. 在内存DC中绘制图形
//绘制保存的直线
POSITION posLine = m_lstLines.GetHeadPosition();

//绘制保存的矩形
POSITION posRECT = m_lstRect.GetHeadPosition();

//将保存的直线绘制到内存中
while (posLine)
{
    DrawPosit& line = m_lstLines.GetNext(posLine);
    dcMem.MoveTo(line.m_ptBegin);
    dcMem.LineTo(line.m_ptEnd);
}

//将保存的矩形绘制到内存中
while (posRECT)
{
    DrawPosit& line = m_lstRect.GetNext(posRECT);
    dcMem.Rectangle(line.m_ptBegin.x, line.m_ptBegin.y,
        line.m_ptEnd.x, line.m_ptEnd.y);
}

//绘制当前直线
if (m_nDrawType == 1)
{
    dcMem.MoveTo(m_ObjectCurrent.m_ptBegin);
    dcMem.LineTo(m_ObjectCurrent.m_ptEnd);
}

//绘制当前矩形
if (m_nDrawType == 0)
{
    dcMem.Rectangle(m_ObjectCurrent.m_ptBegin.x, m_ObjectCurrent.m_ptBegin.y,
                    m_ObjectCurrent.m_ptEnd.x, m_ObjectCurrent.m_ptEnd.y);
}

pDC->SelectStockObject(NULL_BRUSH);

// 5. 贴图, 将内存DC中的图形贴到窗口
pDC->BitBlt(0, 0,  //拷贝到客户区的位置
    rcClient.Width(), rcClient.Height(),//拷贝的大小
    &dcMem,  //从内存DC拷贝
    0, 0,    //从内存DC的左上角拷贝
    SRCCOPY);

部分API

  • SetCapture: 设置窗口,当鼠标移除窗口外的时候,仍然可以接受到鼠标消息
  • ReleaseCaptur: 释放窗口外的鼠标信息捕获,并恢复通常的鼠标输入处理
    
SetCapture();     // 接受窗口外的鼠标消息 
ReleaseCapture(); //不再接受窗口外的鼠标消息

  • 绘制直线
    • MoveTo:直线起点
    • LineTo:直线终点
//绘制当前直线
if (m_nDrawType == 1)
{
    dcMem.MoveTo(m_ObjectCurrent.m_ptBegin);
    dcMem.LineTo(m_ObjectCurrent.m_ptEnd);
}
  • 绘制矩形
//绘制当前矩形
if (m_nDrawType == 0)
{
    dcMem.Rectangle(m_ObjectCurrent.m_ptBegin.x, //起点横坐标
                    m_ObjectCurrent.m_ptBegin.y, //起点纵坐标
                    m_ObjectCurrent.m_ptEnd.x,   //终点横坐标
                    m_ObjectCurrent.m_ptEnd.y);  //终点纵坐标
}

你可能感兴趣的:(MFC)