16,548
社区成员




CRect rect;
GetClientRect(&rect);
CClientDC dc(this);
//翻转颜色
dc.SetROP2(R2_NOT);
//擦除原来的线
dc.MoveTo(m_ptTemp.x,rect.top);
dc.LineTo(m_ptTemp.x,rect.bottom);
dc.MoveTo(rect.left,m_ptTemp.y);
dc.LineTo(rect.right,m_ptTemp.y);
//绘制现在的线
dc.MoveTo(point.x,rect.top);
dc.LineTo(point.x,rect.bottom);
dc.MoveTo(rect.left,point.y);
dc.LineTo(rect.right,point.y);
m_ptTemp=point;
CView::OnMouseMove(nFlags, point);
#pragma once
class CCrossDrawer
{
public:
CCrossDrawer(void);
~CCrossDrawer(void);
void Restart();
void OnMouseMove(UINT nFlag, CPoint pt, CView* pView);
void Render(CDC* pDC);
void AddLine(CString strText);
void ClearTexts();
protected:
CPoint m_ptPre; // 鼠标点
CRect m_rectClient; // 客户区区域矩形
UINT m_nTextHeight; // 文字总高度
UINT m_nTextWidth; // 文字总宽度
CPoint m_ptTextPos; // 文字的输出位置
public:
COLORREF m_clrLine; // 十字线颜色
int m_nDstX; // 文字边框到鼠标的横向距离
int m_nDstY; // 文字边框到鼠标的纵向距离
int m_nExtText; // 文字到文字边框的距离
std::vector<CString> m_Texts; // 文字提示信息
};
#include "StdAfx.h"
#include ".\crossdrawer.h"
CCrossDrawer::CCrossDrawer(void)
:m_ptPre(-999,-999)
,m_ptTextPos(-999,-999)
{
m_clrLine = RGB(0,0,0);
m_nDstX = 8;
m_nDstY = 16;
m_nExtText = 3;
m_nTextHeight = m_nTextWidth = 0;
CString strInit = _T("文字提示信息......第01行");
m_Texts.push_back(strInit);
strInit.Format(_T("文字提示信息......第02行"));
m_Texts.push_back(strInit);
strInit.Format(_T("文字提示信息......第XXX行"));
m_Texts.push_back(strInit);
}
CCrossDrawer::~CCrossDrawer(void)
{
}
void CCrossDrawer::OnMouseMove( UINT nFlag, CPoint pt, CView* pView )
{
pView->GetClientRect(&m_rectClient);
CClientDC dc(pView);
pView->OnPrepareDC(&dc);
dc.DPtoLP(&m_rectClient);
m_rectClient.NormalizeRect();
m_ptPre = pt;
dc.DPtoLP(&m_ptPre);
// 计算文字的宽高
// 找到最长字符串的下标
int nMaxIndex = 0;
int nLines = m_Texts.size();
for (UINT i = 0; i < nLines; i++)
{
if (m_Texts[nMaxIndex].GetLength() < m_Texts[i].GetLength())
nMaxIndex = i;
}
// 选入字体
LOGFONT logfont = { -18,0,0,0,400,0,0,0,134,3,2,1,2, _T("宋体") };
//logfont.lfHeight = Sim2DHelper::FontSizeToLP(&dc, logfont.lfHeight);
CSize szHeight(0, logfont.lfHeight);
dc.DPtoLP(&szHeight);
logfont.lfHeight = szHeight.cy;
CFont font; font.CreateFontIndirect(&logfont);
CFont* pOldFont = dc.SelectObject(&font);
CSize szTextExtent;
if (!m_Texts.empty()) szTextExtent = dc.GetTextExtent(m_Texts[nMaxIndex]);
else szTextExtent = dc.GetTextExtent(_T(""));
m_nTextWidth = szTextExtent.cx;
m_nTextHeight = szTextExtent.cy*nLines;
// 计算文字输出位置
CSize sizeOffset(m_nDstX, m_nDstY);
dc.DPtoLP(&sizeOffset); sizeOffset.cy *= -1;
m_ptTextPos.x = m_ptPre.x + sizeOffset.cx;
m_ptTextPos.y = m_ptTextPos.y = m_ptPre.y + sizeOffset.cy;
if ( (LONG)(m_ptPre.x + sizeOffset.cx + m_nTextWidth) >= m_rectClient.right)
{
m_ptTextPos.x = m_ptPre.x - sizeOffset.cx - m_nTextWidth;
}
if ((LONG)(m_ptPre.x - sizeOffset.cx - m_nTextWidth) <= m_rectClient.left )
{
m_ptTextPos.x = m_ptPre.x + sizeOffset.cx;
}
if ((LONG)(m_ptPre.y + sizeOffset.cy - m_nTextHeight) <= m_rectClient.top)
{
m_ptTextPos.y = m_ptPre.y - sizeOffset.cy + m_nTextHeight;
}
if ((LONG)(m_ptPre.y - sizeOffset.cy + m_nTextHeight) >= m_rectClient.bottom)
{
m_ptTextPos.y = m_ptPre.y + sizeOffset.cy;
}
pView->Invalidate(FALSE);
}
void CCrossDrawer::Restart()
{
m_ptPre.SetPoint(-999,-999);
}
void CCrossDrawer::Render( CDC* pDC )
{
if (m_ptPre.x != -999)
{
CPen pen(PS_DOT, 0, m_clrLine);
CPen* pOldpen = pDC->SelectObject(&pen);
pDC->MoveTo(CPoint(m_ptPre.x, m_rectClient.top));
pDC->LineTo(CPoint(m_ptPre.x, m_rectClient.bottom));
pDC->MoveTo(CPoint(m_rectClient.left, m_ptPre.y));
pDC->LineTo(CPoint(m_rectClient.right, m_ptPre.y));
pDC->SelectObject(pOldpen);
if (!m_Texts.empty())
{
// 以下绘制文字提示框
//// 计算文字左上角
//CSize sizeOffset(m_nDstX, m_nDstY);
//pDC->DPtoLP(&sizeOffset); sizeOffset.cy *= -1;
//CPoint m_ptTextPos = m_ptPre + sizeOffset;
// 计算文本矩形框并绘制
// 找到最长字符串的下标
int nMaxIndex = 0;
int nLines = m_Texts.size();
for (UINT i = 0; i < nLines; i++)
{
if (m_Texts[nMaxIndex].GetLength() < m_Texts[i].GetLength())
nMaxIndex = i;
}
// 选入字体
LOGFONT logfont = { -13,0,0,0,400,0,0,0,134,3,2,1,2, _T("宋体") };
//logfont.lfHeight = Sim2DHelper::FontSizeToLP(pDC, logfont.lfHeight);
CSize szHeight(0, logfont.lfHeight);
pDC->DPtoLP(&szHeight);
logfont.lfHeight = szHeight.cy;
CFont font; font.CreateFontIndirect(&logfont);
CFont* pOldFont = pDC->SelectObject(&font);
// 计算矩形
CSize szTextExtent = pDC->GetTextExtent(m_Texts[nMaxIndex]);
CRect rtTexts(m_ptTextPos.x, m_ptTextPos.y, m_ptTextPos.x + szTextExtent.cx, m_ptTextPos.y - szTextExtent.cy*nLines);
rtTexts.NormalizeRect();
CSize szDstText(m_nExtText, m_nExtText); pDC->DPtoLP(&szDstText);
rtTexts.InflateRect(szDstText);
CBrush brh(RGB(238,245,201));
CBrush* pOldBrh = pDC->SelectObject(&brh);
pDC->Rectangle(rtTexts);
pDC->SelectObject(pOldBrh);
// 绘制文字信息
int nOldBkMode = pDC->SetBkMode(TRANSPARENT);
for (UINT i = 0; i < nLines; i++)
{
pDC->TextOut(m_ptTextPos.x, m_ptTextPos.y - i*szTextExtent.cy, m_Texts[i]);
}
pDC->SetBkMode(nOldBkMode);
pDC->SelectObject(pOldFont);
}
}
}
void CCrossDrawer::AddLine( CString strText )
{
if (strText.GetLength() < 4)
return;
m_Texts.push_back(strText);
}
void CCrossDrawer::ClearTexts()
{
m_Texts.clear();
}