📄 dibview.cpp
字号:
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 CDibView::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 CDibView::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 CDibView::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);
dc.SetPixel(point, m_crPenColor);
ClientToDib(point);
CDC * pDibDC = m_pDib->BeginPaint(&dc);
pDibDC->SetPixel(point, m_crPenColor);
m_pDib->EndPaint();
}
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 CDibView::OnMouseMove(UINT nFlags, CPoint 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) //m_nDrawType == DT_FREELINE && nFlags == MK_LBUTTON)
{
CPen pen(m_nPenStyle, m_nPenWidth, m_crPenColor);
CClientDC dc(this);
CPen* pOldPen = dc.SelectObject(&pen);
dc.MoveTo(m_ptFreelineStart);
dc.LineTo(point);
dc.SelectObject(pOldPen);
CPoint pt = point;
ClientToDib(m_ptFreelineStart);
ClientToDib(pt);
CDC * pDibDC = m_pDib->BeginPaint(&dc);
pOldPen = pDibDC->SelectObject(&pen);
pDibDC->MoveTo(m_ptFreelineStart);
pDibDC->LineTo(pt);
pDibDC->SelectObject(pOldPen);
m_pDib->EndPaint();
// new start point
m_ptFreelineStart = point;
}
CScrollView::OnMouseMove(nFlags, point);
}
void CDibView::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bDrawFreeline)
{
m_bDrawFreeline = 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 CDibView::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 CDibView::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 CDibView::CutSelectedRect()
{
if (! m_rcClip.IsRectEmpty())
{
// adjust position with scroll position
CRect rcInDib(m_rcClip);
ClientToDib(rcInDib);
// cut select rectangle in m_pDib
m_pDib->CutRect(rcInDib);
// empty current rectangle
m_rcClip.SetRectEmpty();
// document changed
CDocument* pDoc = GetDocument();
pDoc->SetModifiedFlag(TRUE);
}
}
void CDibView::MergeFloatDib()
{
if (m_pFloatWnd)
{
CRect rc;
m_pFloatWnd->GetWindowRect(&rc);
CPoint point = rc.TopLeft();
ScreenToClient(&point);
ClientToDib(point);
m_pDib->MergeDib(m_pFloatWnd->m_hDibFloat, point);
// document changed
CDocument* pDoc = GetDocument();
pDoc->SetModifiedFlag(TRUE);
}
DeleteFloatWnd();
}
void CDibView::DeleteFloatDib()
{
// if selected rect is exist, cut it
CutSelectedRect();
// if float DIB window exist, delete it
DeleteFloatWnd();
}
void CDibView::CutFloatDib()
{
// copy to clipboard first
CopyToClipboard();
// then delete
DeleteFloatDib();
}
void CDibView::CopyToClipboard()
{
// Clean clipboard of contents, and copy the DIB/DDB/PAL.
// Actual copy will occured in WM_RENDERALLFORMATS/WM_RENDERFORMAT
if (OpenClipboard())
{
EmptyClipboard();
HDIB hDib;
HBITMAP hBitmap;
HPALETTE hPalette;
// if there is float dib, copy it
if (m_pFloatWnd)
{
hDib = CopyHandle(m_pFloatWnd->m_hDibFloat);
hBitmap = DIBToBitmap(m_pFloatWnd->m_hDibFloat, (HPALETTE)m_pDib->m_pPalette->GetSafeHandle());
hPalette = CopyPalette((HPALETTE)m_pDib->m_pPalette->GetSafeHandle());
}
else // otherwise, copy the entire DIB
{
hDib = CopyHandle(m_pDib->m_hDib);
hBitmap = DIBToBitmap(m_pDib->m_hDib, (HPALETTE)m_pDib->m_pPalette->GetSafeHandle ());
hPalette = CopyPalette((HPALETTE)m_pDib->m_pPalette->GetSafeHandle());
}
// set them to clipboard
SetClipboardData(CF_DIB, hDib);
SetClipboardData(CF_BITMAP, hBitmap);
SetClipboardData(CF_PALETTE, hPalette);
CloseClipboard();
}
}
void CDibView::Cut()
{
// copy to clipboard first
CopyToClipboard();
// then delete
Delete();
}
void CDibView::Delete()
{
if (m_pFloatWnd) // clip area
DeleteFloatDib();
else // entire DIB
{
m_pDib->Destroy();
// modify document flags
CSize sizeTotal(0, 0);
SetScrollSizes(MM_TEXT, sizeTotal);
CDocument* pDoc = GetDocument();
pDoc->UpdateAllViews(NULL);
pDoc->SetModifiedFlag(TRUE);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -