Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / MFC

CHyperLink: A Simple MFC HyperLink Button Class with Any Size 32bpp Icons Support

Rate me:
Please Sign up or sign in to vote.
4.65/5 (48 votes)
19 Jul 2018CPOL5 min read 208K   5.3K   86   36
A class which encapsulates a hyperlink control for web page redirection or normal button usage

HyperLink Demo

Introduction

I know that there are already a lot of classes written for implementing a hyperlink but none satisfied me so I decided to write one on my own. It's only a simple button class usable both for web page redirection or as a normal button with parent notifications. It inherits from CStatic. It's possible to specify a quadruple icon set (when the link is in normal, hovered, clicked or disabled state) and to put these icons on the left, on the right or both sides. It's possible to change the font face, size and weight as you can see in the image above. You can now also change background color, put a border, using multiline text and chose to automatically generate the disabled state icon. To see completely what it can do, download the demo executable.

Using the Code

The class is very simple to use. Anyway, I'll explain the class' public methods and their syntax.

First and most important are: SetLinkText and SetLinkUrl which let you respectively set the link text and the link URL (the last one will be used as tooltip text too). You can also set e-mail address links using the syntax "mailto:me@mail.com" as you surely already know.

C++
TCHAR* GetLinkText();
void SetLinkText(TCHAR* lpText);

TCHAR* GetLinkUrl();
void SetLinkUrl(TCHAR* lpUrl);

I think these don't need explanations.

Now come methods used to specify optional behaviour of the hyperlink.

C++
void LockInPosition(BOOL bLockInPosition = FALSE);

BOOL IsMultiline() { return m_bMultiline; }
void SetMultiline(BOOL bMultiline);

void IsLink(BOOL bIsLink = TRUE);

void UnderlineAlways(BOOL bUnderlineAlways = FALSE);

COLORREF GetUpColor() { return m_crLinkUp; }
COLORREF GetHoverColor() { return m_crLinkHover; }
COLORREF GetDownColor() { return m_crLinkDown; }
COLORREF GetBackgroundColor() { return m_crBackGround; }
void SetColors(COLORREF crLinkUp, COLORREF crLinkHover, COLORREF crLinkDown, 
    COLORREF crBackGround = ::GetSysColor(COLOR_BTNFACE));
void SetBackgroundColor(COLORREF crBackGround = ::GetSysColor(COLOR_BTNFACE));

COLORREF GetBorderColor() { return m_crBorder; }
void SetBorderColor(COLORREF crBorder = RGB(0,0,0));
int GetBorderSize() { return m_nBorderSize; }
void SetBorderSize(int nSize);
int GetBorderStyle() { return m_nBorderStyle; }
void SetBorderStyle(int nStyle);

UINT GetShowIconsOpt() { return m_uShowIcon; }
void SetIcons(HICON hIconUp, HICON hIconHover, HICON hIconDown, 
    UINT uShowIcons, HICON hIconDisabled = NULL);
void SetIconUp(int nIconUp, int dx = 0, int dy = 0);
void SetIconHover(int nIconHover, int dx = 0, int dy = 0);
void SetIconDown(int nIconDown, int dx = 0, int dy = 0);
void SetIconDisabled(int nIconDisabled, int dx = 0, int dy = 0);
void SetShowIcons(UINT uShowIcons);

BOOL GetAutoGenerateDisabled() { return m_bAutoGenerateDisabled; }
void SetAutoGenerateDisabled(BOOL bAutoGenerate);

BOOL SetFont(TCHAR* lpFaceName = "Arial", int nSize = 14, 
    int nWeight = FW_NORMAL, BOOL bItalic = FALSE);
BOOL SetFont(const LPLOGFONT lpFont);

void Disable(BOOL bDisable = FALSE);

