在VC++ 6.0中实现固定背景上的滚动文本

在Visual C++ 6.0中创建一个具有固定背景图像的滚动文本视图是一个有趣的挑战。本文将指导如何通过MFC框架实现这一功能。请注意,本教程仅在Windows XP操作系统上进行了测试。

创建MFCDoc/View项目

首先,需要创建一个MFC文档/视图项目,并选择CScrollView作为基础视图类。这是因为CScrollView类能够处理所有的滚动逻辑。接下来,添加一个想要作为窗口背景的位图资源。然后在框架窗口类中创建一个CBitmap变量来加载位图资源。

class CMainFrame : public CFrameWnd { protected: // 仅通过序列化创建 CMainFrame(); DECLARE_DYNCREATE(CMainFrame) CBitmap m_bmBG; };

PreCreateWindow()虚函数中,需要改变窗口的扩展样式,以便使用双缓冲技术进行绘制。

cs.dwExStyle |= WS_EX_COMPOSITED;

WS_EX_COMPOSITED是一个Windows扩展样式,它使得窗口的所有子窗口按照从下到上的顺序进行绘制,这正是所需要的。

OnCreate()处理函数中,加载位图资源。

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CFrameWnd::OnCreate(lpCreateStruct) == -1) return -1; m_bmBG.LoadBitmap(IDB_BITMAP1); return 0; }

在这里,将从位图创建一个图案画刷,并将其选择到设备上下文中,然后填充客户区域。

BOOL CMainFrame::OnEraseBkgnd(CDC* pDC) { CBrush hbr, *phbrOld; CRect rect; hbr.CreatePatternBrush(&m_bmBG); phbrOld = pDC->SelectObject(&hbr); GetClientRect(▭); pDC->FillRect(▭, &hbr); pDC->SelectObject(phbrOld); hbr.DeleteObject(); return TRUE; }

不要忘记在Mainfrm.h中添加以下行:

#define WS_EX_COMPOSITED 0x02000000L

在视图类中处理WM_CREATE消息,并在处理函数中添加以下代码:

int CTransscrollView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CScrollView::OnCreate(lpCreateStruct) == -1) return -1; CClientDC dc(this); m_ftTimes.CreatePointFont(500, "Times New Roman", &dc); CFont *pOldFont; pOldFont = dc.SelectObject(&m_ftTimes); TEXTMETRIC tm; dc.GetTextMetrics(&tm); m_nLineHt = tm.tmHeight + tm.tmExternalLeading; dc.SelectObject(pOldFont); return 0; }

创建了一个50点的Times New Roman字体,并将其选择到客户端设备上下文中。计算行高并存储它。不要忘记创建CFont m_ftTimesint m_nLineHt类变量。

只需在消息处理函数中返回TRUE

OnInitialUpdate()函数中,改变代码以创建足够大的视图以显示25行文本。

void CTransscrollView::OnInitialUpdate() { CScrollView::OnInitialUpdate(); CSize sizeTotal; // TODO: 计算此视图的总大小 sizeTotal.cx = 500; sizeTotal.cy = 25 * m_nLineHt; SetScrollSizes(MM_TEXT, sizeTotal); }

OnDraw()中,只绘制当滚动时变得可见的那些行。最初,所有行都会被绘制。

void CTransscrollView::OnDraw(CDC* pDC) { CTransscrollDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: 在此处添加原生数据的绘制代码 CFont *pOldFont; int ct; pDC->SetBkMode(TRANSPARENT); int start = GetDeviceScrollPosition().y / m_nLineHt - 1; if (start < 0) start = 0; CRect rcClient; GetClientRect(&rcClient); ct = start + rcClient.Height() / m_nLineHt + 3; if (ct > 25) ct = 25; pOldFont = pDC->SelectObject(&m_ftTimes); pDC->SetTextColor(RGB(255, 12, 146)); for (int i = start; i < ct; i++) { CString s; s.Format("I am line %d on a fixed background", i + 1); pDC->TextOut(0, i * m_nLineHt, s); } pDC->SelectObject(pOldFont); }

如所知,在滚动时,ScrollWindow()会滚动窗口内容,只需要绘制那些变得可见的行。已经计算了起始行号和将要可见的结束行号。只绘制了这些行。请注意,最初所有行都会被绘制。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485