www.gusucode.com > 一个VC++ GUI测试程序-源码程序 > 一个VC++ GUI测试程序-源码程序/code/ScrollLabel.cpp
//Download by http://www.NewXing.com /* * Copyright (c) 2002, Bcdliang * All rights reserved. * * 文件名称:ScrollLabel.cpp * 摘 要:类ScrollLabel的实现 * * 当前版本:1.01 * 作 者:LIANG Zheng * 完成日期:2002年8月11日 */ #include "stdafx.h" #include "ScrollLabel.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif const int SL_DEFAULT_SCROLLSTYLE = CScrollLabel::SL_HSCROLLBOTH; const int SL_DEFAULT_STEP = 4; const int SL_DEFAULT_TICK = 200; const int SL_DEFAULT_TEXTHALIGN = CScrollLabel::SL_TA_LEFT; const int SL_DEFAULT_TEXTVALIGN = CScrollLabel::SL_TA_TOP; const COLORREF SL_DEFAULT_TEXTCOLOR = RGB(0, 255, 0); const COLORREF SL_DEFAULT_BKCOLOR = RGB(0, 0, 0); const HFONT SL_DEFAULT_FONT = (HFONT)::GetStockObject(DEFAULT_GUI_FONT); ///////////////////////////////////////////////////////////////////////////// // CScrollLabel //////////////////////////////////////////////////////////////////////// /* * 函数名称:CScrollLabel * 函数介绍:构造函数,初始化除m_InnerRect和m_InnerLabel外的其它数据成员 * 输入参数:无 * 输出参数:无 * 返回值 :无 */ CScrollLabel::CScrollLabel() { m_uStep = SL_DEFAULT_STEP; //步长:4(1-10) m_uTick = SL_DEFAULT_TICK; //速度:200(50-2000) m_uScrollStyle = SL_DEFAULT_SCROLLSTYLE; // 当前滚动效果 m_uTextHAlign = SL_DEFAULT_TEXTHALIGN; // 当前文字的水平对齐方式 m_uTextVAlign = SL_DEFAULT_TEXTVALIGN; // 当前文字的垂直对齐方式 m_crBkColor = SL_DEFAULT_BKCOLOR; // 背景色 m_crTextColor = SL_DEFAULT_TEXTCOLOR;// 前景色 m_hBrush = ::CreateSolidBrush(m_crBkColor); // 背景刷子 m_Font.Attach(SL_DEFAULT_FONT); // 字体 m_bLeft = false; // m_InnerLabel是否正在向左滚动(used in SL_SCROLLBOTH only) } CScrollLabel::~CScrollLabel() { ::DeleteObject(m_hBrush); m_Font.DeleteObject(); } BEGIN_MESSAGE_MAP(CScrollLabel, CWnd) //{{AFX_MSG_MAP(CScrollLabel) ON_WM_TIMER() ON_WM_CTLCOLOR_REFLECT() ON_WM_CTLCOLOR() //}}AFX_MSG_MAP END_MESSAGE_MAP() //////////////////////////////////////////////////////////////////////// /* * 函数名称:Initialize * 函数介绍:初始化m_InnerRect和m_InnerLabel m_InnerLabel必须在此初始化,才能显示出来, 在OnCreate和构造函数中初始化均不能显示 * 输入参数:无 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::Initialize() { // Create the m_InnerLabel m_InnerRect = CRect(0, 0, 40, 20); BOOL bRet = m_InnerLabel.Create(_T(""), WS_CHILD | WS_VISIBLE | SS_LEFT | SS_LEFTNOWORDWRAP, m_InnerRect, this); ASSERT(bRet); // Set text & font CString str; CWnd::GetWindowText(str); this->SetWindowText(str); this->SetFont(&m_Font); // Clear the parent window CWnd::SetWindowText(_T("")); } //////////////////////////////////////////////////////////////////////// /* * 函数名称:CtlColor * 函数介绍:响应WM_CTLCOLOR_REFLECT消息,重画自己的背景 * 输入参数:CDC* pDC, UINT nCtlColor * 输出参数:无 * 返回值 :HBRUSH */ HBRUSH CScrollLabel::CtlColor(CDC* pDC, UINT nCtlColor) { // TODO: Change any attributes of the DC here // TODO: Return a different brush if the default is not desired return this->m_hBrush; } //////////////////////////////////////////////////////////////////////// /* * 函数名称:OnCtlColor * 函数介绍:响应WM_CTLCOLOR消息,重画子窗口 * 输入参数:CDC* pDC, CWnd *pWnd, UINT nCtlColor * 输出参数:无 * 返回值 :HBRUSH */ HBRUSH CScrollLabel::OnCtlColor(CDC* pDC, CWnd *pWnd, UINT nCtlColor) { // HBRUSH hbr = CWnd::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: Change any attributes of the DC here pDC->SetBkMode(TRANSPARENT); pDC->SetTextColor(this->m_crTextColor); pDC->SetBkColor(this->m_crBkColor); // TODO: Return a different brush if the default is not desired // hbr = (HBRUSH)this->m_bkBrush.GetSafeHandle(); return this->m_hBrush; } void CScrollLabel::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default // rect of parent window CRect rect; this->GetClientRect(&rect); switch (m_uScrollStyle) { case SL_NONE: break; case SL_HSCROLLLEFT: if (m_InnerRect.left < -m_InnerRect.Width()) // appear again { m_InnerRect.OffsetRect(rect.Width() + m_InnerRect.Width(), 0); } m_InnerRect.OffsetRect(-(int)m_uStep, 0); break; case SL_HSCROLLRIGHT: if (m_InnerRect.left > rect.Width()) // appear again { m_InnerRect.OffsetRect(-(rect.Width() + m_InnerRect.Width()), 0); } m_InnerRect.OffsetRect(m_uStep, 0); break; case SL_HSCROLLBOTH: if (rect.Width() > m_InnerRect.Width()) { if (m_InnerRect.left < 0 || m_InnerRect.left > rect.Width() - m_InnerRect.Width()) { // m_InnerRect.OffsetRect(m_bLeft ? m_uStep : -(int)m_uStep, 0); m_bLeft = !m_bLeft; } } else { if (m_InnerRect.left < rect.Width() - m_InnerRect.Width() || m_InnerRect.left > 0) { // m_InnerRect.OffsetRect(m_bLeft ? m_uStep : -(int)m_uStep, 0); m_bLeft = !m_bLeft; } } m_InnerRect.OffsetRect(m_bLeft ? -(int)m_uStep : m_uStep, 0); break; case SL_HSCROLLAUTO: break; default: break; } m_InnerLabel.MoveWindow(&m_InnerRect); CWnd::OnTimer(nIDEvent); } //////////////////////////////////////////////////////////////////////// /* * 函数名称:SetWindowText * 函数介绍:重写父类成员SetWindowText, 设定m_InnerLabel中的字符串 * 输入参数: LPCTSTR lpszString, 新字符串 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::SetWindowText(LPCTSTR lpszString) { m_InnerLabel.SetWindowText(lpszString); switch (this->m_uScrollStyle) { case SL_NONE: // Do nothing break; case SL_HSCROLLLEFT: case SL_HSCROLLRIGHT: case SL_HSCROLLBOTH: // Reset the size of m_InnerRect and horizontally move it to (0, x) this->CalculateTextSize(); m_InnerRect.OffsetRect(-m_InnerRect.left, 0); this->m_bLeft = false; // Move m_InnerLabel to the rect specified by m_InnerRect m_InnerLabel.MoveWindow(&m_InnerRect); m_InnerLabel.Invalidate(); break; case SL_HSCROLLAUTO: break; default: break; } } //////////////////////////////////////////////////////////////////////// /* * 函数名称:GetWindowText * 函数介绍:重写父类成员GetWindowText, 返回m_InnerLabel中的字符串 * 输入参数:无 * 输出参数: CString &rString, 返回m_InnerLabel中的字符串 * 返回值 :无 */ void CScrollLabel::GetWindowText(CString &rString) const { m_InnerLabel.GetWindowText(rString); } //////////////////////////////////////////////////////////////////////// /* * 函数名称:SetFont * 函数介绍:设定m_InnerLabel的字体 * 输入参数: CFont *f, 新字体 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::SetFont(CFont *f) { ASSERT_VALID(f); LOGFONT lf; f->GetLogFont(&lf); m_Font.DeleteObject(); m_Font.CreateFontIndirect(&lf); m_InnerLabel.SetFont(&m_Font); CRect rect; this->GetClientRect(&rect); switch (this->m_uScrollStyle) { case SL_NONE: // Reset the size of m_InnerRect and vertically move it this->CalculateTextSize(); m_InnerRect.right = m_InnerRect.left + rect.Width(); switch (this->m_uTextVAlign) { case SL_TA_TOP: m_InnerRect.OffsetRect(-m_InnerRect.left, -m_InnerRect.top); break; case SL_TA_VCENTER: m_InnerRect.OffsetRect(-m_InnerRect.left, (rect.Height() - m_InnerRect.Height())/2 - m_InnerRect.top); break; case SL_TA_BOTTOM: m_InnerRect.OffsetRect(-m_InnerRect.left, rect.bottom - m_InnerRect.bottom); break; default: break; } // Move m_InnerLabel to the rect specified by m_InnerRect m_InnerLabel.MoveWindow(&m_InnerRect); break; case SL_HSCROLLLEFT: case SL_HSCROLLRIGHT: case SL_HSCROLLBOTH: // Reset the size of m_InnerRect and vertically move it this->CalculateTextSize(); switch (this->m_uTextVAlign) { case SL_TA_TOP: m_InnerRect.OffsetRect(-m_InnerRect.left, -m_InnerRect.top); break; case SL_TA_VCENTER: m_InnerRect.OffsetRect(-m_InnerRect.left, (rect.Height() - m_InnerRect.Height())/2 - m_InnerRect.top); break; case SL_TA_BOTTOM: m_InnerRect.OffsetRect(-m_InnerRect.left, rect.bottom - m_InnerRect.bottom); break; default: break; } this->m_bLeft = false; // Move m_InnerLabel to the rect specified by m_InnerRect m_InnerLabel.MoveWindow(&m_InnerRect); break; case SL_HSCROLLAUTO: break; default: break; } m_InnerLabel.Invalidate(); } //////////////////////////////////////////////////////////////////////// /* * 函数名称:GetFont * 函数介绍:返回当前m_InnerLabel的字体 * 输入参数:无 * 输出参数:无 * 返回值 :当前字体 */ CFont *CScrollLabel::GetFont() { return &this->m_Font; } //////////////////////////////////////////////////////////////////////// /* * 函数名称:SetBkColor * 函数介绍:设定背景色 * 输入参数: COLORREF crColor, 新背景色 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::SetBkColor(COLORREF crColor) { m_crBkColor=crColor; // Reset bk brush if (m_hBrush) ::DeleteObject(m_hBrush); m_hBrush = ::CreateSolidBrush(m_crBkColor); m_InnerLabel.Invalidate(); this->Invalidate(); } //////////////////////////////////////////////////////////////////////// /* * 函数名称:GetBkColor * 函数介绍:返回当前底色 * 输入参数:无 * 输出参数:无 * 返回值 :当前底色 */ COLORREF CScrollLabel::GetBkColor() const { return this->m_crBkColor; } //////////////////////////////////////////////////////////////////////// /* * 函数名称:SetTextColor * 函数介绍:设定文字颜色 * 输入参数: COLORREF crColor, 新文字颜色 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::SetTextColor(COLORREF crColor) { m_crTextColor=crColor; m_InnerLabel.Invalidate(); } //////////////////////////////////////////////////////////////////////// /* * 函数名称:GetTextColor * 函数介绍:返回当前文字颜色 * 输入参数:无 * 输出参数:无 * 返回值 :当前文字颜色 */ COLORREF CScrollLabel::GetTextColor() const { return this->m_crTextColor; } //////////////////////////////////////////////////////////////////////// /* * 函数名称:SetStep * 函数介绍:设置步长 * 输入参数: UINT nStep, 新步长 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::SetStep(UINT uStep) { this->m_uStep = uStep; } //////////////////////////////////////////////////////////////////////// /* * 函数名称:GetStep * 函数介绍:返回当前步长 * 输入参数:无 * 输出参数:无 * 返回值 :当前文字步长 */ UINT CScrollLabel::GetStep(void) const { return this->m_uStep; } //////////////////////////////////////////////////////////////////////// /* * 函数名称:SetTick * 函数介绍:设置速度 * 输入参数: UINT nTick, 新速度 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::SetTick(UINT uTick) { this->m_uTick = uTick; this->SetTimer((int)this, this->m_uTick, NULL); } //////////////////////////////////////////////////////////////////////// /* * 函数名称:GetTick * 函数介绍:返回当前速度 * 输入参数:无 * 输出参数:无 * 返回值 :当前文字速度 */ UINT CScrollLabel::GetTick(void) const { return this->m_uTick; } //////////////////////////////////////////////////////////////////////// /* * 函数名称:SetScrollStyle * 函数介绍:设置Scroll效果 * 输入参数: UINT nStyle, 新Scroll效果 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::SetScrollStyle(UINT nStyle) { ASSERT(nStyle < SL_STYLENUM); m_uScrollStyle=nStyle; CRect rect; this->GetClientRect(&rect); switch (this->m_uScrollStyle) { case SL_NONE: // Stop the timer this->KillTimer((int)this); // Reset the size of m_InnerRect and move it to (0,x) m_InnerRect.right = m_InnerRect.left + rect.Width(); m_InnerRect.OffsetRect(-m_InnerRect.left, 0); // Move m_InnerLabel to the rect specified by m_InnerRect m_InnerLabel.MoveWindow(&m_InnerRect); // Reset text align this->SetTextHAlign(this->m_uTextHAlign); break; case SL_HSCROLLLEFT: case SL_HSCROLLRIGHT: case SL_HSCROLLBOTH: // Set text align to Left&NoWrap m_InnerLabel.ModifyStyle(SS_CENTER | SS_RIGHT, SS_LEFT | SS_LEFTNOWORDWRAP); // Reset the size of m_InnerRect and horizontally move it this->CalculateTextSize(); m_InnerRect.OffsetRect(-m_InnerRect.left, 0); m_bLeft = false; // Move m_InnerLabel to the rect specified by m_InnerRect m_InnerLabel.MoveWindow(&m_InnerRect); this->SetTimer((int)this, this->m_uTick, NULL); break; case SL_HSCROLLAUTO: break; default: break; } m_InnerLabel.Invalidate(); } //////////////////////////////////////////////////////////////////////// /* * 函数名称:GetScrollStyle * 函数介绍:返回当前Scroll效果 * 输入参数:无 * 输出参数:无 * 返回值 :当前Scroll效果 */ UINT CScrollLabel::GetScrollStyle() const { return this->m_uScrollStyle; } //////////////////////////////////////////////////////////////////////// /* * 函数名称:SetTextHAlign * 函数介绍:设定水平对齐方式 * 输入参数: UINT nTextHAlign, 新水平对齐方式 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::SetTextHAlign(UINT nTextHAlign) { m_uTextHAlign=nTextHAlign; switch (this->m_uTextHAlign) { case SL_TA_LEFT: // 左对齐且不换行 m_InnerLabel.ModifyStyle(SS_CENTER | SS_RIGHT, SS_LEFT | SS_LEFTNOWORDWRAP); break; case SL_TA_HCENTER: // 中间对齐且换行 m_InnerLabel.ModifyStyle(SS_RIGHT | SS_LEFT | SS_LEFTNOWORDWRAP, SS_CENTER); break; case SL_TA_RIGHT: // 右对齐且换行 m_InnerLabel.ModifyStyle(SS_LEFT | SS_CENTER | SS_LEFTNOWORDWRAP, SS_RIGHT); break; default: break; } m_InnerLabel.Invalidate(); } //////////////////////////////////////////////////////////////////////// /* * 函数名称:GetTextHAlign * 函数介绍:返回当前水平对齐方式 * 输入参数:无 * 输出参数:无 * 返回值 :当前水平对齐方式 */ UINT CScrollLabel::GetTextHAlign() const { return this->m_uTextHAlign; } //////////////////////////////////////////////////////////////////////// /* * 函数名称:SetTextVAlign * 函数介绍:设定垂直对齐方式 * 输入参数: UINT nTextVAlign, 新垂直对齐方式 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::SetTextVAlign(UINT nTextVAlign) { m_uTextVAlign=nTextVAlign; // 将m_InnerLabel移动到(0, x), x的值由垂直对齐方式决定 // CalculateTextSize(); CRect rect; this->GetClientRect(&rect); switch (this->m_uTextVAlign) { case SL_TA_TOP: m_InnerRect.OffsetRect(-m_InnerRect.left, -m_InnerRect.top); break; case SL_TA_VCENTER: m_InnerRect.OffsetRect(-m_InnerRect.left, (rect.Height() - m_InnerRect.Height())/2 - m_InnerRect.top); break; case SL_TA_BOTTOM: m_InnerRect.OffsetRect(-m_InnerRect.left, rect.bottom - m_InnerRect.bottom); break; default: break; } this->m_bLeft = false; m_InnerLabel.MoveWindow(&m_InnerRect); } //////////////////////////////////////////////////////////////////////// /* * 函数名称:GetTextVAlign * 函数介绍:返回当前垂直对齐方式 * 输入参数:无 * 输出参数:无 * 返回值 :当前垂直对齐方式 */ UINT CScrollLabel::GetTextVAlign() const { return this->m_uTextVAlign; } //////////////////////////////////////////////////////////////////////// /* * 函数名称:CalculateTextSize * 函数介绍:计算m_InnerLabel中的字符串的大小,根据结果修改m_InnerRect的大小, 但不改变m_InnerRect左上角的位置 * 输入参数:无 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::CalculateTextSize() { CString str; m_InnerLabel.GetWindowText(str); CDC *pDC = this->GetDC(); CFont *oldfont = pDC->SelectObject(&this->m_Font); CSize size = pDC->GetTextExtent(str); pDC->SelectObject(oldfont); m_InnerRect.right = m_InnerRect.left + size.cx; m_InnerRect.bottom = m_InnerRect.top + size.cy; } //////////////////////////////////////////////////////////////////////// /* * 函数名称:Default * 函数介绍:将文字的各种属性(除文字外)设置为默认值 * 输入参数:无 * 输出参数:无 * 返回值 :无 */ void CScrollLabel::Default() { CFont f; f.Attach(SL_DEFAULT_FONT); this->SetFont(&f); f.DeleteObject(); this->SetBkColor(SL_DEFAULT_BKCOLOR); this->SetTextColor(SL_DEFAULT_TEXTCOLOR); this->SetStep(SL_DEFAULT_STEP); this->SetTick(SL_DEFAULT_TICK); this->SetTextHAlign(SL_DEFAULT_TEXTHALIGN); this->SetTextVAlign(SL_DEFAULT_TEXTVALIGN); this->SetScrollStyle(SL_DEFAULT_SCROLLSTYLE); }