大家好,
想照PPStream的界面,做一个播放器.PPStream左侧的树型控件,当鼠标移至每个ITEM的时候,
该ITEM的颜色&字体就会自动改变,当鼠标移开的时候,又恢复了以前的字体&颜色,能够给人动态的
效果.这个功能具体是怎么实现的呢!自己在网上找了一些资料,都没有找到满意的.
所以,希望做过或者知道这个的朋友推荐一两个代码实例,谢谢!
想照PPStream的界面,做一个播放器.PPStream左侧的树型控件,当鼠标移至每个ITEM的时候,
该ITEM的颜色&字体就会自动改变,当鼠标移开的时候,又恢复了以前的字体&颜色,能够给人动态的
效果.这个功能具体是怎么实现的呢!自己在网上找了一些资料,都没有找到满意的.
所以,希望做过或者知道这个的朋友推荐一两个代码实例,谢谢!
那个控件未必是treectrl,网上有很多类treectrl或者listctrl的自画控件,自己改改就能实现这效果了
非常感谢!
这里有一个类似的,你看看.
从网上整了一个例子,改了一下.当鼠标移到树控件的某个节点的时候,倒是可以改变颜色.可问题是,当鼠标离开这个节点之后,再去到别的节点或者别的地方,该节点先前的颜色切换不回来了.
研究了一下,没有整明白,不知道是不是还要重载什么方法,还是只要修改现有的OnMouseMove和OnPaint方法就可以了.把整个项目的代码贴上吧(比较小的一个项目),请高手指点!谢谢!
CTreeCtrlEx的头文件:#if !defined(AFX_TREECTRLEX_H__5D969ED4_7DEA_4FB5_8C1D_E12D1CCF0989__INCLUDED_)
#define AFX_TREECTRLEX_H__5D969ED4_7DEA_4FB5_8C1D_E12D1CCF0989__INCLUDED_#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000#include <afxtempl.h>//////////////////////////////////////////////////////////////////////
class CTreeCtrlEx : public CTreeCtrl
{
DECLARE_DYNAMIC(CTreeCtrlEx)public:
CTreeCtrlEx();
virtual ~CTreeCtrlEx(); void SetItemFont(HTREEITEM, LOGFONT&);
void SetItemBold(HTREEITEM, BOOL);
void SetItemColor(HTREEITEM, COLORREF);
BOOL GetItemFont(HTREEITEM, LOGFONT *);
BOOL GetItemBold(HTREEITEM);
COLORREF GetItemColor(HTREEITEM);protected: struct Color_Font {
COLORREF color;
LOGFONT logfont;
}; CMap <void*, void*, Color_Font, Color_Font&> m_mapColorFont; COLORREF m_ItemText_OldColor; protected:
//{{AFX_MSG(CTreeCtrlEx)
afx_msg void OnPaint();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()};#endif // !defined(AFX_TREECTRLEX_H__5D969ED4_7DEA_4FB5_8C1D_E12D1CCF0989__INCLUDED_)CTreeCtrlEx的实现文件:#include "stdafx.h"
#include "ColorTree.h"
#include "TreeCtrlEx.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////
CTreeCtrlEx::CTreeCtrlEx()
{
m_ItemText_OldColor = RGB( 255, 0, 0 );
}CTreeCtrlEx::~CTreeCtrlEx()
{
}//////////////////////////////////
IMPLEMENT_DYNAMIC(CTreeCtrlEx, CTreeCtrl)BEGIN_MESSAGE_MAP(CTreeCtrlEx, CTreeCtrl)
//{{AFX_MSG_MAP(CTreeCtrlEx)
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_WM_DRAWITEM()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()//////////////////////////////////////////////////////////////////////
void CTreeCtrlEx::SetItemFont(HTREEITEM hItem, LOGFONT& logfont)
{
Color_Font cf;
if( !m_mapColorFont.Lookup( hItem, cf ) )
cf.color = (COLORREF)-1;
cf.logfont = logfont;
m_mapColorFont[hItem] = cf;
}//////////////////////////////////////////////////////////////////////
void CTreeCtrlEx::SetItemBold(HTREEITEM hItem, BOOL bBold)
{
SetItemState(hItem, bBold ? TVIS_BOLD: 0, TVIS_BOLD);
}//////////////////////////////////////////////////////////////////////
void CTreeCtrlEx::SetItemColor(HTREEITEM hItem, COLORREF color)
{
Color_Font cf;
if(!m_mapColorFont.Lookup(hItem, cf))
cf.logfont.lfFaceName[0] = '\0';
cf.color = color;
m_mapColorFont[hItem] = cf;
}//////////////////////////////////////////////////////////////////////
BOOL CTreeCtrlEx::GetItemFont(HTREEITEM hItem, LOGFONT * plogfont)
{
Color_Font cf;
if(!m_mapColorFont.Lookup(hItem, cf))
return FALSE;
if(cf.logfont.lfFaceName[0] == '\0')
return FALSE;
*plogfont = cf.logfont;
return TRUE;}//////////////////////////////////////////////////////////////////////
BOOL CTreeCtrlEx::GetItemBold(HTREEITEM hItem)
{
return GetItemState(hItem, TVIS_BOLD) & TVIS_BOLD;
}//////////////////////////////////////////////////////////////////////
COLORREF CTreeCtrlEx::GetItemColor(HTREEITEM hItem)
{
// Returns (COLORREF)-1 if color was not set
Color_Font cf;
if(!m_mapColorFont.Lookup(hItem, cf))
return (COLORREF) - 1;
return cf.color;}//////////////////////////////////////////////////////////////////////
void CTreeCtrlEx::OnPaint()
{
CPaintDC dc(this); // Create a memory DC compatible with the paint DC
CDC memDC;
memDC.CreateCompatibleDC(&dc); CRect rcClip, rcClient;
dc.GetClipBox( &rcClip );
GetClientRect(&rcClient); // Select a compatible bitmap into the memory DC
CBitmap bitmap;
bitmap.CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() );
memDC.SelectObject( &bitmap );
// Set clip region to be same as that in paint DC
CRgn rgn;
rgn.CreateRectRgnIndirect( &rcClip );
memDC.SelectClipRgn(&rgn);
rgn.DeleteObject();
// First let the control do its default drawing.
CWnd::DefWindowProc(WM_PAINT, (WPARAM)memDC.m_hDC, 0); HTREEITEM hItem = GetFirstVisibleItem(); int iItemCount = GetVisibleCount() + 1;
while(hItem && iItemCount--)
{
CRect rect; // Do not meddle with selected items or drop highlighted items
UINT selflag = TVIS_DROPHILITED | TVIS_SELECTED;
Color_Font cf;
//if ( !(GetTreeCtrl().GetItemState( hItem, selflag ) & selflag )
// && m_mapColorFont.Lookup( hItem, cf ))
//if ((GetItemState(hItem, selflag) & selflag)
// && ::GetFocus() == m_hWnd)
// ;
if (m_mapColorFont.Lookup(hItem, cf))
{
CFont *pFontDC;
CFont fontDC;
LOGFONT logfont; if(cf.logfont.lfFaceName[0] != '\0')
logfont = cf.logfont;
else {
// No font specified, so use window font
CFont *pFont = GetFont();
pFont->GetLogFont( &logfont );
} if(GetItemBold(hItem))
logfont.lfWeight = 700; fontDC.CreateFontIndirect(&logfont);
pFontDC = memDC.SelectObject(&fontDC ); if(cf.color != (COLORREF) - 1)
{
memDC.SetTextColor(RGB(0,255,0));
//memDC.SetTextColor(cf.color);
}
else
{
memDC.SetTextColor(/*RGB(0,255,0)*/ GetSysColor(COLOR_WINDOWTEXT) );
}
CString sItem = GetItemText(hItem); GetItemRect(hItem, &rect, TRUE);
if(cf.color != (COLORREF) - 1)
{
memDC.SetBkColor(RGB(255,0,0));
//memDC.SetBkColor(cf.color);
}
else
{
memDC.SetBkColor(/*GetSysColor(COLOR_WINDOWTEXT)*/RGB(255,0,0));
//memDC.SetBkColor( /*GetSysColor(COLOR_WINDOW)*/RGB(0,255,0));
}
memDC.TextOut(rect.left + 2, rect.top + 1, sItem);
memDC.SelectObject(pFontDC);
}
hItem = GetNextVisibleItem(hItem);
}
dc.BitBlt(rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &memDC,
rcClip.left, rcClip.top, SRCCOPY); memDC.DeleteDC();
}void CTreeCtrlEx::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default CRect rc;
TVHITTESTINFO tvInfo;
tvInfo.pt=point;
HTREEITEM hItem=HitTest(&tvInfo); //获得光标进入的项目的句柄
GetItemRect(hItem,&rc,TRUE);
BOOL yn=rc.PtInRect(point);
Color_Font cf;
//cf = m_mapColorFont[hItem];
if(yn) { //光标进入项目标签
cf.color=RGB(0,255,0); //设置项目文本需改变的颜色参数
//SetCursor(NULL); //设置手形光标,hIcon_sx为光标的句柄
//hItem_bc=hItem;
}
else {
cf.color = (COLORREF)-1;
goto OUT_RANGLE;
//cf.color = m_ItemText_OldColor;
}
m_mapColorFont[hItem]=cf;
if(!m_mapColorFont.Lookup(hItem,cf))
cf.color=(COLORREF)-1;
OUT_RANGLE:
m_mapColorFont[hItem]=cf;
Invalidate(FALSE); //强制执行OnPaint()
CTreeCtrl::OnMouseMove(nFlags, point);
}void CTreeCtrlEx::OnDrawItem( int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct )
{
CTreeCtrl::OnDrawItem( nIDCtl, lpDrawItemStruct );
}主对话框调用的代码段:
HTREEITEM hOrder[1024], hContent[1024];
CString sStr; for(int i = 0; i < 1; i++) {
sStr.Format("Parent%d", i);
hOrder[i] = m_cTree.InsertItem(sStr);
for (int j = 0; j < 5; j++) {
sStr.Format("Child%d", j);
hContent[j] = m_cTree.InsertItem(sStr, hOrder[i]);
m_cTree.SetItemColor(hContent[j], RGB(0, 255, 0));
//m_cTree.SetItemColor(hContent[j], RGB(i, 255, 0));
}
//m_cTree.SetItemColor(hOrder[i], RGB(255, i, 0));
m_cTree.SetItemColor(hOrder[i], RGB(255, 0, 0));
}
注:m_CTree为CTreeCtrlEx类的一个变量
移走之后,该节点又恢复之前的颜色.是不是只要重载OnMouseMove()方法
就可以了,还是需要再重载其它的什么方法么?