Visual C++


Banner vertical per desplaçament del text

Aquest article ha estat possible gràcies a la col·laboració de Pere Llaveria.

Amb unes petites modificacions en els fonts de l'article Banner horitzontal per desplaçament del text podem aconseguir un banner que desplaci el text verticalment.

Per a fer això només cal modificar algunes línies de la funció OnPaint, la resta de línies romanen sense canvis.


void CVScrollingBannerStc::OnPaint() 
{
   RECT     rect;
   CWnd     *pWndParent = NULL;
   CPaintDC dc(this);
   CDC      memDC;
   CBitmap  bitmap, *oldBitmap;
   SIZE     size;

   // seleccionem el color de fons per defecte del control estàtic
   CBrush bBrush(::GetSysColor(COLOR_3DFACE));
   CBrush* pOldBrush;

   // obtenim el pare del control, generalment un diàleg
   pWndParent = GetParent();
   if (pWndParent == NULL)
      return;

   // creem un context de dispositiu en memòria compatible
   // amb el del control, en el qual es dibuixarà el text
   if (!memDC.CreateCompatibleDC(&dc)) 
   {
      TRACE0("Error en crear DC en memòria"); 
      return;
   }

   // inicialitzem el bitmap que tindrà la imatge final a copiar en el control
   if (!bitmap.CreateCompatibleBitmap(&dc, m_rect.right, m_rect.bottom)) 
   {
      TRACE0("Error en inicialitzar bitmap en memòria"); 
      return;
   }

   // seleccionem la font per defecte de la finestra pare
   memDC.SelectObject(pWndParent->GetFont());

   // seleccionem el bitmap on pintarem el text
   oldBitmap = memDC.SelectObject(&bitmap);

   // seleccionem el pinzell per esborrar el contingut del rectangle
   pOldBrush = memDC.SelectObject(&bBrush);

   // omplim el rectangle amb el color seleccionat
   memDC.FillRect(&m_rect, &bBrush);

   // seleccionem el rectangle on DrawText() començarà a pintar el text,
   // això és el que genera l'efecte de desplaçament del text, és a dir,
   // indiquem a DrawText() que pinti el text un píxel cap a dalt cada vegada
   rect = m_rect;
   rect.top = rect.bottom - m_nClip;

   // obtenim la mida de la cadena per saber on ha de començar la següent
   GetTextExtentPoint32(memDC.GetSafeHdc(), m_sTexto, m_sTexto.GetLength(), &size);

   // pintem el text en memòria
   memDC.SetBkMode(TRANSPARENT);

   // pintem cada una de les cadenes
   nCadenas = m_sStrings.GetSize();
   for (int i = 0; i < nCadenas; i++)
   {
      // dibuixem cada cadena
      m_sTexto = m_sStrings.GetAt(i);
      memDC.DrawText(m_sTexto, &rect, DT_CENTER | DT_NOPREFIX | DT_SINGLELINE);

      // indiquem on s'ha de dibuixar la següent cadena
      rect.top += size.cy;
   }

   // copiem el contingut del DC en memòria al DC del control
   dc.BitBlt(0, 0, m_rect.right, m_rect.bottom, &memDC, 0, 0, SRCCOPY);

   // hem de calcular que m_nClip sigui major o igual que la mida del
   // rectangle del control (altura) més la mida del rectangle del total
   // de les cadenes, perquè acabin de passar del tot
   if (m_nClip >= m_rect.bottom + size.cy * nCadenas)
      m_nClip = 0;

   // deixem les coses com estaven i eliminem els objectes
   memDC.SelectObject(oldBitmap);
   memDC.SelectObject(&pOldBrush);
   memDC.DeleteDC();
   bitmap.DeleteObject();
   bBrush.DeleteObject();
}

Podem incloure línies en blanc amb AddString perquè actuïn com a separadores entre cadenes de text, això augmenta l'efecte del banner.


BOOL CVScrollingBannerDlg::OnInitDialog() 
{
   CDialog::OnInitDialog();
   
   m_ctrlBanner.AddString(CString("Primer text"));
   m_ctrlBanner.AddString(CString("Continua una cadena buida com a separador"));
   m_ctrlBanner.AddString(CString(""));
   m_ctrlBanner.AddString(CString("Tercer text"));
   m_ctrlBanner.AddString(CString("Cuart text"));
   m_ctrlBanner.AddString(CString("Continua una altra cadena buida com a separador"));
   m_ctrlBanner.AddString(CString(""));
   m_ctrlBanner.AddString(CString("Setè text"));
   m_ctrlBanner.AddString(CString("Vuitè text"));
   
   return TRUE;
}

Fonts ... vscrolling_banner_sources.zip 19 Kb
Vegi's també ... Banner horitzontal per rotació de caràcters
Banner horitzontal per desplaçament del text