📄 dibview.cpp
字号:
// DibView.cpp : implementation file
//
#include "stdafx.h"
#include "ImageBoard.h"
#include "DibView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDibView
IMPLEMENT_DYNCREATE(CDibView, CScrollView)
CDibView::CDibView()
{
m_pDib = NULL;
m_pFloatWnd = NULL;
m_bDrawingRubber = FALSE;
m_bDrawFreeline = FALSE;
m_nDrawCurveStep = -1;
m_bDrawCurve = FALSE;
m_nDrawType = DT_SELECT;
m_nPenStyle = PS_SOLID;
m_nPenWidth = 1;
m_crPenColor = RGB(0,0,0);
m_crFillColor = RGB(0,0,0);
m_nTextAlign = DT_LEFT;
m_hCursorGeneralDraw = NULL;
m_hCursorFreeline = NULL;
m_hCursorFill = NULL;
m_hCursorCurve = NULL;
}
CDibView::~CDibView()
{
}
BEGIN_MESSAGE_MAP(CDibView, CScrollView)
//{{AFX_MSG_MAP(CDibView)
ON_WM_LBUTTONUP()
ON_WM_DESTROY()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_CTLCOLOR()
ON_WM_CREATE()
ON_WM_SETCURSOR()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_REALIZEPAL, OnRealizePal)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDibView drawing
BOOL CDibView::PreCreateWindow(CREATESTRUCT& cs)
{
m_hCursorGeneralDraw = AfxGetApp()->LoadCursor(IDC_CURSORGENERALDRAW);
cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS,
m_hCursorGeneralDraw,
(HBRUSH)(COLOR_WINDOW-1),
AfxGetApp()->LoadIcon(IDR_IMAGEBTYPE));
return CScrollView::PreCreateWindow(cs);
}
void CDibView::Initialize(CDib* pDib)
{
m_pDib = pDib;
}
void CDibView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
CSize sizeTotal;
// TODO: calculate the total size of this view
sizeTotal.cx = sizeTotal.cy = 100;
SetScrollSizes(MM_TEXT, sizeTotal);
}
void CDibView::OnDraw(CDC* pDC)
{
if (::IsWindow(m_EditText.m_hWnd))
{
CRect rc;
m_EditText.GetWindowRect(&rc);
ScreenToClient(&rc);
rc.InflateRect(2,2);
CPen pen(PS_DASH,1,RGB(0,0,255));
CPen *pOldPen = pDC->SelectObject(&pen);
CBrush *pOldBrush = pDC->SelectObject(CBrush::FromHandle((HBRUSH)::GetStockObject(NULL_BRUSH)));
pDC->Rectangle(&rc);
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
}
}
/////////////////////////////////////////////////////////////////////////////
// CDibView diagnostics
#ifdef _DEBUG
void CDibView::AssertValid() const
{
CScrollView::AssertValid();
}
void CDibView::Dump(CDumpContext& dc) const
{
CScrollView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDibView message handlers
void CDibView::OnDestroy()
{
CScrollView::OnDestroy();
DeleteFloatWnd();
delete m_pFont;
}
void CDibView::CreateFloatWnd(HDIB hDib, CPoint ptTopLeft)
{
MergeFloatDib();
// get DIB width and height
LPBYTE lpDIB = (LPBYTE)GlobalLock(hDib);
if (! lpDIB)
{
GlobalUnlock(hDib);
return;
}
int nWidth = (int)DIBWidth(lpDIB);
int nHeight = (int)DIBHeight(lpDIB);
GlobalUnlock(hDib);
// create float window
CRect rc(ptTopLeft.x, ptTopLeft.y, ptTopLeft.x+nWidth, ptTopLeft.y+nHeight);
m_pFloatWnd = new CFloatDibWnd(hDib, rc, this);
}
void CDibView::DeleteFloatWnd()
{
if (m_pFloatWnd)
{
delete m_pFloatWnd;
m_pFloatWnd = NULL;
}
}
void CDibView::ClientToDib(CPoint& point)
{
point.x += GetScrollPos(SB_HORZ);
point.y += GetScrollPos(SB_VERT);
}
void CDibView::ClientToDib(CRect& rect)
{
rect.left += GetScrollPos(SB_HORZ);
rect.top += GetScrollPos(SB_VERT);
rect.right += GetScrollPos(SB_HORZ);
rect.bottom += GetScrollPos(SB_VERT);
}
void CDibView::DibToClient(CPoint& point)
{
point.x -= GetScrollPos(SB_HORZ);
point.y -= GetScrollPos(SB_VERT);
}
void CDibView::DibToClient(CRect& rect)
{
rect.left -= GetScrollPos(SB_HORZ);
rect.top -= GetScrollPos(SB_VERT);
rect.right -= GetScrollPos(SB_HORZ);
rect.bottom -= GetScrollPos(SB_VERT);
}
BOOL CDibView::AdjustPointinDib(CPoint& point)
{
int nWidth = m_pDib->GetWidth();
int nHeight = m_pDib->GetHeight();
BOOL bOut = FALSE;
ClientToDib(point);
if (point.x < 0)
{
point.x = 0;
bOut = TRUE;
}
else if (point.x >= nWidth)
{
point.x = nWidth;
bOut = TRUE;
}
if (point.y < 0)
{
point.y = 0;
bOut = TRUE;
}
else if (point.y >= nHeight)
{
point.y = nHeight;
bOut = TRUE;
}
DibToClient(point);
return bOut;
}
void CDibView::DoDrawRubber(CDC *pDC, CRect rc)
{
if (rc.IsRectEmpty())
return;
// draw
switch(m_nDrawType)
{
case DT_SELECT:
case DT_TEXT:
pDC->Rectangle(&rc);
break;
case DT_LINE:
{
// use client coordinates
CPoint ptStart(m_ptStart);
DibToClient(ptStart);
if (ptStart == rc.TopLeft() ||
ptStart == rc.BottomRight())
{
pDC->MoveTo(rc.TopLeft());
pDC->LineTo(rc.BottomRight());
}
else
{
pDC->MoveTo(rc.right, rc.top);
pDC->LineTo(rc.left, rc.bottom);
}
}
break;
case DT_CURVE:
{
if (m_nDrawCurveStep == 0)
{
// use client coordinates
CPoint ptStart(m_ptStart);
DibToClient(ptStart);
if (ptStart == rc.TopLeft() ||
ptStart == rc.BottomRight())
{
pDC->MoveTo(rc.TopLeft());
pDC->LineTo(rc.BottomRight());
}
else
{
pDC->MoveTo(rc.right, rc.top);
pDC->LineTo(rc.left, rc.bottom);
}
}
}
break;
case DT_RECT_H:
case DT_RECT_F:
pDC->Rectangle(&rc);
break;
case DT_ROUNDRECT_H:
case DT_ROUNDRECT_F:
pDC->RoundRect(&rc, CPoint((int)(rc.Width()/3), (int)(rc.Height()/3)));
break;
case DT_ELLIP_H:
case DT_ELLIP_F:
pDC->Ellipse(&rc);
break;
}
}
void CDibView::StartDrawRubber(CPoint point)
{
// save current mouse position
ClientToDib(point);
m_ptStart = point;
// empty current rectangle
m_rcClip.SetRectEmpty();
m_rcRubber.SetRectEmpty();
// capture mouse
SetCapture();
}
void CDibView::DrawRubber(CPoint point)
{
// get DC and set its ROP
CClientDC dc(this);
// define used pen
int nPenStyle;
int nPenWidth;
COLORREF color;
int nOldRop = dc.SetROP2(R2_NOTXORPEN);
if (m_nDrawType == DT_SELECT || m_nDrawType == DT_TEXT)
{
nPenStyle = PS_DOT;
nPenWidth = 1;
color = RGB(0,0,0);
}
else
{
nPenStyle = m_nPenStyle;
nPenWidth = m_nPenWidth;
color = m_crPenColor;
}
CPen pen(nPenStyle, nPenWidth, color);
CPen* pOldPen = dc.SelectObject(&pen);
// if there is rectangle drawn, clear it
DoDrawRubber(&dc, m_rcRubber);
// Adjust cooridnates for select
if (m_nDrawType == DT_SELECT)
{
// get current scroll pos
int nScrollX = GetScrollPos(SB_HORZ);
int nScrollY = GetScrollPos(SB_VERT);
// calculate new scroll pos, and set it
CRect rcClient;
GetClientRect(&rcClient);
int nMinX, nMaxX, nMinY, nMaxY;
GetScrollRange(SB_HORZ, &nMinX, &nMaxX);
GetScrollRange(SB_VERT, &nMinY, &nMaxY);
BOOL bNeedRedraw = FALSE;
if ((rcClient.Width() < m_pDib->GetWidth()) &&
(point.x < 0 || point.x > rcClient.right))
{
nScrollX += point.x;
nScrollX = BOUND(nScrollX, nMinX, nMaxX);
SetScrollPos(SB_HORZ, nScrollX);
bNeedRedraw = TRUE;
}
if ((rcClient.Height() < m_pDib->GetHeight()) &&
(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 CDibView::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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -