Click here to Skip to main content
12,394,573 members (77,226 online)
Click here to Skip to main content

Stats

1.1M views
6.1K downloads
323 bookmarked
Posted

Introduction to wxWidgets

, 25 Dec 2005 GPL3
A beginner's tutorial on wxWidgets for cross platform GUI development.
/* This is a wxHyperlinkCtrl for static text boxes in wxWindows..
 * 
 * Copyright (C) 2001-2005 Angelo Mandato
 *
 * This code is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA
 */

/*//////////////// hyperlinkctrl.cpp ///////////////////
	Last modified:	06/17/2005
	Author:			Angelo Mandato
	Version:		1.3
	Web:			http://www.spaceblue.com/code/
	Email:			angelo@spaceblue.com

	Note:			View hyperlinkctrl.html for more information

	/// Contributors ///
	Name:			Mark McManus
	Email:			mmcmanus@scientificmetrics.com
	Notes:			Contributed code for the EVT_COMMAND_LINK_CLICKED event
					which is fired when AutoBrowse(false) is set and added
					DoPopup(false) to supress pop up menu to copy web link.
					Thanks Mark!

*/////////////////////////////////////////////////

#include "hyperlinkctrl.h"
#include <wx/msgdlg.h>
#include <wx/mimetype.h>
#include <wx/app.h>
#include <wx/menu.h>
#include <wx/clipbrd.h>
#include <wx/wx.h>
#include <wx/event.h>
#include <wx/tooltip.h>
#include <windows.h>

#ifdef __WIN32__
#include <wx/msw/registry.h>
#endif



DEFINE_EVENT_TYPE(wxEVT_COMMAND_LINK_CLICKED)
#ifndef HYPERLINKCTRL_COMMANDEVENT
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LINK_MCLICKED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_LINK_RCLICKED)
#endif

BEGIN_EVENT_TABLE(wxHyperlinkCtrl, wxStaticText)
	EVT_MOUSE_EVENTS( wxHyperlinkCtrl::OnMouseEvent)
	EVT_MOTION(wxHyperlinkCtrl::OnMouseEvent)
  EVT_MENU(HYPERLINKS_POPUP_COPY, wxHyperlinkCtrl::OnPopUpCopy )
END_EVENT_TABLE()

wxHyperlinkCtrl::wxHyperlinkCtrl(wxWindow *parent, wxWindowID id, const wxString &label,
               const wxPoint &pos, const wxSize &size, int style, const wxString& name, const wxString& szURL )
			   : wxStaticText(parent, id, label, pos, size, style|wxPOPUP_WINDOW, name)
{
	if( szURL.IsEmpty() )
		m_szURL = label;
	else
		m_szURL = szURL;

	// Set Tooltip
	SetToolTip( m_szURL );

	// Set default properties
	ReportErrors(); // default: true
	SetUnderlines(); // default: true, true, true
	SetColours(); // default: blue, violet, blue
	SetVisited(); // default: false
	EnableRollover();// default: false
	SetBold(); // default: false
	SetLinkCursor(); // default: wxCURSOR_HAND

//**Added By Mark McManus
    AutoBrowse(); // default true
    DoPopup(); // default true
//**Mark McManus

  OpenInSameWindow(); // default false
	// Set control properties and refresh
	UpdateLink(true);
}

// Goto the specified URL
bool wxHyperlinkCtrl::GotoURL( const wxString &szUrl, const wxString &szBrowser, const bool &bReportErrors, const bool &bSameWinIfPossible )
{
  wxLogNull logOff;

	// Use the browser specified
	if(!szBrowser.IsEmpty() )
	{
		wxString szCmd = szBrowser;
		szCmd += " ";
		szCmd += szUrl; // URLs are encoded so no need to put them in quotes

		if( wxExecute( szCmd, FALSE) != 0 )
			return true;
		else
			DisplayError("Unable to launch specified browser.", bReportErrors);

    return false;
	}

#ifdef __WIN32__

  if( bSameWinIfPossible )
  {
	  HINSTANCE result = ShellExecute(NULL, _T("open"), szUrl.c_str(), NULL,NULL, SW_SHOW);

	  if( (unsigned int)result > HINSTANCE_ERROR )
		  return true;

	  // Hack for Firefox, it returns FNF, do not know why
	  if( (unsigned int)result == SE_ERR_FNF )
		  return true;
  }

	wxRegKey Regkey( "HKEY_CLASSES_ROOT\\http\\shell\\open\\command" );
	Regkey.Open();
	wxString szOpenWith = Regkey;

	wxString szCmd = "";
	if( szOpenWith.Find("%1") != -1 )
	{
		szCmd = szOpenWith;
		szCmd.Replace( "%1", "\"" + szUrl + "\"" );
	}
	else
	{
		// first strip the \" character from the front and parse out the string...
		szOpenWith.Trim(false);

		if( szOpenWith.GetChar(0) == '\"' )
		{
			szOpenWith.Remove(0, 1);
			int nEnd = szOpenWith.Find("\"");
			if( nEnd > 0 )
				szOpenWith.Remove(nEnd);
		}
		else
		{
			int nEnd = szOpenWith.Find(" ");
			if( nEnd > 0 )
				szOpenWith.Remove(nEnd);
		}
		
		szCmd.Printf("\"%s\" \"%s\"", szOpenWith.c_str(), szUrl.c_str() );
	}

	if( wxExecute( szCmd, FALSE) != 0 )
		return true;
	else
	{
		DisplayError("Unable to launch default browser.", bReportErrors);
		return false;
	}
	
#endif
	// Untested code follows
	wxFileType *ft = wxTheMimeTypesManager->GetFileTypeFromExtension( wxT("html") );
	if ( !ft )
	{
		DisplayError("Impossible to determine the file type for extension html", bReportErrors);
		return false;
	}

	wxString cmd;
	bool bResult = ft->GetOpenCommand(&cmd, wxFileType::MessageParameters( szUrl, "" ));
	delete ft;

	if (!bResult)
	{
		DisplayError("Unable to retrieve command information", bReportErrors);
		return false;
	}

	bResult = (wxExecute( cmd, FALSE) != 0);
  if( !bResult )
    DisplayError("Unable to launch browser.", bReportErrors);

	return bResult;
}

// Capture mouse events for Cursor, Link colors and Underlines
void wxHyperlinkCtrl::OnMouseEvent(wxMouseEvent& event)
{
	if ( !event.Moving() )
  {
    if ( event.Entering() )
		{
			SetCursor( m_crHand ); //wxCursor( wxCURSOR_HAND ) );

			if( m_bEnableRollover )
			{
				SetForegroundColour(m_crLinkRolloverColor);
				wxFont fontTemp = GetFont();
				fontTemp.SetUnderlined( m_bRolloverUnderline );
				if( m_bBold )
					fontTemp.SetWeight(wxBOLD);

				SetFont( fontTemp );
				Refresh(true);
			}
		}
    else if ( event.Leaving() )
		{
			SetCursor( wxNullCursor );
			if( m_bEnableRollover )
				UpdateLink(true);
		}
    else if( !event.Moving() )
    {
      if ( event.LeftUp() ) 
      {
				if( m_bAutoBrowse )
        {
					GotoURL( m_szURL, m_szBrowserPath, m_bReportErrors, m_bSameWinIfPossible );
        }
        else
        {
#ifdef HYPERLINKCTRL_COMMANDEVENT
          wxCommandEvent eventOut(wxEVT_COMMAND_LINK_CLICKED, GetId());
          eventOut.SetEventObject(this);
          GetParent()->ProcessEvent( eventOut );
#else
          wxPoint posOnParent = GetPosition();
          posOnParent.x += event.GetPosition().x;
          posOnParent.y += event.GetPosition().y;

				  wxHyperlinkEvent eventOut(wxEVT_COMMAND_LINK_CLICKED, GetId());
				  eventOut.SetEventObject(this);
				  eventOut.SetPosition( posOnParent );
          GetParent()->ProcessEvent( eventOut );
#endif
        }

				SetVisited( true );
      }
      else if ( event.RightUp() )
      {
				//**Modified By Mark McManus, enhanced by Angelo Mandato
        if( m_bDoPopup )
        {
					wxMenu *menuPopUp = new wxMenu("", wxMENU_TEAROFF);
					menuPopUp->Append(HYPERLINKS_POPUP_COPY, "Copy");
					PopupMenu( menuPopUp, wxPoint( event.m_x, event.m_y ) );
					delete menuPopUp; // ADDED 06/30/2004 (prevents memory leaks)
        }
				else
				{
#ifndef HYPERLINKCTRL_COMMANDEVENT
          wxPoint posOnParent = GetPosition();
          posOnParent.x += event.GetPosition().x;
          posOnParent.y += event.GetPosition().y;

				  wxHyperlinkEvent eventOut(wxEVT_COMMAND_LINK_RCLICKED, GetId());
				  eventOut.SetEventObject(this);
				  eventOut.SetPosition( posOnParent );
          GetParent()->ProcessEvent( eventOut );
#endif
				}
        //**Mark McManus
      }
      else if( event.MiddleUp() )
      {
#ifndef HYPERLINKCTRL_COMMANDEVENT
        wxPoint posOnParent = GetPosition();
        posOnParent.x += event.GetPosition().x;
        posOnParent.y += event.GetPosition().y;

				wxHyperlinkEvent eventOut(wxEVT_COMMAND_LINK_MCLICKED, GetId());
				eventOut.SetEventObject(this);
				eventOut.SetPosition( posOnParent );
        GetParent()->ProcessEvent( eventOut );
#endif
      }
    }
  }

	event.Skip();
}

void wxHyperlinkCtrl::OnPopUpCopy( wxCommandEvent &event )
{
  wxUnusedVar(event);
  wxTheClipboard->UsePrimarySelection();

  if (!wxTheClipboard->Open())
    return;

  wxTextDataObject *data = new wxTextDataObject( m_szURL );
  wxTheClipboard->SetData( data );
  wxTheClipboard->Close();
}

void wxHyperlinkCtrl::UpdateLink(const bool &bRefresh)
{
	wxFont fontTemp = GetFont();

	if( m_bVisited )
	{
		SetForegroundColour( m_crVisitedColour );
		fontTemp.SetUnderlined( m_bVisitedUnderline );
	}
	else
	{
		SetForegroundColour( m_crLinkColour );
		fontTemp.SetUnderlined( m_bLinkUnderline );
	}

	if( m_bBold )
		fontTemp.SetWeight(wxBOLD);

	SetFont( fontTemp );
	Refresh( bRefresh );
}

#ifdef __WIN95__
long wxHyperlinkCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
{
	if (nMsg == WM_NCHITTEST)
		return (long)HTCLIENT;

	return wxStaticText::MSWWindowProc( nMsg, wParam, lParam );
}
#endif

void wxHyperlinkCtrl::DisplayError( const wxString &szError, const bool &bReportErrors )
{
	if( bReportErrors )
		wxMessageBox( szError, "Hyperlink Error", wxOK | wxCENTRE | wxICON_ERROR  );
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

Priyank Bolia
Software Developer (Senior)
India India
No Biography provided

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160721.1 | Last Updated 25 Dec 2005
Article Copyright 2005 by Priyank Bolia
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid