📄 creditsctrl.cpp
字号:
// CreditsCtrl.cpp : implementation file
// Modified by jingzhou xu
//////////////////////////////////////////
#include "stdafx.h"
#include "Toolmangne.h" //加入应用头文件
#include "CreditsCtrl.h"
#include <afxtempl.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define CCREDITCTRL_TIMER1 100
// use transparent BitBlts if supported? ( UNTESTED!! )
//#define CCREDITCTRL_USE_TRANSPARENT_BITBLT
// stuff that _should_ have been defined in some header :-/
#ifndef C1_TRANSPARENT
#define C1_TRANSPARENT 0x0001
#endif
#ifndef CAPS1
#define CAPS1 94
#endif
#ifndef NEWTRANSPARENT
#define NEWTRANSPARENT 3
#endif
/////////////////////////////////////////////////////////////////////////////
// CCreditsCtrl
LPCTSTR CCreditsCtrl::m_lpszClassName = NULL;
CCreditsCtrl::CCreditsCtrl()
{
m_nTimerSpeed = 40;
m_nCurBitmapOffset = 0;
m_crInternalTransparentColor = RGB(255,0,255);
m_pBackgroundPaint = CCreditsCtrl::DrawBackground;
m_dwBackgroundPaintLParam = GetSysColor(COLOR_BTNFACE);//(DWORD)m_crBackgroundColor;
m_hLinkCursor = NULL;
m_hDefaultCursor = NULL;
m_bCanScroll = TRUE;
m_bIsScrolling = FALSE;
}
CCreditsCtrl::~CCreditsCtrl()
{
}
BEGIN_MESSAGE_MAP(CCreditsCtrl, CWnd)
//{{AFX_MSG_MAP(CCreditsCtrl)
ON_WM_PAINT()
ON_WM_TIMER()
ON_WM_SIZE()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CCreditsCtrl::Create(DWORD dwExStyle, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, UINT nDefaultCursorID, UINT nLinkCursorID)
{
m_hDefaultCursor = nDefaultCursorID == 0 ? NULL : AfxGetApp()->LoadCursor(nDefaultCursorID);
if(nLinkCursorID == 0)
SetDefaultLinkCursor();
else
m_hLinkCursor = AfxGetApp()->LoadCursor(nLinkCursorID);
// register window class & create CWnd object
if (m_lpszClassName == NULL)
m_lpszClassName = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW);
BOOL bResult = CreateEx(dwExStyle, m_lpszClassName, _T(""), dwStyle,
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
pParentWnd->GetSafeHwnd(), (HMENU)nID, NULL );
// start scrolling
if(bResult)
SetTimer(CCREDITCTRL_TIMER1,m_nTimerSpeed*10,NULL);
return bResult;
}
BOOL CCreditsCtrl::Create(DWORD dwExStyle, DWORD dwStyle, UINT nPlaceholderID, CWnd* pParentWnd, UINT nID, UINT nDefaultCursorID, UINT nLinkCursorID)
{
// get rect from placeholder and call create with the found rect
RECT rect;
pParentWnd->GetDlgItem(nPlaceholderID)->GetWindowRect(&rect);
pParentWnd->ScreenToClient(&rect);
return Create(dwExStyle, dwStyle, rect, pParentWnd, nID, nDefaultCursorID, nLinkCursorID);
}
/////////////////////////////////////////////////////////////////////////////
// CCreditsCtrl message handlers
void CCreditsCtrl::OnPaint()
{
static BOOL bFirstDraw = TRUE;
CPaintDC dc(this); // device context for painting
// init memory DC
CDC memDC;
memDC.CreateCompatibleDC(&dc);
int nMemDCSave = memDC.SaveDC();
CBitmap memBmp;
memBmp.CreateCompatibleBitmap(&dc,m_rcClient.Width(),m_rcClient.Height());
memDC.SelectObject(&memBmp);
// draw backgorund
if(m_pBackgroundPaint!=NULL)
(*m_pBackgroundPaint)(&memDC,m_rcClient,m_bIsScrolling||bFirstDraw,m_dwBackgroundPaintLParam);
// calculate hot rectagle position and save background at that location
CDC hotBgDC;
CBitmap hotbgBmp,*pOldHBgBmp;
CRect rcHotRect;
if(m_rcHotRect != CRect(0,0,0,0))
{
hotBgDC.CreateCompatibleDC(&memDC);
hotbgBmp.CreateCompatibleBitmap(&memDC,m_rcHotRect.Width(),m_rcHotRect.Height());
pOldHBgBmp = hotBgDC.SelectObject(&hotbgBmp);
if(m_nBitmapHeight <= m_rcClient.bottom)
rcHotRect = m_rcHotRect;
else if(m_nBitmapHeight-m_nCurBitmapOffset+m_rcHotRect.top < m_rcClient.bottom)
rcHotRect.SetRect(m_rcHotRect.left,m_nBitmapHeight-m_nCurBitmapOffset+m_rcHotRect.top,m_rcHotRect.right,m_nBitmapHeight-m_nCurBitmapOffset+m_rcHotRect.bottom);
else
rcHotRect.SetRect(m_rcHotRect.left,m_rcHotRect.top-m_nCurBitmapOffset,m_rcHotRect.right,m_rcHotRect.bottom-m_nCurBitmapOffset);
hotBgDC.BitBlt(0,0,m_rcHotRect.Width(),m_rcHotRect.Height(),&memDC,rcHotRect.left,rcHotRect.top,SRCCOPY);
}
// draw normal bitmap
if(m_nBitmapHeight <= m_rcClient.bottom)
{
CRect rect = m_rcClient;
rect.bottom = m_nBitmapHeight;
DrawTransparentBitmap(&m_bmpNormal,&memDC,m_crInternalTransparentColor,rect,rect);
} else
{
DrawTransparentBitmap(&m_bmpNormal,&memDC,m_crInternalTransparentColor,CRect(0,0,m_rcClient.right,min(m_nBitmapHeight-m_nCurBitmapOffset,m_rcClient.bottom)),CRect(0,m_nCurBitmapOffset,0,0/*the two last values are not taken into account by DrawTransparentBitmap anyway*/));
if(m_nBitmapHeight-m_nCurBitmapOffset < m_rcClient.bottom)
DrawTransparentBitmap(&m_bmpNormal,&memDC,m_crInternalTransparentColor,CRect(0,m_nBitmapHeight-m_nCurBitmapOffset,m_rcClient.right,m_rcClient.bottom),CRect(0,0,0,0/*the two last values are not taken into account by DrawTransparentBitmap anyway*/));
}
// draw hot rect onto generic background
if(m_rcHotRect != CRect(0,0,0,0))
{
memDC.BitBlt(rcHotRect.left,rcHotRect.top,rcHotRect.Width(),rcHotRect.Height(),&hotBgDC,0,0,SRCCOPY);
DrawTransparentBitmap(&m_bmpHot,&memDC,m_crInternalTransparentColor,rcHotRect,m_rcHotRect);
hotBgDC.SelectObject(pOldHBgBmp);
}
// copy memory DC to screen
dc.BitBlt(0,0,m_rcClient.Width(),m_rcClient.Height(),&memDC,0,0,SRCCOPY);
memDC.RestoreDC(nMemDCSave);
if(bFirstDraw)
bFirstDraw = FALSE;
}
CString CCreditsCtrl::SetDataString(LPCTSTR lpszNewString)
{
CString sOldString = m_sData;
m_sData = lpszNewString;
if(IsWindow(m_hWnd))
Initialize();
return sOldString;
}
CString CCreditsCtrl::SetDataString(UINT nStringResourceID)
{
CString sOldString = m_sData;
m_sData.LoadString(nStringResourceID);
if(IsWindow(m_hWnd))
Initialize();
return sOldString;
}
CString CCreditsCtrl::FormatDataString(LPCTSTR lpszFormat, ...)
{
ASSERT(AfxIsValidString(lpszFormat));
CString sOldString = m_sData; // store old string
// let CString do the formatting
va_list argList;
va_start(argList, lpszFormat);
m_sData.FormatV(lpszFormat, argList);
va_end(argList);
if(IsWindow(m_hWnd)) // Initialize bitmaps if we have already been Create()d
Initialize();
return sOldString;
}
CString CCreditsCtrl::FormatDataString(UINT nFormatID, ...)
{
CString strFormat;
VERIFY(strFormat.LoadString(nFormatID) != 0); // load resource string
CString sOldString = m_sData; // store old string
// let CString do the formatting
va_list argList;
va_start(argList, nFormatID);
m_sData.FormatV(strFormat, argList);
va_end(argList);
if(IsWindow(m_hWnd)) // Initialize bitmaps if we have already been Create()d
Initialize();
return sOldString;
}
CString CCreditsCtrl::GetDataString()
{
return m_sData;
}
void CCreditsCtrl::SetDefaultLinkCursor()
{
// following code is taken from Chris Maunders hyperlink control (http://www.codeproject.com) - tnx
if (m_hLinkCursor == NULL) // No cursor handle - load our own
{
// Get the windows directory
CString strWndDir;
GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH), MAX_PATH);
strWndDir.ReleaseBuffer();
strWndDir += _T("\\winhlp32.exe");
// This retrieves cursor #106 from winhlp32.exe, which is a hand pointer
HMODULE hModule = LoadLibrary(strWndDir);
if (hModule) {
HCURSOR hHandCursor = ::LoadCursor(hModule, MAKEINTRESOURCE(106));
if (hHandCursor)
m_hLinkCursor = CopyCursor(hHandCursor);
}
FreeLibrary(hModule);
}
}
void CCreditsCtrl::OnTimer(UINT nIDEvent)
{
if(nIDEvent == CCREDITCTRL_TIMER1)
{
if(IsWindowVisible())
{
// increment bitmap offset
if(++m_nCurBitmapOffset > m_nBitmapHeight)
m_nCurBitmapOffset = 1;
// update cursor
CPoint point,pt;
GetCursorPos(&point);
pt = point;
ScreenToClient(&point);
if(m_rcClient.PtInRect(point) && WindowFromPoint(pt)==this)
{
CRect rect;
int n;
if((n = HitTest(point)) != -1)
{
rect = m_HotRects[n];
SetCursor(m_hLinkCursor);
}
else
{
rect = CRect(0,0,0,0);
SetCursor(m_hDefaultCursor);
}
if(rect != m_rcHotRect)
m_rcHotRect = rect;
}
// update window
Invalidate(FALSE);
UpdateWindow();
// set timer
SetTimer(CCREDITCTRL_TIMER1,m_nTimerSpeed,NULL);
}
} else
CWnd::OnTimer(nIDEvent);
}
void CCreditsCtrl::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
if(IsWindow(m_hWnd))
GetClientRect(m_rcClient);
Initialize();
}
void CCreditsCtrl::TransparentBlt(CDC *pSrcDC, CDC* pDestDC,COLORREF crTrans,const CRect& rcDest,const CRect& rcSrc)
{
int SaveDestDC = pDestDC->SaveDC();
int SaveSrcDC = pSrcDC->SaveDC();
#ifdef CCREDITCTRL_USE_TRANSPARENT_BITBLT // use transparent BitBlts if supported?
// Only attempt this if device supports functionality. ( untested!! )
if(pDestDC->GetDeviceCaps(CAPS1) & C1_TRANSPARENT)
{
// Special transparency background mode
pDestDC->SetBkMode(NEWTRANSPARENT);
pDestDC->SetBkColor(crTrans);
// Actual blt is a simple source copy; transparency is automatic.
pDestDC->BitBlt(rcDest.left, rcDest.top, rcDest.Width(), rcDest.Height(), pSrcDC, rcSrc.left, rcSrc.top, SRCCOPY);
} else // if driver doesn't support transparent BitBlts, do it the hard way
{
#endif
// initialize memory DC and monochrome mask DC
CDC tmpDC, maskDC;
CBitmap bmpTmp, bmpMask;
int SaveTmpDC, SaveMaskDC;
tmpDC.CreateCompatibleDC(pDestDC);
maskDC.CreateCompatibleDC(pDestDC);
SaveTmpDC = tmpDC.SaveDC();
SaveMaskDC = maskDC.SaveDC();
bmpTmp.CreateCompatibleBitmap(pDestDC,rcDest.Width(),rcDest.Height());
bmpMask.CreateBitmap(rcDest.Width(),rcDest.Height(),1,1,NULL);
tmpDC.SelectObject(&bmpTmp);
maskDC.SelectObject(&bmpMask);
// copy existing data from destination dc to memory dc
tmpDC.BitBlt(0,0,rcDest.Width(),rcDest.Height(),pDestDC,rcDest.left,rcDest.top,SRCCOPY);
// create mask
pSrcDC->SetBkColor(crTrans);
maskDC.BitBlt(0,0,rcDest.Width(),rcDest.Height(),pSrcDC,rcSrc.left,rcSrc.top,SRCCOPY);
// do some BitBlt magic
tmpDC.SetBkColor(RGB(255,255,255));
tmpDC.SetTextColor(RGB(0,0,0));
tmpDC.BitBlt(0,0,rcDest.Width(),rcDest.Height(),pSrcDC,rcSrc.left,rcSrc.top,SRCINVERT);
tmpDC.BitBlt(0,0,rcDest.Width(),rcDest.Height(),&maskDC,0,0,SRCAND);
tmpDC.BitBlt(0,0,rcDest.Width(),rcDest.Height(),pSrcDC,rcSrc.left,rcSrc.top,SRCINVERT);
// copy what we have in our memory DC to the destination DC
pDestDC->BitBlt(rcDest.left,rcDest.top,rcDest.Width(),rcDest.Height(),&tmpDC,0,0,SRCCOPY);
// clean up
tmpDC.RestoreDC(SaveTmpDC);
maskDC.RestoreDC(SaveMaskDC);
#ifdef CCREDITCTRL_USE_TRANSPARENT_BITBLT
}
#endif
pDestDC->RestoreDC(SaveDestDC);
pSrcDC->RestoreDC(SaveSrcDC);
}
void CCreditsCtrl::DrawTransparentBitmap(CBitmap *pBitmap, CDC* pDC,COLORREF crTrans,const CRect& rcDest,const CRect& rcSrc)
{
int SaveImageDC;
// initialize image DC
CDC imageDC;
imageDC.CreateCompatibleDC(pDC);
SaveImageDC = imageDC.SaveDC();
imageDC.SelectObject(pBitmap);
TransparentBlt(&imageDC,pDC,crTrans,rcDest,rcSrc);
// clean up
imageDC.RestoreDC(SaveImageDC);
}
void CCreditsCtrl::Initialize()
{
//// [Initialize] ///////////////////////////////////////
// //
// Create bitmaps and calc hot regions from m_sData //
// //
/////////////////////////////////////////////////////////
int nMaxHeight = 5000;
// initialize normal and hot DCs
CDC *pDC = GetDC();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -