Click here to Skip to main content
Click here to Skip to main content

Hyperlink Scroller

By , 21 Nov 2002
 

Sample Image

Introduction

This article is about a subclassed static control which you can use to scroll hyperlinks from right to left. I once used it to scroll news headlines as hyperlinks in an application.

Using the code

The source for this subclassed control is in ScrollLink.h and ScrollLink.cpp. In it, you will find 2 classes, CScrollLink and CTextFrame. The latter is used by CScrollLink for each hyperlink to scroll, so you don't really need to know much about it to use this hyperlink scroller. To use it, you need to use a Static control and subclassed with CScrollLink. Note that you need to check the 'Notify' property of the static control.

The code listed below will show you how to 

  1. Change the scrolling text colors, fonts, scroll speed, rate, etc.
  2. Change the font attributes such as bold hyperlinks, underline them when hovered.
  3. Add hyperlink name and its url for scrolling.
  4. Remove all the hyperlinks that were added.
  5. Begin scrolling all the added hyperlinks.

1) Change the scrolling text colors, fonts, scroll speed, rate, etc.

#define CLR_RED RGB(255, 0, 0) // Red color
#define CLR_BLUE RGB(0, 0, 255) // Blue color
#define CLR_BLACK RGB(0, 0, 0) // Black color
#define CLR_GRAY RGB(178, 178, 178) // Gray color
#define CLR_WHITE RGB(255, 255, 255) // White color

#define SCROLLRATE 1 // Frequency of timer
#define SCROLLSPEED 1 // Amount of pixels to scroll
#define SCROLLALLOWANCE 50 // Amount of pixels between 2 scroll text
CScrollLink::CScrollLink()
{
    // Empty array
    m_oTextFrames.RemoveAll();
    m_iTextFramesScrolling.RemoveAll();

    // Scroll rate is the value used in SetTimer(), which scrolls your hyperlinks to
    // the left by x pixels, where x is the scroll speed value. Scroll allowance is the
    // gap in pixels between 2 scrolling hyperlinks
    m_uiScrollRate = SCROLLRATE;
    m_uiScrollSpeed = SCROLLSPEED;
    m_uiScrollAllowance = SCROLLALLOWANCE;

    // The text of the hyperlink will be black if there is no url for it. If not, it will
    // be blue. The color of the hyperlink is set to red when mouse it is hovered and the
    // background color of the control is set to the same as the button color.
    m_clrText = CLR_BLACK;
    m_clrHover = CLR_RED;
    m_clrBackground = GetSysColor(COLOR_BTNFACE);

    // Set flag
    m_bOnHover = FALSE;
}

2) Change the font attributes such as bold hyperlinks, underline them when hovered.

This hyperlink scroller uses the same font as its parent. You can change its font attributes for the scrolling text as well as when it is hovered in CreateTextFonts as show below.

void CScrollLink::CreateTextFonts(void)
{
    // Get window font
    CFont* pFont = GetFont();
    
    // Create LOGFONT structure
    LOGFONT lfLogFont;

    // Get LOGFONT structure of current font
    pFont->GetLogFont(&lfLogFont);

    // Set font to be bold
    lfLogFont.lfWeight = FW_BOLD;

    // Create normal font that is bold (when not hovered)
    m_oNormalFont.CreateFontIndirect(&lfLogFont);
    
    // Set underline attribute
    lfLogFont.lfUnderline = TRUE;

    // Create current font with underline attribute (when hovered)
    m_oUnderlinedFont.CreateFontIndirect(&lfLogFont);
}

3) Add hyperlink name and its url for scrolling.

Now to add your hyperlink to the scroller, you should use AddScrollText as shown below. Note that you can pass an empty url string and the scrolled text will appear as a normal text instead of a hyperlink.

BOOL CScrollLink::AddScrollText(CString strText /* Text to scroll */, 
                                CString strURL /* URL behind scrolled text */)
{
    // Allocate memory for CTextFrame object
    CTextFrame* pTextFrame = new CTextFrame(strText, strURL);

    // Check if memory allocation successful
    if (pTextFrame != NULL)
    {
        // Store object into array
        m_oTextFrames.Add(pTextFrame);

        // Assign null pointer value
        pTextFrame = NULL;

        // Indicate success
        return TRUE;
    }

    // Indicate failure
    return FALSE;
}

4) Remove all the hyperlinks that were added.

And to clear all the hyperlinks that you have added, call RemoveAllScrollText.

BOOL CScrollLink::RemoveAllScrollText(void)
{
    // Remove all scroll text
    DeleteTextFrames();

    // Repaint
    Invalidate();

    // Indicate success
    return TRUE;
}

5) Begin scrolling all the added hyperlinks.

After you have added your hyperlinks details, call StartScrolling to begin scrolling them.

/* bRestart = Flag to indicate whether to restart scrolling */
BOOL CScrollLink::StartScrolling(BOOL bRestart)
{
    // Make sure there are text to scroll
    if (m_oTextFrames.GetSize() > 0)
    {
        // Stop timer if any
        KillTimer(ID_SCROLLTIMER);

        // Check if scrolling is to be restarted
        if (bRestart == TRUE)
        {
            // Empty array of indexes of current scrolling text frames
            m_iTextFramesScrolling.RemoveAll();

            // Store index of the first text frame to be scrolling
            m_iTextFramesScrolling.Add(0);

            // Initialize size of text and its starting position
            PrepareTextFramesForScrolling();

            // Clear any previous scroll text
            Invalidate();
        }

        // Scrolling is to be continued
        else
        {}

        // Start timer
        SetTimer(ID_SCROLLTIMER, SCROLLRATE, NULL);

        // Indicate success
        return TRUE;
    }

    // Indicate failure
    return FALSE;
}