CToolTipCtrl* GetTooltip();
void SetTooltip(CToolTipCtrl* pToolTip);
  • LockInPosition is called to specify if the link has to be drawn leaving space for icons although icons are not visible. Try the demo application to understand how it works.
  • UnderlineAlways specifies if the hyperlink will keep the underline style always, even when the link is not hovered.
  • IsLink says if the hyperlink is a link referring to a web page and if the URL string is a web URL or if it's only a tooltip text and the button is a regular dialog button. A point to mention about this method: if you call IsLink(FALSE) and hence the link is considered a regular button, the class will automatically notify the clicks to the parent; instead if the hyperlink is used as a link, the notification will be send only if the static style SS_NOTIFY is set for the control.
  • SetColors sets the hyperlink colors. The parameters are simple to understand. The last parameter specifies the background color. I've added it to solve the problems of the transparent background simulation if you use dialogs in which the background color is different from the default COLOR_BTNFACE. I added specific methods for the background color.
  • SetBorderColor, SetBorderSize, SetBorderStyle are all meant to change border behaviour. To disable border, simply call SetBorderSize(0).
  • GetShowIconsOpt simply retrieves the UINT flag specifying how to show icons. This is useful if you need to add a visualization to others already existing instead of setting all once (for example: SetIcons(NULL,NULL,NULL,m_HyperLink.GetGetShowIconsOpt() | 0x0005)).
  • SetIcons sets the hyperlink icons to show on the left or on the right or on both sides of the link for all the different states: normal, hovered, clicked, disabled. Icons can be of any size and/or format. First of all, if you already set an icon, you can pass NULL for that icon to leave the icon unchanged. Now some explanation about the last parameter, that is uShowIcons. This is a WORD flag. The declaration below can help to understand what values it accepts:
    C++
    enum {
        SI_ICONUP_ON    = 0x0001, //Show icon when mouse Up (normal)
        SI_ICONUP_LEFT  = 0x0002, //Show icon when mouse up on the left
        SI_ICONUP_RIGHT = 0x0004, //Show icon when mouse up on the right
        //
        SI_ICONHOVER_ON    = 0x0010, //Show icon when mouse hover
        SI_ICONHOVER_LEFT  = 0x0020, //Show icon when mouse hover on the left
        SI_ICONHOVER_RIGHT = 0x0040, //Show icon when mouse hover on the right
        //
        SI_ICONDOWN_ON    = 0x0100, //Show icon when mouse down
        SI_ICONDOWN_LEFT  = 0x0200, //Show icon when mouse down on the left
        SI_ICONDOWN_RIGHT = 0x0400 //Show icon when mouse down on the right
        //
        SI_ICONDISABLED_ON    = 0x1000, //Show icon when hyperlink is disabled
        SI_ICONDISABLED_LEFT  = 0x2000, //Show icon when hyperlink is 
                                        //disabled on the left
        SI_ICONDISABLED_RIGHT = 0x4000  //Show icon when hyperlink is 
                                        //disabled on the right
    }; 

    Bits 0-7 represent the icon shown for the normal hyperlink state, bits 8-15 instead represent the icon shown for the hovered hyperlink state, 16-23 for the clicked hyperlink state and last 8 bits are for disabled state. Each 8 bits flag says how the icon is shown and whether it is shown on the left/right in that state. So a value of 3 shows only the left icon, while a value of 5 shows only the right icon, and a value of 7 shows both on the left and the right. So if you want to show icons on all states and both on left and right, simply call SetIcons with 0x7777 as the last parameter. It's simpler to do than to explain. For example, if you want a hyperlink with an icon on the left which disappears on the left and appears on the right when the hyperlink is hovered, and you want to show both when you click on the hyperlink and when it's disabled, you just have to call SetIcons with the flag 0x7753. Something like this:

    C#
    SetIcons(theApp.LoadIcon(IDI_ICON1), 
         theApp.LoadIcon(IDI_ICON1),theApp.LoadIcon(IDI_ICON1),0x0753);

    In addition, I added some specific functions to load icons from resource ID. Those are SetIconUp, SetIconHover, SetIconDown, SetIconDisabled. Plus, I put a method to set only how icons must be shown (that is, the uShowIcons flag).

  • GetAutoGenerateDisabled simply set whether to generate automatically or not the disabled state icon.
  • SetFont doesn't need explanations I think. The method requires the font face, font size, font weight and a BOOL indicating if the font will be italicised or an overloaded version which requires a LPLOGFONT.
  • Disable simply disables the hyperlink.
  • GetTooltip and SetTooltip respectively gets or sets a custom tooltip to use with the control.

Notes

I found those icons on my hard drive but sincerely don't know where do they come from, so if they're copyrighted material and the owner of the rights doesn't want to let me use them, just let me know and I will replace those with something else.

Conclusions

So, that's all, I think.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Synved Ltd.
Ireland Ireland

Comments and Discussions

 
SuggestionAutomatically generating disabled icon Pin
Damir Valiulin28-Mar-12 17:38
Damir Valiulin28-Mar-12 17:38 
GeneralConflict with other controls Pin
Pixbyte14-Oct-10 17:07
Pixbyte14-Oct-10 17:07 
GeneralGreat work - but text justification problem Pin
Johnnyfartpants14-Dec-08 8:02
Johnnyfartpants14-Dec-08 8:02 
This is a simple but very useful control. My only criticism is that the link text seems to be always left-justified. It would be nice if the text alignment could conform to whatever is set for the control's style (left, centre or right).

One other (minor) niggle is that CHyperLink::OpenUrl() doesn't fail (or even notice) if there's no internet connection available. I changed it to this - which displays a warning dialog if there's no internet connection:-

#include "wininet.h"

int CHyperLink::OpenUrl()
{
	if ((m_lpLinkUrl != NULL) && (m_bIsLink) && (_tcslen(m_lpLinkUrl)))
	{
		if (::InternetCheckConnection(m_lpLinkUrl, FLAG_ICC_FORCE_CONNECTION, 0))
			HINSTANCE result = ShellExecute(NULL, _T("open"), m_lpLinkUrl, NULL, NULL, SW_SHOWDEFAULT);
		else 
		{
			CWnd* pParent = GetParent();

			if (pParent)
				::MessageBox(pParent->GetSafeHwnd(), "No internet connection was found    ", "Network connection error", (MB_OK | MB_ICONSTOP));
			else
				::MessageBox(NULL, "No internet connection was found    ", "Network connection error", (MB_OK | MB_ICONSTOP));
		}
	}
	else
		return -1;

	return 0;
}

You then only need to link to wininet.lib. Note that wininet.h should really be in angle brackets but they won't display properly on this site (they get interpreted as a tag).
GeneralSmall bugs... Pin
James R. Twine17-Sep-07 3:38
James R. Twine17-Sep-07 3:38 
GeneralRe: Small bugs... Pin
Elia Sarti17-Sep-07 11:10
Elia Sarti17-Sep-07 11:10 
GeneralThe text changed Pin
olncy4-Aug-07 1:33
olncy4-Aug-07 1:33 
GeneralRe: The text changed Pin
Elia Sarti5-Aug-07 0:03
Elia Sarti5-Aug-07 0:03 
NewsHello Pin
DgMv4-Jan-07 10:10
DgMv4-Jan-07 10:10 
GeneralRe: Hello Pin
Elia Sarti4-Jan-07 11:28
Elia Sarti4-Jan-07 11:28 
GeneralRe: Hello Pin
DgMv5-Jan-07 8:51
DgMv5-Jan-07 8:51 
QuestionMulti Line isnt supported??? Pin
Shurid14-Nov-06 22:15
Shurid14-Nov-06 22:15 
AnswerRe: Multi Line isnt supported??? Pin
Elia Sarti15-Nov-06 4:53
Elia Sarti15-Nov-06 4:53 
GeneralRe: Multi Line isnt supported??? Pin
Shurid16-Nov-06 17:15
Shurid16-Nov-06 17:15 
GeneralRe: Multi Line isnt supported??? Pin
Elia Sarti17-Nov-06 5:03
Elia Sarti17-Nov-06 5:03 
GeneralRe: Multi Line isnt supported??? Pin
Shurid19-Nov-06 17:47
Shurid19-Nov-06 17:47 
AnswerRe: Multi Line isnt supported??? Pin
Elia Sarti3-May-07 5:19
Elia Sarti3-May-07 5:19 
Generalproject file Pin
jamesw200318-Nov-05 9:02
jamesw200318-Nov-05 9:02 
GeneralRe: project file Pin
Elia Sarti18-Nov-05 15:16
Elia Sarti18-Nov-05 15:16 
GeneralRe: project file Pin
kelotrbrbr5-Aug-06 10:17
kelotrbrbr5-Aug-06 10:17 
GeneralRe: project file Pin
kelotrbrbr5-Aug-06 10:42
kelotrbrbr5-Aug-06 10:42 
QuestionWhy TCHAR* ? Pin
HobbitCoder5-Nov-05 8:31
HobbitCoder5-Nov-05 8:31 
AnswerRe: Why TCHAR* ? Pin
Elia Sarti5-Nov-05 16:57
Elia Sarti5-Nov-05 16:57 
GeneralRe: Why TCHAR* ? Pin
HobbitCoder6-Nov-05 3:42
HobbitCoder6-Nov-05 3:42 
GeneralRe: Why TCHAR* ? Pin
Elia Sarti6-Nov-05 4:37
Elia Sarti6-Nov-05 4:37 
GeneralRe: Why TCHAR* ? Pin
HobbitCoder6-Nov-05 5:04
HobbitCoder6-Nov-05 5:04 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.