正在开发一个程序,程序里面有很多可以绘画的对象,需要在一个窗口里面显示每个对象的提示消息,就用CToolTipCtrl来做,结果在画十字线的时候遇到了问题(根据鼠标当前的位置,画十字线),我用的是SetROP2来擦除上次画的十字线。
结果是:有的时候出现提示信息后,上次的线没有被擦除。后来经过很久的最终终于发现了问题。
原因是:我在OnMouseMove中不断判断当前鼠标光标下对象的类型来显示不同的提示信息,所以在OnMouseMove中调用了CToolTipCtrl::UpdateTipText()。原来,当UpdateTipText()显示提示信息文本不同(提示框的区域的大小改变)时,会发送OnPaint()消息,来更新背景(并不是全部更新,而是将当前提示文本的RECT变为无效,类似于调用了InvalidateRect()函数),所以就遗留了上次画线的痕迹。、
解决办法,在OnPaint消息中,重画十字线把原来的擦除掉。
源码:
CPoint m_ptLast;//上次画十字线的点。
m_ptLast = CPoint(-1, -1);//给他一个无效初始值。
void OnPaint()
{
CPaintDC dc(this);
CDC *pDC = GetDC();
pDC->SetROP2(R2_NOT);
//擦除上次的线。
if (m_ptLast.x > -1 && m_ptLast.y > -1)
{
pDC->MoveTo(0, m_ptLast.y);
pDC->LineTo(rtClient.Width(), m_ptLast.y);
pDC->MoveTo(m_ptLast.x, 0);
pDC->LineTo(m_ptLast.x, rtClient.Height());
m_ptLast = CPoint(-1, -1);//避免多次擦除。
}
ReleaseDC(pDC);
}
void OnMouseMove(CPoint point)
{
CRect rtClient;
GetClientRect(rtClient);
CDC *pDC = GetDC();
pDC.SetROP2(R2_NOT);
//擦除上次的线。
if (m_ptLast.x > -1 && m_ptLast.y > -1)
{
pDC->MoveTo(0, m_ptLast.y);
pDC->LineTo(rtClient.Width(), m_ptLast.y);
pDC->MoveTo(m_ptLast.x, 0);
pDC->LineTo(m_ptLast.x, rtClient.Height());
}
//画十字线。
m_ptLast = point;
pDC->MoveTo(0, m_ptLast.y);
pDC->LineTo(rtClient.Width(), m_ptLast.y);
pDC->MoveTo(m_ptLast.x, 0);
pDC->LineTo(m_ptLast.x, rtClient.Height());
ReleaseDC(pDC);
//UpdateTipText();更新提示文本会产生OnPaint ()消息,注意提示信息内容如果没有改变(即提示框区域的大小没有改变),是不会产生OnPaint消息的。
}
本人新手一枚,如果有错误,请不吝指出。