Points of Interest

Well, I need to apologize if my code comments appear vague. I am still improving on that. Also, I know that some of my code could be further improved, so I will be open to your comments, suggestions and criticisms.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Weiye Chen
Other
Singapore Singapore
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMutiThread problemsmembershirley_cl15 Jul '09 - 17:00 
i apply this cotrol into my mutiThread App.however ,i come across the following problems even if i use Criticalsection to lock the scroller control in the thread Proc.
 
-----------------------------------------------------------------------
AfxAssertFailedLine(const char * 0x0044631c _szAfxTempl, int 254) line 39 + 20 bytes
CArray<int,int>::GetAt(int 1) line 254 + 61 bytes
CScrollLink::DrawScrollingText(CDC * 0x00126d68 {hDC=0x9901104a attrib=0x9901104a}) line 268 + 22 bytes
-----------------------------------------------------------------
 
can u help with work it out?
GeneralLittle question about using this control in ATL projectmembermfranco_neto5 Oct '06 - 5:46 
Hi,
 
I am by far no expert in MFC or ATL, even C++. But I have, with some very hard work, managed to adapt one tutorial of creating a toolbar, in ATL, to the application I needed. Now, reading this amazing tutorial by Weiye Chen, I can see that it is in MFC. So I am confused if it is possible to use it directly with an ATL project, or I would need to adapt the code...D'Oh! | :doh:
 
For example, the message maps in ATL are diferente than MFC, as well as the list of parameter passade by OnPaint, etc...
 
Can anyone point me in the right direction? What do I need to adapt?
 
Thanks a lot for everyone that writes to CP. You have no idea how you guys help us beginners!!!Big Grin | :-D
Questiona little suggestion or improvement?memberice_lei18 Sep '06 - 22:55 
hello, this is really a nice work, thank you very much!Smile | :)
but here i have a little suggestion(or may be improvement)for this work.
that is, sometimes when change the size of the control dynamically, the interval between the new added text and the prior, also change to be larger or smaller than the macro SCROLLALLOWANCE we set.so i modify some parts of your code in the method AddOnNewScrollingText() as belows:
void CScrollLink::AddOnNewScrollingText(void)
{
...
// Set starting position in pixels for scrolling
// pTextFrame->m_iXOffSets.Add(m_oTextArea.right); <-this is your orginal code
int lEnd = pTextFrame->m_iXOffSets.GetAt(pTextFrame->m_iXOffSets.GetSize() - 1) + pTextFrame->m_szTextSize.cx + SCROLLALLOWANCE; <- added by me
pTextFrame->m_iXOffSets.Add(lEnd); <- added by me

 
// Add new text frame index into array
m_iTextFramesScrolling.Add(iIndex);
...
}
now it can be works rightly when we change size of the control,the interval remain equal to the SCROLLALLOWANCE.
is this right?any ideas?Smile | :)
 
china, ice_lei.
QuestionHow to display not flikingmemberpyoon17 Apr '06 - 3:31 
Hello,
Thank you for your good.
I have a question.
When the text is scrolling, the text data is redrawing.
By the way, the scrolling text is displayed like flicking text.
How can I display more smoothly ?
 
Thanks.
QuestionHow to change the SCROLLRATE and SCROLLSPEEDmemberchinakknd26 Mar '06 - 21:15 
I change the SETTIMER(,x,)but when x=20 ,the speed is slow,x=15 or 10 ,the rate dosn't change.why?
how to change the scrollrate
您是中国人吗?我发现它在滚动的时候有些闪,如何解决这个问题呢?就是降低rate?另外默认的滚动速度太快了,怎么慢一些呢?
AnswerRe: How to change the SCROLLRATE and SCROLLSPEEDmemberWeiye Chen27 Mar '06 - 1:57 
The x value is actually in milliseconds. It determines the intervale between each timer callback. So you can't really see a difference with values of 10 - 20.
 
Weiye Chen
Life is hard, yet we are made of flesh...
QuestionCan I creat the control with 'creat' methodmemberchgrbr31 Oct '05 - 20:37 
i want to creat the control in my program , not only to draw it on the dialog window. Can i use the 'creat' method? i have tried but failed .what can i do ?thank u
AnswerRe: Can I creat the control with 'creat' methodmemberWeiye Chen8 Nov '05 - 21:18 
First thing you need to amend is to put this extra line in CScrollLink::CreateTextFonts(...) function as shown below:
void CScrollLink::CreateTextFonts(void)
{
   // Get window font
   CFont* pFont = GetFont();
   
   // Include this line
   if(pFont == NULL)
      return; 
 
   // Create LOGFONT structure
   LOGFONT lfLogFont;
   .
   .
}
When you call Create(...), be sure to use the SS_NOTIFY flag. However, i still couldn't figure out how to set the font as according to the parent window with this method of creation.

 
Weiye Chen
Life is hard, yet we are made of flesh...
Generaltransparent text and haltssusssir kaber28 Jul '05 - 13:25 
Hi! I was wondering, has anyone patched this to have support for transparent texts as well as halts and vertical scroll drops.
Ex. Text scrolls, get to approx middle of the scroll control, and delays for a certain amount of time ?
 
Thanks.

Questionright to left scroll ?memberwaelahmed5 Sep '04 - 16:44 
right to left scroll ?
 
regards
wael

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 22 Nov 2002
Article Copyright 2002 by Weiye Chen
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid