文字横向滚动的关键在于在计时器里递增文字位置的偏移并重绘,还要处理边界和循环绘制的效果,下面是一个基于CStatic的文字横向滚动的例子
void CMyStatic::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CString strText;
GetWindowText(strText);
if (strText == m_strText)
{
CDC* pDC = GetDC();
pDC->SelectObject(&m_font);
CSize size = pDC->GetTextExtent(strText);
ReleaseDC(pDC);
CRect rect;
GetClientRect(rect);
int iWidth = rect.Width();
if (size.cx > iWidth)
{
Invalidate();
UpdateWindow();
m_iExtend += 2;
if (m_iExtend > size.cx)
m_iExtend -= size.cx + 8;
}
}
else
{
m_iExtend = 0;
m_strText = strText;
}
CStatic::OnTimer(nIDEvent);
}
void CMyStatic::OnPaint()
{
// TODO: Add your message handler code here
CPaintDC dc(this);
CRect rc;
GetClientRect(rc);
CString strText;
GetWindowText(strText);
CDC memDC;
memDC.CreateCompatibleDC(&dc);
CBitmap bmp;
bmp.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
memDC.SelectObject(&bmp);
memDC.SelectObject(&m_font);
dc.SelectObject(&m_font);
memDC.FillSolidRect(rc, RGB(255, 255, 255);
CSize size = memDC.GetTextExtent(strText);
if (size.cx > rc.Width())
{
if (size.cx - m_iExtend > 0)
memDC.TextOut(rc.left - m_iExtend, rc.top + (rc.Height() - size.cy)/2, strText);
if (rc.left - m_iExtend + 8 +size.cx < rc.right)
memDC.TextOut(rc.left - m_iExtend +
8+size.cx , rc.top + (rc.Height() - size.cy)/2, strText);
}
else
memDC.TextOut(rc.left, rc.top + (rc.Height() - size.cy)/2, strText);
dc.BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memDC, rc.left, rc.top, SRCCOPY);
memDC.DeleteDC();
bmp.DeleteObject();
}
. In MainFrm.h, change the type of status bar as:
CMyStatusBar m_wndStatusBar;
3. Also change the indicator array in MainFrm.cpp as:
static UINT indicators[] = { ID_SEPARATOR, IDS_SCROLL_PANE, //scrolling text
ID_INDICATOR_CAPS, ID_INDICATOR_NUM, ID_INDICATOR_SCRL, };
4. Add IDS_SCROLL_PANE in the string table with few blanks.
The size of pane will depend on this blank string. There are other painfull ways of sizing a pane too.
5. Add following member to CMyStatusBar: Cstring m_strScrollText;
6. Add OnTimer() to the CMyStatusBar:
void CMyStatusBar::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
if (m_strScrollText.IsEmpty())
{
KillTimer(1);
SetPaneText(CommandToIndex(IDS_SCROLL_PANE), “”);
return;
}
static UINT str_idx = 0; //offset into string
//if end of string, return to top
if (str_idx >= (UINT) (m_strScrollText.GetLength() / 2) – 1)
{
str_idx = 0;
}
//display string
SetPaneText(CommandToIndex(IDS_SCROLL_PANE), ((LPCSTR) m_strScrollText)+str_idx);
//scroll one character
str_idx = str_idx + 1; CStatusBar::OnTimer(nIDEvent); }
7. Destroy timer:
void CMyStatusBar::OnDestroy()
{
CStatusBar::OnDestroy();
// TODO: Add your message handler code here
KillTimer(1);
}
8. Add a method to start scrolling text. This method must be called after the mainframe (and the status bar)
has been constructed to display scrolling text. Perhaps from the CWinApp::InitInstance().
void CMyStatusBar::StartDisplay(void)
{
//set text for scrolling
m_strScrollText = ” Hello! World. “
//to make it circular scroll
m_strScrollText += m_strScrollText;
KillTimer(1);
VERIFY(SetTimer(1, 200, NULL) != 0); //timer
}
|