采用CRectTracker类来实现:点击一个控件时,为其绘制边框
参考资料:http://www.vckbase.com/vckbase/vckbase10/vc/nonctrls/misc_21/1021002.htm
步骤1:在CxxxDoc中添加变量
CRectTracker m_rectBound;
步骤2:在static的单击事件响应函数中加入:
其中Invalidate()函数的调用时机值得分析。
void CSwitchChannelView::OnStnClickedStatic0()
{
//TODO: 在此添加控件通知处理程序代
///////////////////////////////////////////////////////////////////////////////////////////
// 用CRectTracker类来实现
//将上一个边框擦除
//得到控件的矩形
CPoint Point;
GetCursorPos(&Point);//得到鼠标的位置 ,in screen coordinate
HWND hWnd = ::WindowFromPoint(Point);//得到该点所在的窗口句柄
::GetWindowRect(hWnd,GetDocument()->m_rectBound.m_rect);
//因为要在客户区绘制(与clientDC对应),所以将屏幕坐标转为client坐标
ScreenToClient(GetDocument()->m_rectBound.m_rect);
//得到dc
CClientDC clientDC(this);
//重绘。调用CSwitchChannelView::OnDraw()函数,先将前一个
//边框擦除,再将现在控件的边框绘制出来。
Invalidate();
}
步骤3:在CSwitchChannelView::OnDraw()里加入如下代码:
void CSwitchChannelView::OnDraw(CDC* pDC)
{
//////////////////////////////////////////////////////////////////////////
///用于画边框
if (m_bIsDrawBound)//修改后,加状态判断
{
GetDocument()->m_rectTracker.Draw(pDC);
}
}
续:
为了解决窗口大小变化、位置移动、改变分屏方式等情况下绘制的边框消失的情况,还应该在几种情况发生进行重绘操作:
- 在OnSize()中加入改变m_rectTracker.m_rect的大小的语句。并将m_bIsDrawBound变量置为true.
1 void CMSVideoMonitorView::OnSize(UINT nType, int cx, int cy)
2 {
3 CFormView::OnSize(nType, cx, cy);
4
5 // TODO: 在此处添加消息处理程序代码
6
7
8 //在窗口大小发生改时,将用于绘制外边框的矩形的大小也改变。
9 if (!GetDocument()->m_rectTracker.m_rect.IsRectEmpty())//判断这个矩形是否为空。若为空,说明还没有进行过单击控件操作
10 {
11 ::GetWindowRect(GetDocument()->m_hCurrentClickedWindow,GetDocument()->m_rectTracker.m_rect);
12 ScreenToClient(GetDocument()->m_rectTracker.m_rect);//将控件的屏幕坐标转换为客户区坐标
13 }
14 m_bIsDrawBound = true;
15 }
- 与此对应的,应在Doc的构造函数里将m_rectTracker.m_rect置空。
//将CRectTracker.m_rect初始化为空矩形 m_rectTracker.m_rect.SetRectEmpty();
- 在分屏函数OnArrangeScreen()里,每种分屏方式实现后,也改变绘框矩形的大小。同时,将全屏状态置为false.
1 void CMSVideoMonitorView::OnArrangeScreen(UINT menuID)
2 {
3 GetDocument()->m_bIsFullScreen = false;//在重新了安排了画面以后,应该将全屏的状态置为false
4 ////////////////////////////////////////////////////////////////////////////////////////////////////////
5 //同时应该改变用于绘制边框的矩形
6 //在窗口大小发生改时,将用于绘制外边框的矩形的大小也改变。
7 if (!GetDocument()->m_rectTracker.m_rect.IsRectEmpty())//判断这个矩形是否为空。若为空,说明还没有进行过单击控件操作
8 {
9 ::GetWindowRect(GetDocument()->m_hCurrentClickedWindow,GetDocument()->m_rectTracker.m_rect);
10 ScreenToClient(GetDocument()->m_rectTracker.m_rect);//将控件的屏幕坐标转换为客户区坐标
11 }
12 Invalidate();//立即重绘窗体,显示效果
13 }
待解决问题:
- 调用Invalidate()导致重绘,因此在点击过快时,会出现闪屏现象。
- 网上有继承CRectTracker类,改写其OnDraw()函数,以实现改变边框颜色的例子。自己尚未实现。
浙公网安备 33010602011771号