采用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()函数,以实现改变边框颜色的例子。自己尚未实现。

posted on 2011-08-24 14:52  LateStop  阅读(1250)  评论(0)    收藏  举报

导航