📄 imageboardview.cpp
字号:
(point.y < 0 || point.y > rcClient.bottom))
{
nScrollY += point.y;
nScrollY = BOUND(nScrollY, nMinY, nMaxY);
SetScrollPos(SB_VERT, nScrollY);
bNeedRedraw = TRUE;
}
if (bNeedRedraw)
{
// redraw
Invalidate(FALSE);
UpdateWindow();
}
// normalize point coordinate
if (AdjustPointinDib(point))
{
ClientToScreen(&point);
SetCursorPos(point.x, point.y);
ScreenToClient(&point);
}
}
// use client coordinates
CPoint ptStart(m_ptStart);
DibToClient(ptStart);
// set new rectangle
if (point.x < ptStart.x)
{
m_rcRubber.left = point.x;
m_rcRubber.right = ptStart.x;
}
else
{
m_rcRubber.left = ptStart.x;
m_rcRubber.right = point.x;
}
if (point.y < ptStart.y)
{
m_rcRubber.top = point.y;
m_rcRubber.bottom = ptStart.y;
}
else
{
m_rcRubber.top = ptStart.y;
m_rcRubber.bottom = point.y;
}
m_rcRubber.NormalizeRect();
// draw new rectangle
DoDrawRubber(&dc, m_rcRubber);
// restore
dc.SelectObject(pOldPen);
dc.SetROP2(nOldRop);
}
void CImageBoardView::StopDrawRubber()
{
if (m_nDrawType == DT_SELECT || m_nDrawType == DT_TEXT)
{
m_rcClip = m_rcRubber;
// if there is rectangle drawn, clear it
if (! m_rcClip.IsRectEmpty())
{
// get DC and set its ROP
CClientDC dc(this);
int OldRop = dc.SetROP2(R2_NOTXORPEN);
// define used pen
CPen pen(PS_DOT, 1, RGB(0,0,0));
CPen* pOldPen = dc.SelectObject(&pen);
// draw to clear
DoDrawRubber(&dc, m_rcClip);
// restore
dc.SetROP2(OldRop);
dc.SelectObject(pOldPen);
}
if (m_nDrawType == DT_TEXT)
{
// empty clip area
m_rcClip.SetRectEmpty();
CRect rc = m_rcRubber;
CClientDC dc(this);
CFont *pOldFont = dc.SelectObject(m_pFont);
CRect rcLetter(0,0,1,1);
int nHeight = dc.DrawText(_T("中"),&rcLetter, DT_CALCRECT);
int nWidth = 4*rcLetter.Width();
dc.SelectObject(pOldFont);
if (rc.Height() < nHeight)
rc.bottom = rc.top + nHeight;
if (rc.Width() < nWidth)
rc.right = rc.left + nWidth;
ClientToDib(rc);
if (rc.bottom > m_pDib->GetHeight())
rc.bottom = m_pDib->GetHeight();
if (rc.right > m_pDib->GetWidth())
rc.right = m_pDib->GetWidth();
DibToClient(rc);
DWORD style = ES_LEFT;
if (m_nTextAlign == DT_LEFT)
style = ES_LEFT;
else if (m_nTextAlign == DT_CENTER)
style = ES_CENTER;
else if (m_nTextAlign == DT_RIGHT)
style = ES_RIGHT;
m_EditText.Create(style|WS_VISIBLE|WS_CHILD|ES_MULTILINE,
rc,
this,
IDC_EDIT);
rc.InflateRect(2,2);
InvalidateRect(&rc);
m_EditText.SetFont(m_pFont);
m_EditText.SetFocus();
}
}
else
{
// if there is rectangle drawn, clear it
CClientDC dc(this);
CPen pen(m_nPenStyle, m_nPenWidth, m_crPenColor);
int nOldRop = dc.SetROP2(R2_NOTXORPEN);
CPen* pOldPen = dc.SelectObject(&pen);
DoDrawRubber(&dc, m_rcRubber);
dc.SetROP2(nOldRop);
dc.SelectObject(pOldPen);
// draw on dib
CRect rc = m_rcRubber;
ClientToDib(rc);
CBrush brush(m_crFillColor);
CBrush* pOldBrush;
CDC * pDibDC = m_pDib->BeginPaint(&dc);
pOldPen = pDibDC->SelectObject(&pen);
if (m_nDrawType == DT_RECT_F ||
m_nDrawType == DT_ROUNDRECT_F ||
m_nDrawType == DT_ELLIP_F)
{
pOldBrush = pDibDC->SelectObject(&brush);
}
else
pOldBrush = dc.SelectObject(CBrush::FromHandle((HBRUSH)GetStockObject(HOLLOW_BRUSH)));
switch(m_nDrawType)
{
case DT_LINE:
{
if (m_ptStart == rc.TopLeft() ||
m_ptStart == rc.BottomRight())
{
pDibDC->MoveTo(rc.TopLeft());
pDibDC->LineTo(rc.BottomRight());
}
else
{
pDibDC->MoveTo(rc.right, rc.top);
pDibDC->LineTo(rc.left, rc.bottom);
}
}
break;
case DT_RECT_H:
case DT_RECT_F:
pDibDC->Rectangle(&rc);
break;
case DT_ROUNDRECT_H:
case DT_ROUNDRECT_F:
pDibDC->RoundRect(&rc, CPoint((int)(rc.Width()/3), (int)(rc.Height()/3)));
break;
case DT_ELLIP_H:
case DT_ELLIP_F:
pDibDC->Ellipse(&rc);
break;
}
pDibDC->SelectObject(pOldPen);
pDibDC->SelectObject(pOldBrush);
m_pDib->EndPaint();
Invalidate(FALSE);
}
// release capture mouse
ReleaseCapture();
}
BOOL CImageBoardView::PointInDib(CPoint point)
{
if (m_pDib->IsEmpty())
return FALSE;
ClientToDib(point);
CRect rcDib(0, 0, m_pDib->GetWidth(), m_pDib->GetWidth());
return rcDib.PtInRect(point);
}
BOOL CImageBoardView::MergeText()
{
if (! ::IsWindow(m_EditText.m_hWnd))
return FALSE;
CString s;
m_EditText.GetWindowText(s);
CRect rc;
m_EditText.GetWindowRect(&rc);
ScreenToClient(&rc);
CRect rcClear = rc;
rcClear.InflateRect(3,3);
m_EditText.DestroyWindow();
InvalidateRect(&rcClear);
// Merge Text into DIB
if (! s.IsEmpty())
{
CClientDC dc(this);
CDC * pDibDC = m_pDib->BeginPaint(&dc);
int nOldBkMode = pDibDC->SetBkMode(TRANSPARENT);
COLORREF crOldTextColor = pDibDC->SetTextColor(m_crPenColor);
CFont *pOldFont = pDibDC->SelectObject(m_pFont);
// needed rectangle
ClientToDib(rc);
if (rc.bottom > m_pDib->GetHeight())
rc.bottom = m_pDib->GetHeight();
if (rc.right > m_pDib->GetWidth())
rc.right = m_pDib->GetWidth();
pDibDC->DrawText(s, &rc, m_nTextAlign);
pDibDC->SetBkMode(nOldBkMode);
pDibDC->SetTextColor(crOldTextColor);
pDibDC->SelectObject(pOldFont);
m_pDib->EndPaint();
}
return TRUE;
}
void CImageBoardView::OnLButtonDown(UINT nFlags, CPoint point)
{
if (PointInDib(point))
{
// Merge and delete old float DIB (if exist)
MergeFloatDib();
// if ther is text, just merge it into DIB
if (! MergeText()) // else, do paint
{
if (m_nDrawType == DT_FREELINE)
{
m_bDrawFreeline = TRUE;
m_ptFreelineStart = point;
SetCapture();
// set a pixel anyway
CClientDC dc(this);
ClientToDib(point);
CDC * pDibDC = m_pDib->BeginPaint(&dc);
pDibDC->SetPixel(point, m_crPenColor);
m_pDib->EndPaint();
Invalidate(FALSE);
}
else if (m_nDrawType == DT_ERASER)
{
m_bErasing = TRUE;
SetCapture();
// set a pixel anyway
CClientDC dc(this);
ClientToDib(point);
CRect rc(point.x-4, point.y-4, point.x+4, point.y+4);
CDC * pDibDC = m_pDib->BeginPaint(&dc);
CBrush brush(m_crFillColor);
CBrush *pOldBrush = pDibDC->SelectObject(&brush);
CPen Pen(PS_SOLID, 1, m_crFillColor);
CPen *pOldPen = pDibDC->SelectObject(&Pen);
pDibDC->Ellipse(&rc);
pDibDC->SelectObject(pOldPen);
pDibDC->SelectObject(pOldBrush);
m_pDib->EndPaint();
Invalidate(FALSE);
}
else if (m_nDrawType == DT_PICKER)
{
CClientDC dc(this);
COLORREF crColor = dc.GetPixel(point);
CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
ASSERT_KINDOF(CMainFrame, pAppFrame);
if (pAppFrame->m_wndPaintParamBar.m_nSelectColorMode == PP_FILL_COLOR)
{
m_crFillColor = crColor;
ShowFillColor();
}
else if (pAppFrame->m_wndPaintParamBar.m_nSelectColorMode == PP_PEN_COLOR)
{
m_crPenColor = crColor;
ShowPenColor();
}
}
else if (m_nDrawType == DT_FILL)
{
CBrush brush(m_crFillColor);
CClientDC dc(this);
COLORREF crColor = dc.GetPixel(point);
CBrush* pOldBrush = dc.SelectObject(&brush);
dc.ExtFloodFill(point.x, // x-coordinate where filling begins
point.y, // y-coordinate where filling begins
crColor, // fill color
FLOODFILLSURFACE); // fill type
dc.SelectObject(pOldBrush);
ClientToDib(point);
CDC * pDibDC = m_pDib->BeginPaint(&dc);
pOldBrush = pDibDC->SelectObject(&brush);
pDibDC->ExtFloodFill(point.x, // x-coordinate where filling begins
point.y, // y-coordinate where filling begins
crColor, // fill color
FLOODFILLSURFACE); // fill type
pDibDC->SelectObject(pOldBrush);
m_pDib->EndPaint();
}
else if (m_nDrawType == DT_CURVE)
{
if (! m_bDrawCurve)
{
m_bDrawCurve = TRUE;
m_nDrawCurveStep = 1;
m_ptCurve[0] = point;
m_ptCurve[1] = point;
m_ptCurve[2] = point;
m_ptCurve[3] = point;
// capture mouse
::SetCursor(m_hCursorCurve);
SetCapture();
}
else
{
CRect rc;
GetClientRect(&rc);
if (! rc.PtInRect(point))
{
DrawTmpCurve();
m_bDrawCurve = FALSE;
ReleaseCapture();
::SetCursor(m_hCursorGeneralDraw);
}
else
{
DrawTmpCurve();
if (m_nDrawCurveStep == 2)
m_ptCurve[2] = point;
else if (m_nDrawCurveStep == 3)
m_ptCurve[1] = point;
DrawTmpCurve();
}
}
}
else
{
if (m_nDrawType == DT_LINE)
{
// set a pixel anyway
CClientDC dc(this);
dc.SetPixel(point, m_crPenColor);
ClientToDib(point);
CDC * pDibDC = m_pDib->BeginPaint(&dc);
pDibDC->SetPixel(point, m_crPenColor);
m_pDib->EndPaint();
}
// start draw rectangle
StartDrawRubber(point);
m_bDrawingRubber = TRUE;
}
}
}
CScrollView::OnLButtonDown(nFlags, point);
}
void CImageBoardView::OnMouseMove(UINT nFlags, CPoint point)
{
SetStatusBarCursorPosition(point);
// change rectangle
if (m_bDrawingRubber)
DrawRubber(point);
if (m_bDrawCurve && nFlags == MK_LBUTTON)
{
DrawTmpCurve();
if (m_nDrawCurveStep == 1)
m_ptCurve[3] = point;
else if (m_nDrawCurveStep == 2)
m_ptCurve[2] = point;
else if (m_nDrawCurveStep == 3)
m_ptCurve[1] = point;
DrawTmpCurve();
}
// draw FREELINE
if (m_bDrawFreeline)
{
CPen pen(m_nPenStyle, m_nPenWidth, m_crPenColor);
CClientDC dc(this);
CPoint pt = point;
ClientToDib(m_ptFreelineStart);
ClientToDib(pt);
CDC * pDibDC = m_pDib->BeginPaint(&dc);
CPen* pOldPen = pDibDC->SelectObject(&pen);
pDibDC->MoveTo(m_ptFreelineStart);
pDibDC->LineTo(pt);
pDibDC->SelectObject(pOldPen);
m_pDib->EndPaint();
Invalidate(FALSE);
// new start point
m_ptFreelineStart = point;
}
else if (m_bErasing)
{
// set a pixel anyway
CClientDC dc(this);
ClientToDib(point);
CRect rc(point.x-4, point.y-4, point.x+4, point.y+4);
CDC * pDibDC = m_pDib->BeginPaint(&dc);
CBrush brush(m_crFillColor);
CBrush *pOldBrush = pDibDC->SelectObject(&brush);
CPen Pen(PS_SOLID, 1, m_crFillColor);
CPen *pOldPen = pDibDC->SelectObject(&Pen);
pDibDC->Ellipse(&rc);
pDibDC->SelectObject(pOldPen);
pDibDC->SelectObject(pOldBrush);
m_pDib->EndPaint();
Invalidate(FALSE);
}
CScrollView::OnMouseMove(nFlags, point);
}
void CImageBoardView::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bDrawFreeline)
{
m_bDrawFreeline = FALSE;
ReleaseCapture();
}
else if (m_bErasing)
{
m_bErasing = FALSE;
ReleaseCapture();
}
else if (m_bDrawCurve)
{
m_nDrawCurveStep++;
// finish draw curve
if (m_nDrawCurveStep > 3)
{
ReleaseCapture();
::SetCursor(m_hCursorGeneralDraw);
m_bDrawCurve = FALSE;
DrawCurve();
}
}
else if (m_bDrawingRubber)
{
StopDrawRubber();
m_bDrawingRubber = FALSE;
if (! m_rcClip.IsRectEmpty())
{
// adjust position with scroll position
CRect rcInDib(m_rcClip);
ClientToDib(rcInDib);
// create float DIB
HDIB hDib = m_pDib->CopyRect(rcInDib);
// create new float DIB window
CreateFloatWnd(hDib, m_rcClip.TopLeft());
}
}
CScrollView::OnLButtonUp(nFlags, point);
}
void CImageBoardView::DrawTmpCurve()
{
CPen penCurve(PS_SOLID, m_nPenWidth, m_crPenColor);
CClientDC dc(this);
CPen* pOldPen = dc.SelectObject(&penCurve);
int nOldRop = dc.SetROP2(R2_NOTXORPEN);
dc.PolyBezier(m_ptCurve, 4);
dc.SelectObject(pOldPen);
dc.SetROP2(nOldRop);
}
void CImageBoardView::DrawCurve()
{
DrawTmpCurve();
CPen penCurve(PS_SOLID, m_nPenWidth, m_crPenColor);
CClientDC dc(this);
CDC * pDibDC = m_pDib->BeginPaint(&dc);
CPen* pOldPen = pDibDC->SelectObject(&penCurve);
pDibDC->PolyBezier(m_ptCurve, 4);
pDibDC->SelectObject(pOldPen);
m_pDib->EndPaint();
Invalidate(FALSE);
}
void CImageBoardView::CutSelectedRect()
{
if (! m_rcClip.IsRectEmpty())
{
// adjust position with scroll position
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -