15,979
社区成员
发帖
与我相关
我的任务
分享
// .cpp
// CaptionScroll.cpp : implementation file
//
#include "stdafx.h"
#include <locale>
#include <math.h>
#include "CaptionScroll.h"
// CCaptionScroll
IMPLEMENT_DYNAMIC(CCaptionScroll, CWnd)
CCaptionScroll::CCaptionScroll()
: m_clrBk(255, 220, 220, 220)
, m_clrFont(255, 0,0,0)
, m_fontSize(18.0f)
, m_fontType(_T("宋体"))
, m_percent(0.0f)
, m_indTopLine(0)
#ifdef _USE_FLOAT__
, m_scrollStep(1.0f)
, m_lineOffset(0.0f)
, m_fontPixHeight(0.0f)
, m_txtHeight(0.0f)
, m_lineDis(2.0f)
#else
, m_scrollStep(1)
, m_lineOffset(0)
, m_fontPixHeight(0)
, m_txtHeight(0)
, m_lineDis(2)
#endif
, m_timeLen(0.0f)
, m_timeCur(0.0f)
, m_pOwnerWnd(NULL)
, m_bDragAble(false)
{
}
void
CCaptionScroll::SetDragAble(bool b)
{
m_bDragAble = b;
}
bool
CCaptionScroll::SetCaptionFile(const CString& fileName)
{
Clear();
bool bRes = true;
if (m_capFile.Open(fileName, CStdioFile::modeRead|CFile::typeText) != FALSE)
{
char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );
setlocale( LC_CTYPE, "chs" ); //设定
// TODO: if the file is biggish, not read all strings once.
// catch some of them, and catch more after free some old catch if be needed.
BOOL bRes = FALSE;
do
{
try
{
CString strLine;
bRes = m_capFile.ReadString(strLine);
if (bRes != FALSE)
{
m_arrlistStr.Add(strLine);
}
}
catch (CFileException* e)
{
e;
MessageBox(_T("文件读取失败!"));
bRes = false;
break;
}
} while (bRes);
setlocale( LC_CTYPE, old_locale ); //还原区域设定
free( old_locale );
m_capFile.Close(); // if use cache, do not close file here
}
else
{
bRes = false;
}
Invalidate();
return bRes;
}
void
CCaptionScroll::AutoScroll(int direction, UINT nElapse)
{
SetTimer(direction, nElapse, NULL);
}
void
CCaptionScroll::ScrollUp()
{
static int i = 0;
int numAllLines = m_arrlistStr.GetCount();
if (m_indTopLine < numAllLines)
{
#ifdef _USE_FLOAT__
REAL lineH = m_fontPixHeight + m_lineDis;
#else
int lineH = m_fontPixHeight + m_lineDis;
#endif
m_lineOffset -= m_scrollStep;
if (m_lineOffset < -lineH)
{
m_lineOffset = m_lineOffset + lineH;
++m_indTopLine;
}
Invalidate();
}
}
void
CCaptionScroll::GotoPercent(float percent)
{
#ifdef _USE_FLOAT__
float lineH = m_fontPixHeight + m_lineDis;
int numAllLines = m_arrlistStr.GetSize();
float txtHeight = lineH * numAllLines;
float pos = txtHeight * percent;
m_indTopLine = (int)(pos / lineH);
m_lineOffset = -fmod(pos, lineH);
Invalidate();
#else
int lineH = m_fontPixHeight + m_lineDis;
int numAllLines = m_arrlistStr.GetSize();
int txtHeight = lineH * numAllLines;
int pos = int(txtHeight * percent);
m_indTopLine = (int)(pos / lineH);
m_lineOffset = -pos % lineH;
Invalidate();
#endif
}
float
CCaptionScroll::CurrPercent()
{
return m_percent;
}
void
CCaptionScroll::Reset()
{
#ifdef _USE_FLOAT__
m_percent = 0.0f;
m_indTopLine = 0;
m_lineOffset = 0.0f;
m_timeCur = 0.0f;
Invalidate();
#else
m_percent = 0;
m_indTopLine = 0;
m_lineOffset = 0;
m_timeCur = 0;
Invalidate();
#endif
}
void
CCaptionScroll::Clear()
{
if (m_capFile.m_hFile != CStdioFile::hFileNull)
{
m_capFile.Close();
}
m_arrlistStr.RemoveAll();
Reset();
#ifdef _USE_FLOAT__
m_timeLen = 0.0f;
m_txtHeight = 0.0f;
#else
m_timeLen = 0;
m_txtHeight = 0;
#endif
Invalidate();
}
void
CCaptionScroll::UpdateCurTime()
{
if (m_timeLen > 0 && m_timeCur <= m_timeLen)
{
if (m_timeCur > 0)
{
float percent = float(m_timeCur / m_timeLen);
GotoPercent(percent);
}
else if (m_timeCur == 0)
{
Reset();
}
}
}
//////////////////////////////////////////////////////////////////////////
void
CCaptionScroll::OnDraw(CDC* pDC)
{
Gdiplus::Graphics graphics(pDC->m_hDC);
graphics.Clear(m_clrBk);
int numLines = m_arrlistStr.GetCount();
if (numLines > 0)
{
Gdiplus::Font font(m_fontType, m_fontSize);
Gdiplus::SolidBrush brush(m_clrFont);
Gdiplus::StringFormat stringFormat;
stringFormat.SetAlignment(StringAlignmentNear);
stringFormat.SetLineAlignment(StringAlignmentNear);
#ifdef _USE_FLOAT__
REAL drewdHeight = 0;
REAL lineH = m_fontPixHeight + m_lineDis;
#else
int drewdHeight = 0;
int lineH = m_fontPixHeight + m_lineDis;
#endif
//Gdiplus::RectF rcLine((REAL)(m_rcClnt.left), (REAL)(m_rcClnt.top + m_lineOffset), (REAL)(m_rcClnt.Width()), m_fontPixHeight);
PointF ptOrg(0, (REAL)(m_rcClnt.top + m_lineOffset));
int numAllLines = m_arrlistStr.GetCount();
for (int ind = m_indTopLine; (ind < numAllLines) && (drewdHeight < m_rcClnt.bottom + lineH); ++ind)
{
const CString& str = m_arrlistStr.GetAt(ind);
if (!str.IsEmpty())
{
//graphics.DrawString(str, str.GetLength(), &font, rcLine, &stringFormat, &brush);
graphics.DrawString(str, str.GetLength(), &font, ptOrg, &brush);
// Gdiplus::GraphicsPath path;
// FontFamily fontFamily(m_fontType);
// path.AddString(str, str.GetLength(), &fontFamily, 0, m_fontSize, ptOrg, &stringFormat);
// graphics.FillPath(&brush, &path);
}
drewdHeight += lineH;
// rcLine.Y += lineH;
ptOrg.Y += lineH;
}
}
//int r = m_clrBk.GetR();
//int g = m_clrBk.GetG();
//int b = m_clrBk.GetB();
//COLORREF clrBk( RGB( r,g,b));
//CBrush brushBk( clrBk);
//pDC->SetBkMode(TRANSPARENT); //设置背景为透明!
//pDC->FillRect(m_rcClnt, &brushBk);
// int numLines = m_arrlistStr.GetCount();
// if (numLines > 0)
// {
// int y = m_lineOffset;
// int drewHeight = 0;
// int lineH = 18 + m_lineDis;
// for (int ind = m_indTopLine; (ind < numLines) && (drewHeight < m_rcClnt.bottom + lineH); ++ind)
// {
// const CString& str = m_arrlistStr.GetAt(ind);
// pDC->TextOut(0,y, str, str.GetLength());
// drewHeight += lineH;
// y += lineH;
// }
//}
}
BEGIN_MESSAGE_MAP(CCaptionScroll, CWnd)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_SIZE()
ON_WM_MOVE()
ON_WM_TIMER()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_MOUSEWHEEL()
ON_WM_KEYUP()
END_MESSAGE_MAP()
// CCaptionScroll message handlers
int
CCaptionScroll::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
{
return -1;
}
CDC* pDC = GetDC();
Gdiplus::Graphics graphics(pDC->m_hDC);
Gdiplus::Font font(m_fontType, m_fontSize);
#ifdef _USE_FLOAT__
m_fontPixHeight = font.GetHeight(&graphics);
#else
m_fontPixHeight = (int)(font.GetHeight(&graphics) + 1);
#endif
ReleaseDC(pDC);
return 0;
}
void
CCaptionScroll::OnDestroy()
{
Clear();
CWnd::OnDestroy();
}
void
CCaptionScroll::OnPaint()
{
CWnd::OnPaint();
m_pDC = GetDC();
m_memDC.CreateCompatibleDC(m_pDC);
// 创建与m_pDC相兼容的内存位图
m_memBitmap.CreateCompatibleBitmap( m_pDC, m_rcSelf.Width(), m_rcSelf.Height());
// 内存绘图设备选择内存位图为绘制区
m_pOldBmp = m_memDC.SelectObject( &m_memBitmap);
// 创建内存绘图区
m_memDC.BitBlt( 0, 0, m_rcSelf.Width(), m_rcSelf.Height(), m_pDC, 0, 0, SRCCOPY);
// 使用内存设备,在内存位图中画图
OnDraw(&m_memDC);
// 使用屏幕设备,把内存设备中的图像画到屏幕上
m_pDC->BitBlt( 0, 0, m_rcSelf.Width(), m_rcSelf.Height(), &m_memDC, 0, 0, SRCCOPY);
m_memDC.SelectObject(m_pOldBmp);
m_memBitmap.DeleteObject();
m_memDC.DeleteDC();
ReleaseDC(m_pDC);
}
BOOL
CCaptionScroll::OnEraseBkgnd(CDC* pDC)
{
//return CWnd::OnEraseBkgnd(pDC);
return TRUE;
}
void
CCaptionScroll::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
GetWindowRect(&m_rcSelf);
GetClientRect(&m_rcClnt);
}
void
CCaptionScroll::OnMove(int x, int y)
{
CWnd::OnMove(x,y);
}
void
CCaptionScroll::OnTimer(UINT_PTR nIDEvent)
{
CWnd::OnTimer(nIDEvent);
if (nIDEvent == 0)
{
ScrollUp();
}
else if (nIDEvent == 1)
{
ScrollDown();
}
}
void
CCaptionScroll::OnLButtonDown(UINT nFlags, CPoint point)
{
CWnd::OnLButtonDown(nFlags, point);
m_oldMousePt = point;
ClientToScreen(&m_oldMousePt);
}
void
CCaptionScroll::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd::OnMouseMove(nFlags, point);
SetFocus();
if ( m_bDragAble &&
((nFlags & MK_LBUTTON) == MK_LBUTTON)
)
{
ClientToScreen(&point);
if (m_oldMousePt != point)
{
int offsetW = point.x - m_oldMousePt.x;
int offsetH = point.y - m_oldMousePt.y;
m_rcSelf.left += offsetW;
m_rcSelf.right += offsetW;
m_rcSelf.top += offsetH;
m_rcSelf.bottom += offsetH;
MoveWindow(m_rcSelf);
m_oldMousePt = point;
}
//Invalidate();
UpdateWindow();
}
}
// .h
#pragma once
// CCaptionScroll
#define _USE_FLOAT__
class CCaptionScroll : public CWnd
{
DECLARE_DYNAMIC(CCaptionScroll)
public:
enum ViewMode
{
ModeFixedSize,
ModeAutoSize
};
CCaptionScroll();
virtual ~CCaptionScroll();
void SetMyOwner(CWnd* pWnd);
void SetDragAble(bool b);
bool SetCaptionFile(const CString& fileName);
void SetFontType(const CString& type);(/*Font, FontColor, FontSize*/);
const CString& GetFontType();
DWORD SetFontColor(DWORD dwARGB);
DWORD GetFontColor();
DWORD SetBkColor(DWORD dwARGB);
DWORD GetBkColor();
#ifdef _USE_FLOAT__
float SetStep(float step); // each time, the string scroll`s length.
float GetStep();
float SetLineDis(float dis);
float GetLineDis();
#else
int SetStep(int step);
int GetStep();
int SetLineDis(int dis);
int GetLineDis();
#endif
// ViewMode SetMode(ViewMode mode);
void AutoScroll(int direction, UINT nElapse);
void ScrollUp();
void ScrollDown();
void SetTimeLen(double dSecLen);
double GetTimeLen();
void SetTimeCur(double dSecCur);
double GetTimeCur();
void GotoPercent(float percent);
float CurrPercent();
void Reset();
void Clear();
protected:
virtual void OnDraw(CDC* pDC);
void UpdateCurTime();
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnMove(int x, int y);
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
DECLARE_MESSAGE_MAP()
private:
// GDI+程序启动的标识
ULONG_PTR m_gdiplusToken;
//Gdiplus::Graphics* m_pGraphics;
CDC* m_pDC; // 用于画图的DC
CDC m_memDC; // 内存DC
CBitmap m_memBitmap; // 内存位图
CBitmap* m_pOldBmp; // 旧的位图指针
CRect m_rcSelf;
CRect m_rcClnt;
CWnd* m_pOwnerWnd;
bool m_bDragAble;
CStdioFile m_capFile;
CStringArray m_arrlistStr;
float m_percent;
int m_indTopLine; // 第一行显示字符串缓存中的第几行
#ifdef _USE_FLOAT__
REAL m_lineDis; // 行间距
REAL m_scrollStep; // 滚动的单元长度
float m_lineOffset;
REAL m_fontPixHeight; // 文字的像素高
REAL m_txtHeight;
#else
int m_lineDis;
int m_scrollStep;
int m_lineOffset;
int m_fontPixHeight;
int m_txtHeight;
#endif
double m_timeLen;
double m_timeCur;
CString m_fontType;
Gdiplus::REAL m_fontSize;
Gdiplus::Color m_clrBk;
Gdiplus::Color m_clrFont;
CPoint m_oldMousePt;
};