mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
446 lines
10 KiB
446 lines
10 KiB
// CreditStatic.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "CreditSt.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
// defined in MAIN.CPP
|
|
extern HINSTANCE ghInstance;
|
|
|
|
#define DISPLAY_TIMER_ID 150 // timer id
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CCreditStatic
|
|
|
|
CCreditStatic::CCreditStatic()
|
|
{
|
|
|
|
m_Colors[0] = RGB(0,0,255); // Black
|
|
m_Colors[1] = RGB(255,0,0); // Red
|
|
m_Colors[2] = RGB(0,128,0); // John Deer Green
|
|
m_Colors[3] = RGB(0,255,255); // Turquoise
|
|
m_Colors[4] = RGB(255,255,255); // White
|
|
|
|
m_TextHeights[0] = 36;
|
|
m_TextHeights[1] = 34;
|
|
m_TextHeights[2] = 34;
|
|
m_TextHeights[3] = 30;
|
|
m_nCurrentFontHeight = m_TextHeights[NORMAL_TEXT_HEIGHT];
|
|
|
|
|
|
m_Escapes[0] = '\t';
|
|
m_Escapes[1] = '\n';
|
|
m_Escapes[2] = '\r';
|
|
m_Escapes[3] = '^';
|
|
|
|
/*
|
|
m_DisplaySpeed[0] = 75;
|
|
m_DisplaySpeed[1] = 65;
|
|
m_DisplaySpeed[2] = 15;
|
|
*/
|
|
|
|
m_CurrentSpeed = 15; //DISPLAY_FAST;
|
|
m_ScrollAmount = -1;
|
|
|
|
m_ArrIndex = NULL;
|
|
m_nCounter = 31;
|
|
m_nClip = 0;
|
|
|
|
m_bFirstTurn = TRUE;
|
|
m_Gradient = GRADIENT_RIGHT_DARK;
|
|
n_MaxWidth = 0;
|
|
TimerOn = 0;
|
|
m_szWork = NULL;
|
|
}
|
|
|
|
CCreditStatic::~CCreditStatic()
|
|
{
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CCreditStatic, CStatic)
|
|
//{{AFX_MSG_MAP(CCreditStatic)
|
|
ON_WM_ERASEBKGND()
|
|
ON_WM_TIMER()
|
|
ON_WM_DESTROY()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CCreditStatic message handlers
|
|
|
|
BOOL CCreditStatic::StartScrolling()
|
|
{
|
|
if(m_pArrCredit->IsEmpty())
|
|
return FALSE;
|
|
|
|
if (m_BmpMain)
|
|
{
|
|
DeleteObject(m_BmpMain);
|
|
m_BmpMain = NULL;
|
|
}
|
|
|
|
::GetClientRect(this->m_hWnd, &m_ScrollRect);
|
|
|
|
TimerOn = (UINT)SetTimer(DISPLAY_TIMER_ID, m_CurrentSpeed, NULL);
|
|
ASSERT(TimerOn != 0);
|
|
|
|
m_ArrIndex = m_pArrCredit->GetHeadPosition();
|
|
// m_nCounter = 1;
|
|
// m_nClip = 0;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CCreditStatic::EndScrolling()
|
|
{
|
|
KillTimer(DISPLAY_TIMER_ID);
|
|
TimerOn = 0;
|
|
|
|
if (m_BmpMain)
|
|
{
|
|
DeleteObject(m_BmpMain);
|
|
m_BmpMain = NULL;
|
|
}
|
|
}
|
|
|
|
void CCreditStatic::SetCredits(LPCTSTR credits,TCHAR delimiter)
|
|
{
|
|
LPTSTR str,ptr1,ptr2;
|
|
|
|
ASSERT(credits);
|
|
|
|
if ((str = _tcsdup(credits)) == NULL)
|
|
return;
|
|
|
|
m_pArrCredit = new (CStringList);
|
|
ASSERT (m_pArrCredit);
|
|
|
|
m_pArrCredit->RemoveAll();
|
|
|
|
ptr1 = str;
|
|
while((ptr2 = _tcschr(ptr1,delimiter)) != NULL)
|
|
{
|
|
*ptr2 = '\0';
|
|
m_pArrCredit->AddTail(ptr1);
|
|
ptr1 = ptr2+1;
|
|
}
|
|
m_pArrCredit->AddTail(ptr1);
|
|
|
|
free(str);
|
|
|
|
m_ArrIndex = m_pArrCredit->GetHeadPosition();
|
|
// m_nCounter = 1;
|
|
// m_nClip = 0;
|
|
}
|
|
|
|
BOOL CCreditStatic::OnEraseBkgnd(CDC* pDC)
|
|
{
|
|
return TRUE;
|
|
|
|
// return CStatic::OnEraseBkgnd(pDC);
|
|
}
|
|
|
|
//************************************************************************
|
|
// OnTimer
|
|
//
|
|
// On each of the display timers, scroll the window 1 unit. Each 20
|
|
// units, fetch the next array element and load into work string. Call
|
|
// Invalidate and UpdateWindow to invoke the OnPaint which will paint
|
|
// the contents of the newly updated work string.
|
|
//************************************************************************
|
|
void CCreditStatic::OnTimer(UINT nIDEvent)
|
|
{
|
|
BOOL bCheck = FALSE;
|
|
|
|
if (m_nCounter++ % m_nCurrentFontHeight == 0) // every x timer events, show new line
|
|
{
|
|
m_nCounter=1;
|
|
m_szWork = (LPCTSTR)m_pArrCredit->GetNext(m_ArrIndex);
|
|
|
|
if(m_bFirstTurn)
|
|
bCheck = TRUE;
|
|
|
|
if (m_ArrIndex == NULL)
|
|
{
|
|
m_bFirstTurn = FALSE;
|
|
m_ArrIndex = m_pArrCredit->GetHeadPosition();
|
|
}
|
|
m_nClip = 0;
|
|
}
|
|
|
|
HDC hMainDC = this->GetDC()->m_hDC;
|
|
RECT rc = m_ScrollRect;
|
|
|
|
rc.left = ((rc.right-rc.left)-n_MaxWidth)/2;
|
|
rc.right = rc.left + n_MaxWidth;
|
|
|
|
HDC hDC = ::CreateCompatibleDC(hMainDC);
|
|
|
|
// Don't try to scroll credits you don't have!
|
|
if (m_szWork)
|
|
MoveCredit(&hMainDC, rc, bCheck);
|
|
else
|
|
FillGradient(&hMainDC, m_ScrollRect);
|
|
|
|
::SelectObject(hDC, m_BmpMain);
|
|
::BitBlt(hMainDC, 0, 0, m_ScrollRect.right-m_ScrollRect.left, m_ScrollRect.bottom-m_ScrollRect.top, hDC, 0, 0, SRCCOPY);
|
|
|
|
::ReleaseDC(this->m_hWnd, hMainDC);
|
|
::DeleteDC(hDC);
|
|
|
|
CStatic::OnTimer(nIDEvent);
|
|
}
|
|
|
|
void CCreditStatic::FillGradient(HDC *pDC, RECT& FillRect)
|
|
{
|
|
float fStep,fRStep,fGStep,fBStep; // How large is each band?
|
|
|
|
WORD R = GetRValue(m_Colors[BACKGROUND_COLOR]);
|
|
WORD G = GetGValue(m_Colors[BACKGROUND_COLOR]);
|
|
WORD B = GetBValue(m_Colors[BACKGROUND_COLOR]);
|
|
|
|
// Determine how large each band should be in order to cover the
|
|
// client with 256 bands (one for every color intensity level)
|
|
//if(m_Gradient % 2)
|
|
//{
|
|
fRStep = (float)R / 255.0f;
|
|
fGStep = (float)G / 255.0f;
|
|
fBStep = (float)B / 255.0f;
|
|
/*
|
|
}
|
|
else
|
|
{
|
|
fRStep = (float)(255-R) / 255.0f;
|
|
fGStep = (float)(255-G) / 255.0f;
|
|
fBStep = (float)(255-B) / 255.0f;
|
|
}
|
|
*/
|
|
|
|
COLORREF OldCol = ::GetBkColor(*pDC);
|
|
RECT rc;
|
|
|
|
// Start filling bands
|
|
fStep = (float)(m_ScrollRect.right-m_ScrollRect.left) / 256.0f;
|
|
|
|
for (short iOnBand = (short)((256*FillRect.left)/(m_ScrollRect.right-m_ScrollRect.left));
|
|
(int)(iOnBand*fStep) < FillRect.right && iOnBand < 256; iOnBand++)
|
|
{
|
|
::SetRect(&rc,
|
|
(int)(iOnBand * fStep),
|
|
FillRect.top,
|
|
(int)((iOnBand+1) * fStep),
|
|
FillRect.bottom+1);
|
|
|
|
// If we want to enable gradient filling from any direction!
|
|
/*
|
|
switch(m_Gradient)
|
|
{
|
|
case GRADIENT_RIGHT_DARK:
|
|
col = RGB((int)(R-iOnBand*fRStep),(int)(G-iOnBand*fGStep),(int)(B-iOnBand*fBStep));
|
|
break;
|
|
case GRADIENT_RIGHT_LIGHT:
|
|
col = RGB((int)(R+iOnBand*fRStep),(int)(G+iOnBand*fGStep),(int)(B+iOnBand*fBStep));
|
|
break;
|
|
case GRADIENT_LEFT_DARK:
|
|
col = RGB((int)(iOnBand*fRStep),(int)(iOnBand*fGStep),(int)(iOnBand*fBStep));
|
|
break;
|
|
case GRADIENT_LEFT_LIGHT:
|
|
col = RGB(255-(int)(iOnBand*fRStep),255-(int)(iOnBand*fGStep),255-(int)(iOnBand*fBStep));
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
*/
|
|
::SetBkColor(*pDC, RGB((int)(R-iOnBand*fRStep),(int)(G-iOnBand*fGStep),(int)(B-iOnBand*fBStep)));
|
|
::ExtTextOut(*pDC, 0, 0, ETO_OPAQUE, &rc, NULL, 0, NULL);
|
|
|
|
}
|
|
::SetBkColor(*pDC, OldCol);
|
|
}
|
|
|
|
void CCreditStatic::MoveCredit(HDC* pDC, RECT& ClientRect, BOOL bCheck)
|
|
{
|
|
HDC hMemDC = ::CreateCompatibleDC(*pDC);
|
|
|
|
HBITMAP *pOldMemDCBitmap = NULL;
|
|
HFONT *pOldFont = NULL;
|
|
|
|
RECT r1;
|
|
|
|
if (m_BmpMain == NULL)
|
|
{
|
|
m_BmpMain = ::CreateCompatibleBitmap(*pDC, m_ScrollRect.right-m_ScrollRect.left, m_ScrollRect.bottom-m_ScrollRect.top );
|
|
|
|
pOldMemDCBitmap = (HBITMAP *)::SelectObject(hMemDC, m_BmpMain);
|
|
|
|
FillGradient(&hMemDC, m_ScrollRect);
|
|
} else pOldMemDCBitmap = (HBITMAP *)::SelectObject(hMemDC, m_BmpMain);
|
|
|
|
|
|
if ((ClientRect.right-ClientRect.left) > 0)
|
|
{
|
|
::ScrollDC(hMemDC, 0, m_ScrollAmount, &m_ScrollRect, &ClientRect, NULL, &r1);
|
|
}
|
|
else
|
|
{
|
|
r1 = m_ScrollRect;
|
|
r1.top = r1.bottom-abs(m_ScrollAmount);
|
|
}
|
|
|
|
m_nClip = m_nClip + abs(m_ScrollAmount);
|
|
|
|
|
|
//*********************************************************************
|
|
// FONT SELECTIlON
|
|
short rmcode = 1;
|
|
|
|
if (lstrlen(m_szWork))
|
|
{
|
|
BYTE bUnderline, bItalic;
|
|
bUnderline = bItalic = FALSE;
|
|
|
|
COLORREF nTmpColour = m_Colors[TOP_LEVEL_GROUP_COLOR];
|
|
|
|
TCHAR c = m_szWork[lstrlen(m_szWork)-1];
|
|
|
|
if(c == m_Escapes[TOP_LEVEL_GROUP])
|
|
{
|
|
m_nCurrentFontHeight = m_TextHeights[TOP_LEVEL_GROUP_HEIGHT];
|
|
}
|
|
else if(c == m_Escapes[GROUP_TITLE])
|
|
{
|
|
m_nCurrentFontHeight = m_TextHeights[GROUP_TITLE_HEIGHT];
|
|
nTmpColour = m_Colors[GROUP_TITLE_COLOR];
|
|
}
|
|
else if(c == m_Escapes[TOP_LEVEL_TITLE])
|
|
{
|
|
m_nCurrentFontHeight = m_TextHeights[TOP_LEVEL_TITLE_HEIGHT];
|
|
nTmpColour = m_Colors[TOP_LEVEL_TITLE_COLOR];
|
|
}
|
|
|
|
// If this were application critical, I'd make an array of fonts a member
|
|
// and create all the fonts prior to starting the timer!
|
|
HFONT pfntArial = ::CreateFont(m_nCurrentFontHeight, 0, 0, 0,
|
|
FW_BOLD, bItalic, bUnderline, 0,
|
|
ANSI_CHARSET,
|
|
OUT_DEFAULT_PRECIS,
|
|
CLIP_DEFAULT_PRECIS,
|
|
PROOF_QUALITY,
|
|
VARIABLE_PITCH | 0x04 | FF_DONTCARE,
|
|
(LPCTSTR)"Arial");
|
|
|
|
::SetTextColor(hMemDC, nTmpColour);
|
|
|
|
if (pOldFont != NULL)
|
|
::SelectObject(hMemDC, pOldFont);
|
|
|
|
pOldFont = (HFONT *)::SelectObject(hMemDC, pfntArial);
|
|
}
|
|
|
|
FillGradient(&hMemDC, r1);
|
|
|
|
::SetBkMode(hMemDC, TRANSPARENT);
|
|
|
|
if(bCheck)
|
|
{
|
|
SIZE size;
|
|
::GetTextExtentPoint(hMemDC, (LPCTSTR)m_szWork,lstrlen(m_szWork)-rmcode, &size);
|
|
|
|
if (size.cx > n_MaxWidth)
|
|
{
|
|
n_MaxWidth = (short)((size.cx > (m_ScrollRect.right-m_ScrollRect.left)) ? (m_ScrollRect.right-m_ScrollRect.left) : size.cx);
|
|
ClientRect.left = ((m_ScrollRect.right-m_ScrollRect.left)-n_MaxWidth)/2;
|
|
ClientRect.right = ClientRect.left + n_MaxWidth;
|
|
}
|
|
|
|
}
|
|
|
|
RECT r = ClientRect;
|
|
r.top = r.bottom-m_nClip;
|
|
|
|
DrawText(hMemDC, (LPCTSTR)m_szWork,lstrlen(m_szWork)-rmcode,&r,DT_TOP|DT_CENTER|DT_NOPREFIX | DT_SINGLELINE);
|
|
|
|
if (pOldFont != NULL)
|
|
::SelectObject(hMemDC, pOldFont);
|
|
|
|
::SelectObject(hMemDC, pOldMemDCBitmap);
|
|
|
|
::DeleteDC(hMemDC);
|
|
}
|
|
|
|
void CCreditStatic::OnDestroy()
|
|
{
|
|
CStatic::OnDestroy();
|
|
|
|
m_pArrCredit->RemoveAll();
|
|
|
|
if (m_pArrCredit)
|
|
delete (m_pArrCredit);
|
|
|
|
if(TimerOn)
|
|
EndScrolling();
|
|
}
|
|
|
|
/* In the event we ever want a few library routines!
|
|
void CCreditStatic::SetCredits(UINT nID, TCHAR delimiter)
|
|
{
|
|
LPTSTR lpCredits = new (TCHAR[255]);
|
|
ASSERT (lpCredits);
|
|
|
|
::LoadString(ghInstance, nID, lpCredits, 255);
|
|
|
|
SetCredits((LPCTSTR)lpCredits, delimiter);
|
|
|
|
if (lpCredits)
|
|
delete[] (lpCredits);
|
|
}
|
|
|
|
void CCreditStatic::SetSpeed(UINT index, int speed)
|
|
{
|
|
ASSERT(index <= DISPLAY_FAST);
|
|
|
|
if(speed)
|
|
m_DisplaySpeed[index] = speed;
|
|
|
|
m_CurrentSpeed = index;
|
|
}
|
|
|
|
void CCreditStatic::SetColor(UINT index, COLORREF col)
|
|
{
|
|
ASSERT(index <= NORMAL_TEXT_COLOR);
|
|
|
|
m_Colors[index] = col;
|
|
}
|
|
|
|
void CCreditStatic::SetTextHeight(UINT index, int height)
|
|
{
|
|
ASSERT(index <= NORMAL_TEXT_HEIGHT);
|
|
|
|
m_TextHeights[index] = height;
|
|
}
|
|
|
|
void CCreditStatic::SetEscape(UINT index, char escape)
|
|
{
|
|
ASSERT(index <= DISPLAY_BITMAP);
|
|
|
|
m_Escapes[index] = escape;
|
|
}
|
|
|
|
void CCreditStatic::SetGradient(UINT value)
|
|
{
|
|
ASSERT(value <= GRADIENT_LEFT_LIGHT);
|
|
|
|
m_Gradient = value;
|
|
}
|
|
|
|
void CCreditStatic::SetTransparent(BOOL bTransparent)
|
|
{
|
|
m_bTransparent = bTransparent;
|
|
}
|
|
*/
|