01. CAD双缓冲绘图
# CAD
1. 什么时候绘制
1. WM_PAINT时绘制,MFC中是CMFCApplication1View::OnDraw时绘制
2. 在哪里绘制
1. DC
|
SDK |
MFC |
绘制区域 |
|
BeginPaint |
CPaintDC |
无效区 |
|
GetDC |
CClientDC |
客户区 |
|
GetWindowDC |
CWindowDC |
整个窗口 |
|
CreateCompatibleDC |
CDC |
内存 |
3. 如何绘制
1. InvalidateRect(hWnd, nullptr, TRUE);如果调用时传TRUE清除背景,就会导致闪烁。
2. 捕获鼠标SetCapture, ReleaseCapture
3. SDK用MoveToEx, MoveToEx绘制直线
4. 双缓冲步骤
SDK例子:
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
RECT rect = {};
GetClientRect(hWnd, &rect);
auto nWidth = rect.right - rect.left;
auto nHeight = rect.bottom - rect.top;
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP hBitMap = CreateCompatibleBitmap(hdc, nWidth, nHeight);
SelectObject(hdcMem, hBitMap);
FillRect(hdcMem, &rect, (HBRUSH)(RGB(255, 255, 255) + 1));
for (auto &pts : vec) {
MoveToEx(hdcMem, pts.first.x, pts.first.y, nullptr);
LineTo(hdcMem, pts.second.x, pts.second.y);
}
MoveToEx(hdcMem, ptBeg.x, ptBeg.y, nullptr);
LineTo(hdcMem, ptEnd.x, ptEnd.y);
BitBlt(hdc, 0, 0, nWidth, nHeight, hdcMem, 0, 0, SRCCOPY);
DeleteObject(hBitMap);
DeleteDC(hdcMem);
EndPaint(hWnd, &ps);
break;
}
MFC例子:
void CMFCApplication1View::OnDraw(CDC *pDC) {
CMFCApplication1Doc *pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CRect rcClient;
GetClientRect(&rcClient);
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
CBitmap bmpMem;
bmpMem.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
dcMem.SelectObject(&bmpMem);
dcMem.FillSolidRect(rcClient, RGB(255, 255, 255));
auto pos = m_lstLines.GetHeadPosition();
while (pos) {
auto line = m_lstLines.GetNext(pos);
dcMem.MoveTo(line.first);
dcMem.LineTo(line.second);
}
dcMem.MoveTo(m_ptBegin);
dcMem.LineTo(m_ptEnd);
pDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &dcMem, 0, 0, SRCCOPY);
}

浙公网安备 33010602011771号