📄 scrollerctrl.cpp
字号:
// CScrollerCtrl : class implementation// Copyright 2002, Joshua Heyer// You are free to use this code for whatever you want, provided you// give credit where credit is due: if you use this code without substantial// modification, please presearve this comment block.// I'm providing this code in the hope that it is useful to someone, as i have// gotten much use out of other peoples code over the years.// If you see value in it, make some improvements, etc., i would appreciate it // if you sent me some feedback.// Have fun!//
#include "stdafx.h"
#include "ScrollerCtrl.h"
// command messages:
// sent when text has scrolled completely off the window
const int CScrollerCtrl::SC_SCROLL_COMPLETE = 0;
// defaults
const int CScrollerCtrl::nSCROLL_DELAY = 80; // time between each frame (milliseconds)
const int CScrollerCtrl::nSCROLL_PAUSE = 5000; // time to pause before autoscrolling (milliseconds)
const int CScrollerCtrl::nMARGIN = 5; // (pixels)
const int CScrollerCtrl::nFONT_SIZE = 12; // (points)
const int CScrollerCtrl::nFONT_WEIGHT = FW_SEMIBOLD;
const char* CScrollerCtrl::szFONT_NAME = "Comic Sans MS";
// initialization
CScrollerCtrl::CScrollerCtrl()
{
m_crBackground = RGB(0,0,0);
m_crForeground = RGB(255,255,255);
m_pbmpPattern = NULL;
m_pbmpLogo = NULL;
m_nContentHeight = 0;
m_nScrollOffset = 0;
m_unTimerPause = 2;
m_nScrollDelay = nSCROLL_DELAY;
m_nScrollPause = nSCROLL_PAUSE;
m_eState = PAUSED;
m_bTilePattern = TRUE;
m_bShowScroll = FALSE;
m_bWrap = TRUE;
m_sizeBuffer = CSize(0,0);
}
// create the window:
// remove WS_VSCROLL to avoid showing scrollbar.
// remove WS_TABSTOP to disable keyboard scrolling.
BOOL CScrollerCtrl::Create(const RECT& rect, CWnd* pParentWnd, UINT uStyle, UINT nID)
{
if ( NULL == m_font.GetSafeHandle() )
SetFont(szFONT_NAME, nFONT_SIZE, nFONT_WEIGHT);
// remember if user specified the style, but don't show initially
m_bShowScroll = uStyle&WS_VSCROLL;
uStyle &= ~WS_VSCROLL;
if ( CWnd::Create(::AfxRegisterWndClass(CS_HREDRAW|CS_PARENTDC|CS_VREDRAW,::LoadCursor(NULL,IDC_ARROW)), "Scroller", uStyle, rect, pParentWnd, nID) )
{
m_eState = PAUSED;
SetTimer(1, m_nScrollDelay, NULL);
m_unTimerPause = SetTimer(m_unTimerPause, m_nScrollPause, NULL);
return TRUE;
}
return FALSE;
}
// activate/deactivate wrapping mode:
// if not set, content is scrolled completely off screen
// before being repeated.
void CScrollerCtrl::SetWrapping(BOOL bWrap)
{
m_bWrap = bWrap;
if ( NULL != m_hWnd )
Invalidate(FALSE);
}
// Sets the color used for the background (if no pattern is set)
// or margins (if pattern is set and not tiled)
void CScrollerCtrl::SetBgColor(COLORREF clrBg)
{
m_crBackground = clrBg;
if ( NULL != m_hWnd )
Invalidate(FALSE);
}
// Sets the color used for text
void CScrollerCtrl::SetFgColor(COLORREF clrBg)
{
m_crForeground = clrBg;
if ( NULL != m_hWnd )
Invalidate(FALSE);
}
// Sets the font; size is in points, see LOGFONT documentation for weight constants
void CScrollerCtrl::SetFont(const CString& strName, int nSize, int nWeight)
{
if ( NULL != m_font.GetSafeHandle() )
m_font.DeleteObject();
LOGFONT logFont;
memset(&logFont,0,sizeof(logFont));
strncpy(logFont.lfFaceName,strName,LF_FACESIZE);
logFont.lfPitchAndFamily = FF_SWISS;
logFont.lfQuality = ANTIALIASED_QUALITY;
logFont.lfWeight = nWeight;
logFont.lfHeight = nSize*10;
// actually create the font; if for some reason this fails, use a default
if ( !m_font.CreatePointFontIndirect(&logFont) )
m_font.CreateStockObject(SYSTEM_FONT);
}
// Sets the text to be displayed
void CScrollerCtrl::SetText(const CString& strText)
{
m_strText = strText;
if ( NULL != m_hWnd )
{
// force RecalcLayout()
m_sizeBuffer = CSize(0,0);
Invalidate(FALSE);
}
}
// Sets the bitmap to be displayed above the text
CBitmap* CScrollerCtrl::SetLogo(CBitmap* pbmpLogo)
{
CBitmap* pbmpOld = m_pbmpLogo;
m_pbmpLogo = pbmpLogo;
if ( NULL != m_hWnd )
{
// force RecalcLayout()
m_sizeBuffer = CSize(0,0);
Invalidate(FALSE);
}
return pbmpOld;
}
// Sets the background pattern
CBitmap* CScrollerCtrl::SetPattern(CBitmap* pbmpPattern, BOOL bTile)
{
m_bTilePattern = bTile;
CBitmap* pbmpOld = m_pbmpPattern;
m_pbmpPattern = pbmpPattern;
if ( NULL != m_hWnd )
Invalidate(FALSE);
return pbmpOld;
}
// Sets the time (in milliseconds) between frames (autoscrolling speed)
// (will revert to default if less than 0)
void CScrollerCtrl::SetScrollDelay(int nScrollDelay)
{
m_nScrollDelay = nScrollDelay;
if ( m_nScrollDelay < 0 )
m_nScrollDelay = nSCROLL_DELAY;
if ( NULL != m_hWnd )
SetTimer(1, m_nScrollDelay, NULL);
}
// Sets the delay (in milliseconds) when autoscrolling pauses
// (will disable pausing if set less than scroll delay)
void CScrollerCtrl::SetScrollPause(int nScrollPause)
{
m_nScrollPause = nScrollPause;
}
BEGIN_MESSAGE_MAP(CScrollerCtrl, CWnd)
ON_WM_ERASEBKGND()
ON_WM_GETDLGCODE()
ON_WM_KEYDOWN()
ON_WM_MOUSEWHEEL()
ON_WM_PAINT()
ON_WM_TIMER()
ON_WM_VSCROLL()
ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()
// CScrollerCtrl message handlers
// entire window is updated in OnPaint() so do nothing here.
BOOL CScrollerCtrl::OnEraseBkgnd(CDC* pDC)
{
return FALSE;
}
// resize buffer first if necessary, then compose onto buffer,
// wrapping if specified, finally update the screen.
void CScrollerCtrl::OnPaint()
{
CPaintDC dc(this);
CDC dcBackBuffer;
dcBackBuffer.CreateCompatibleDC(&dc);
// resize buffer if neccessary, calculate content size.
RecalcLayout(&dc);
CBitmap* pOldBmp = dcBackBuffer.SelectObject(&m_bmpBackBuffer);
FillBackground(&dcBackBuffer);
int nOffset = nMARGIN + m_nScrollOffset;
do
{
nOffset += DrawLogo(&dcBackBuffer, nOffset) + nMARGIN;
nOffset += DrawBodyText(&dcBackBuffer, nOffset) + nMARGIN*2;
} while ( nOffset < m_sizeBuffer.cy && m_bWrap );
dc.BitBlt(0,0,m_sizeBuffer.cx,m_sizeBuffer.cy,&dcBackBuffer,0,0,SRCCOPY);
// cleanup
dcBackBuffer.SelectObject(pOldBmp);
}
// if buffer size does not match window size, resize buffer.
// Calculate content size.
void CScrollerCtrl::RecalcLayout(CDC* pDC)
{
CRect rectClient;
GetClientRect(&rectClient);
if ( m_sizeBuffer != rectClient.Size() )
{
m_sizeBuffer = rectClient.Size();
if ( m_bmpBackBuffer.GetSafeHandle() != NULL )
m_bmpBackBuffer.DeleteObject();
m_bmpBackBuffer.CreateCompatibleBitmap(pDC, m_sizeBuffer.cx, m_sizeBuffer.cy);
m_nContentHeight = nMARGIN*3;
m_nContentHeight += DrawLogo(pDC, 0, FALSE);
m_nContentHeight += DrawBodyText(pDC, 0, FALSE);
}
}
// Draw the background; uses background color unless a pattern
// bitmap is set, in which case that will be tiled or centered.
void CScrollerCtrl::FillBackground(CDC* pDC)
{
CRect rectClient;
GetClientRect(&rectClient);
if ( NULL == m_pbmpPattern )
{
pDC->FillSolidRect(rectClient, m_crBackground);
}
else
{
CDC dcPat;
dcPat.CreateCompatibleDC(pDC);
CBitmap* pbmpOld = dcPat.SelectObject(m_pbmpPattern);
BITMAP bitmap;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -