Пример #1
0
void NFOView::OnLeftButtonDown(void)
{
    POINT point = {}; 
    GetCursorPos(&point);
    ScreenToClient(_handle, &point);
    POINTS points = { point.x, point.y };
    if (IsHyperlink(points))
    {
        std::wstring hyperlink = GetHyperlinkAtPoint(points);
        ShellExecuteW(_handle, L"open", hyperlink.c_str(), NULL, NULL, SW_SHOWNORMAL);
    }
}
Пример #2
0
void NFOView::OnMouseMove(POINTS& point)
{
    DWORD selStart;
    DWORD selEnd;
    SendMessage(_handle, EM_GETSEL, (WPARAM)&selStart, (LPARAM)&selEnd);

    bool isSelecting = selEnd > selStart;

    if (IsHyperlink(point) && !isSelecting)
    {
        HCURSOR cursor = LoadCursor(NULL, IDC_HAND);
        SetCursor(cursor);
    }
    else
    {
        HCURSOR cursor = LoadCursor(NULL, IDC_IBEAM);
        SetCursor(cursor);
    }
}
Пример #3
0
int ParseLine( LPCLASSDATA lpcd, int nInBlock, TCHAR *pcText, int nLength, SYNTAX_COLOR *scColors, int *lpnBlocks, int nNumBlocks, int nLine )
{
	LPPARSER	lpp = Parser;
	LPKEYHASH	lpHash;
	LPBLOCK		lpBlock;
	COLORREF	crText = Parser->crColors[ CARR_TEXT ];
	int		nIndex = 0, nBlock = 0, nSize, i, nMatchX1 = 0, nMatchX2 = 0;
	BOOL		bContinue = FALSE, bStartOfLine = TRUE, bHasInit = FALSE;
  int nHyperLength;   // Modified by Stephan (2005-06-12)
                      // To allow unquoted paths with space like c:\program files
	
	/*
	 *	Compute match columns.
	 */
	if ( lpcd->ptBracket1.y >= 0 ) nMatchX1 = CaretOffsetLine( lpcd, lpcd->ptBracket1.y, lpcd->ptBracket1.x );
	if ( lpcd->ptBracket2.y >= 0 ) nMatchX2 = CaretOffsetLine( lpcd, lpcd->ptBracket2.y, lpcd->ptBracket2.x );

	/*
	 *	Any text to parse?
	 */
	if ( nLength == 0 )
		/*
		 *	Return the block we are in.
		 */
		 return nInBlock;

	/*
	 *	Start with a normal text
	 *	color block...
	 */
	if ( scColors )
	{
		/*
		 *	Enough text blocks?
		 */
		CHECK_BLOCKS;
		scColors[ nBlock ].nColumn   = nLength;
		scColors[ nBlock ].crColor   = crText;
		scColors[ nBlock ].crBgColor = CLR_DEFAULT;
		scColors[ nBlock ].pHash     = NULL;
		scColors[ nBlock ].wFlags    = 0;
	}

	/*
	 *	Parser active?
	 */
	if ( lpp == NULL )
	{
		/*
		 *	A single text color block.
		 */
		*lpnBlocks = 1;
		return -1;
	}

	/*
	 *	Are we in a block?
	 */
	if ( nInBlock != -1 )
	{
		/*
		 *	Get the block.
		 */
		lpBlock = ArrayGetAt( lpp->lpaBlocks, nInBlock );
		
		/*
		 *	Setup the color.
		 */
		if ( scColors )
		{
			/*
			 *	Enough text blocks?
			 */
			CHECK_BLOCKS;
			scColors[ nBlock ].nColumn   = nLength;
			scColors[ nBlock ].crColor   = lpBlock->crColor;
			scColors[ nBlock ].crBgColor = lpBlock->crBgColor;
			scColors[ nBlock ].pHash     = NULL;
			scColors[ nBlock ].wFlags    = 0;
		}

		/*
		 *	End the block with a string?
		 */
		if ( lpBlock->nEnd )
		{
			/*
			 *	See if the terminator string occures
			 *	on the line.
			 */
			LPCTSTR pszStr = ( lpp->bCaseOn ? StrStr : StrStrI )( pcText, lpBlock->pszEnd );

			/*
			 *	Terminator found?
			 */
			if( pszStr == NULL )
			{
				/*
				 *	Are we parsing hyperlinks?
				 */
				if ( Parser->bParseHyperLinks && scColors && lpnBlocks )
				{
					/*
					 *	Find all hyperlinks in the line starting
					 *	at offset 'nIndex'.
					 */
					*lpnBlocks = FindHyperlinksInBlock( lpcd, pcText, nIndex, nLength, 0, nNumBlocks, lpnBlocks, scColors ) + 1;
					scColors[ *lpnBlocks - 1 ].nColumn = nLength;
				}
				else if ( lpnBlocks )
					/*
					 *	Uses a single block.
					 */
					*lpnBlocks = 1;

				/*
				 *	Remain in the text block.
				 */
				return nInBlock;
			}
			else if ( Parser->bParseHyperLinks && scColors && lpnBlocks )
				/*
				 *	Find all hyperlinks from offset 'nIndex'
				 *	up to the block end marker.
				 */
				nBlock = FindHyperlinksInBlock( lpcd, pcText, nIndex, ( int )( pszStr - pcText ), 0, nNumBlocks, lpnBlocks, scColors );

			/*
			 *	Skip to the index at which
			 *	the terminator was found.
			 */
			nIndex = ( int )( pszStr - pcText );
		}
	}
	else
	{
		/*
		 *	If we are not yet inside a block we determine
		 *	if any of the block initiators occure in this
		 *	line and, if so, at which offset.
		 */
		for ( i = 0; ; i++ )
		{
			/*
			 *	Get the block.
			 */
			lpBlock = ArrayGetAt( lpp->lpaBlocks, i );
			
			/*
			 *	Done?
			 */
			if ( lpBlock == NULL ) 
				break;

			/*
			 *	By default this block initiator is not on
			 *	this line.
			 */
			lpBlock->bInLine = FALSE;

			/*
			 *	Will the initiator fit at all?
			 */
			if ( lpBlock->nStart && lpBlock->nStart <= nLength )
			{
				/*
				 *	Look up the block initiator on the line.
				 */
				LPCTSTR pszStr = ( lpp->bCaseOn ? StrStr : StrStrI )( pcText, lpBlock->pszStart );

				/*
				 *	Found?
				 */
				if ( pszStr != NULL )
				{
					/*
					 *	We have a block initializer.
					 */
					bHasInit = TRUE;

					/*
					 *	This block initiator is located 
					 *	on this line.
					 */
					lpBlock->bInLine = TRUE;
				}
			}
		}
	}
	
	/*
	 *	First we skip the leading blanks...
	 */
	while ( _istspace( pcText[ nIndex ] ) && nIndex <= nLength ) nIndex++;

	/*
	 *	Iterate text.
	 */
	for ( /*nIndex = 0*/; nIndex <= nLength; nIndex++ )
	{
		/*
		 *	Clear continue flag.
		 */
		bContinue = FALSE;

		/*
		 *	In a block?
		 */
		if ( nInBlock != -1 )
		{
			/*
			 *	Get block.
			 */
			lpBlock = ArrayGetAt( lpp->lpaBlocks, nInBlock );

			/*
			 *	Does the block terminate with a string?
			 */
			if ( lpBlock->nEnd )
			{
				/*
				 *	Does the terminator occure in the text?
				 */
				LPCTSTR pszStr = ( lpp->bCaseOn ? StrStr : StrStrI )( &pcText[ nIndex ], lpBlock->pszEnd );
				
				/*
				 *	No. Return the block number.
				 */
				if ( pszStr == NULL )
				{
					/*
					 *	Are we parsing hyperlinks?
					 */
					if ( Parser->bParseHyperLinks && scColors && lpnBlocks )
					{
						/*
						 *	Find the hyperlinks starting at offset 'nIndex'.
						 */
						*lpnBlocks = FindHyperlinksInBlock( lpcd, pcText, nIndex, nLength, nBlock, nNumBlocks, lpnBlocks, scColors ) + 1;
						scColors[ *lpnBlocks - 1 ].nColumn = nLength;
					}
					else if ( lpnBlocks )
						/*
						 *	Store the block number. 
						 */
						*lpnBlocks = nBlock + 1;

					return nInBlock;
				}
				else if ( Parser->bParseHyperLinks && scColors && lpnBlocks )
					/*
					 *	Find all hyperlinks from offset 'nIndex'
					 *	up to the block end marker.
					 */
					nBlock = FindHyperlinksInBlock( lpcd, pcText, nIndex, ( int )( pszStr - pcText ), nBlock, nNumBlocks, lpnBlocks, scColors );

				/*
				 *	Skip through to the index at which the
				 *	terminator was found.
				 */
				nIndex = ( int )( pszStr - pcText );
			}

			/*
			 *	Will the terminator fit?
			 */
			if ( nLength - nIndex >= lpBlock->nEnd || lpBlock->pszEnd == END_OF_LINE )
			{
				/*
				 *	End a block?
				 */
				if ( BlockEnd( lpcd, lpBlock, pcText, nIndex, nLength ))
				{
					/*
					 *	Color array present?
					 */
					if ( scColors )
					{
						/*
						 *	Enough room?
						 */
						CHECK_BLOCKS;

						/*
						 *	Yes. Terminate current color.
						 */
						scColors[ nBlock++ ].nColumn = nIndex + lpBlock->nEnd;

						/*
						 *	Start a new color.
						 */
						scColors[ nBlock ].nColumn   = nLength;
						scColors[ nBlock ].crColor   = crText;
						scColors[ nBlock ].crBgColor = CLR_DEFAULT;
						scColors[ nBlock ].pHash     = NULL;
						scColors[ nBlock ].wFlags    = 0;
					}

					/*
					 *	Skip the block terminator.
					 */
					if ( lpBlock->pszEnd != END_OF_LINE ) nIndex += lpBlock->nEnd - 1;
					else				      nIndex = nLength;

					/*
					 *	No longer in the block.
					 */
					nInBlock = -1;
					
					/*
					 *	Continue parse...
					 */
					continue;
				}
			}
		}
		
		/*
		 *	Keep looking for the terminator if
		 *	we are still inside a block.
		 */
		if ( nInBlock != -1 )
		{
			if ( scColors && nIndex >= nLength )
				scColors[ nBlock ].nColumn = nIndex;
			continue;
		}

		/*
		 *	Do we have an initiator?
		 */
		if ( bHasInit )
		{
			/*
			 *	Look up the block
			 *	initiators.
			 */	
			for ( i = 0; ; i++ )
			{
				/*
				 *	Valid block?
				 */
				if (( lpBlock = ArrayGetAt( lpp->lpaBlocks, i )) == NULL )
					break;

				/*
				 *	Block initiator in this
				 *	line?
				 */
				if ( ! lpBlock->bInLine )
					continue;

				/*
				 *	Block found?
				 */
				if ( ! BlockStart( lpcd, lpBlock, pcText, nIndex, nLength, bStartOfLine ))
					continue;

				/*
				 *	Colors present?
				 */
				if ( scColors )
				{
					/*
					 *	Enough room?
					 */
					CHECK_BLOCKS;

					/*
					 *	Yes. Terminate current color.
					 */
					scColors[ nBlock++ ].nColumn = nIndex;

					/*
					 *	Start a new color.
					 */
					scColors[ nBlock ].nColumn   = nLength;
					scColors[ nBlock ].crColor   = lpBlock->crColor;
					scColors[ nBlock ].crBgColor = lpBlock->crBgColor;
					scColors[ nBlock ].pHash     = NULL;
					scColors[ nBlock ].wFlags    = 0;
				}

				/*
				 *	Mark us as being in the block.
				 */
				nInBlock = i;

				/*
				 *	Does this block terminate at eol?
				 */
				if ( lpBlock->pszEnd == END_OF_LINE )
				{
					/*
					 *	Look at the rest of the line
					 *	for hyperlinks.
					 */
					if ( Parser->bParseHyperLinks && scColors && lpnBlocks )
						nBlock = FindHyperlinksInBlock( lpcd, pcText, nIndex, nLength, nBlock, nNumBlocks, lpnBlocks, scColors );

					/*
					 *	Skip everything except
					 *	the last terminator length 
					 *	plus the escape character.
					 */
					nIndex = max( 0, nLength - 2 );
				}
				else
					/*
					 *	Skip the block initiator.
					 */
					nIndex += lpBlock->nStart - 1;

				/*
				 *	Break the loop and
				 *	continue parsing.
				 */
				bContinue = TRUE;
				break;
			}
		}

		/*
		 *	No longer at the start
		 *	of the line...
		 */
		bStartOfLine = FALSE;

		/*
		 *	Continue?
		 */
		if ( bContinue || scColors == NULL )
			continue;

		/*
		 *	Skip spaces.
		 */
		if ( _istspace( pcText[ nIndex ] ))
		{
			/*
			 *	Make a new block.
			 */
			if ( scColors[ nBlock ].crBgColor != CLR_DEFAULT ||
			     scColors[ nBlock ].crColor   != crText ||
			     scColors[ nBlock ].wFlags )
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup new color.
				 */
				scColors[ nBlock ].crColor   = crText;
				scColors[ nBlock ].crBgColor = CLR_DEFAULT;
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;
			}
			continue;
		}
	
		if ( Parser->bParseHyperLinks && scColors )
		{
      nHyperLength = IsHyperlink( pcText, nIndex, nLength );    // Modified by Stephan (2005-06-12)

      if (nHyperLength)
      {
			  /*
			  *	Enough room?
			  */
			  CHECK_BLOCKS;

			  /*
			  *	Yes. Terminate current color.
			  */
			  scColors[ nBlock++ ].nColumn = nIndex;

			  /*
			  *	Start a new color.
			  */
			  scColors[ nBlock ].nColumn   = nLength;
			  scColors[ nBlock ].crColor   = Parser->crColors[ CARR_HYPERLINK ];
			  scColors[ nBlock ].crBgColor = Parser->crColors[ CARR_BACKGROUND_HYPERLINK ];
			  scColors[ nBlock ].pHash     = NULL;
			  scColors[ nBlock ].wFlags    = SCF_HYPERLINK;

			  /*
			  *	Is it a quoted hyperlink?
			  */
			  if ( nIndex && (pcText[ nIndex - 1 ] == _T( '"' ) || pcText[ nIndex - 1 ] == _T( '\'' )))   // Modified by Stephan (2005-05-30)
			  {
				  /*
				  *	Look up the next quote.
				  */
				  while ( nIndex < nLength && pcText[ nIndex ] != _T( '"' ) && pcText[ nIndex ] != _T( '\'' ))   // Modified by Stephan (2005-05-30)
            nIndex++;
				  if ( pcText[ nIndex ] == _T( '"' ) || pcText[ nIndex ] == _T( '\'' ))   // Modified by Stephan (2005-05-30)
            nIndex--;
			  }
			  else
			  {
				  /*
				  *	Look up the next white space.
				  */
          nIndex += nHyperLength;   // Modified by Stephan
				  while ( nIndex < nLength && ! _istspace( pcText[ nIndex ] ) &&
                  pcText[ nIndex ] != _T('(') && pcText[ nIndex ] != _T(',') &&
                  pcText[ nIndex ] != _T(';') && pcText[ nIndex ] != _T(')') &&
                  pcText[ nIndex ] != _T('\''))   // Modified by Stephan (2005-05-28)
            nIndex++;
				  if ( _istspace( pcText[ nIndex ] ) ||
              pcText[ nIndex ] == _T('(') || pcText[ nIndex ] == _T(',') ||
              pcText[ nIndex ] == _T(';') || pcText[ nIndex ] == _T(')') ||
              pcText[ nIndex ] == _T('\''))   // Modified by Stephan (2005-05-28)
            nIndex--;
			  }
			  continue;
      }
		}

		/*
		 *	Delimiter?
		 */
		if ( IsDelimiter( lpcd, pcText[ nIndex ] ))
		{
			/*
			 *	Any change in color?
			 */
			if (( scColors[ nBlock ].crColor   != Parser->crColors[ CARR_DELIMITER ] ) ||
			    ( scColors[ nBlock ].crBgColor != Parser->crColors[ CARR_BACKGROUND_DELIMITER ] ) ||
			    ( scColors[ nBlock ].wFlags ))
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup delimiter color.
				 */
				scColors[ nBlock ].crColor   = Parser->crColors[ CARR_DELIMITER ];
				scColors[ nBlock ].crBgColor = Parser->crColors[ CARR_BACKGROUND_DELIMITER ];
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;
			}

			/*
			 *	Do we have matched brackets?
			 */
			if (( nLine == lpcd->ptBracket1.y && nIndex == nMatchX1 ) ||
			    ( nLine == lpcd->ptBracket2.y && nIndex == nMatchX2 ))
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup match color.
				 */
				scColors[ nBlock ].crColor   = scColors[ nBlock - 1 ].crColor;
				scColors[ nBlock ].crBgColor = lpp->crColors[ CARR_BRACKET_MATCH ];
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;
			}

			/*
			 *	Continue parsing.
			 */
			continue;
		} 
		else
		/*
		 *	Is it a number? This check is a bit
		 *	to simple but it should not pose
		 *	any problems...
		 */
		if ( _istdigit( pcText[ nIndex ] ))
		{
			/*
			 *	Color changes?
			 */
			if (( scColors[ nBlock ].crColor   != Parser->crColors[ CARR_NUMBER ] ) ||
			    ( scColors[ nBlock ].crBgColor != Parser->crColors[ CARR_BACKGROUND_NUMBER ] ) ||
			    ( scColors[ nBlock ].wFlags ))
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate the current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup the number colors.
				 */
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].crColor   = Parser->crColors[ CARR_NUMBER ];
				scColors[ nBlock ].crBgColor = Parser->crColors[ CARR_BACKGROUND_NUMBER ];
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;
			}
		}
		else
		{
			/*
			 *	Do we have bracket matches?
			 */
			if (( nLine == lpcd->ptBracket1.y && nIndex == nMatchX1 ) ||
			    ( nLine == lpcd->ptBracket2.y && nIndex == nMatchX2 ))
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup match color.
				 */
				scColors[ nBlock ].crColor   = crText;
				scColors[ nBlock ].crBgColor = lpp->crColors[ CARR_BRACKET_MATCH ];
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;

				/*
				 *	Continue parsing.
				 */
				continue;
			}
			else if ( scColors[ nBlock ].crColor   != crText ||
				  scColors[ nBlock ].crBgColor != CLR_DEFAULT ||
				  scColors[ nBlock ].wFlags )
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;
		
				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nIndex;

				/*
				 *	Setup text color.
				 */
				scColors[ nBlock ].crColor   = crText;
				scColors[ nBlock ].crBgColor = CLR_DEFAULT;
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;
			}
		}

		/*
		 *	Count the characters up until
		 *	the next space or delimiter.
		 */
		nSize = nIndex;
		while ( nSize < nLength && ! _istspace( pcText[ nSize ] ) && ! IsDelimiter( lpcd, pcText[ nSize ] ))
		{
			/*
			 *	Do we have bracket matches?
			 */
			if (( nLine == lpcd->ptBracket1.y && nSize == nMatchX1 ) ||
			    ( nLine == lpcd->ptBracket2.y && nSize == nMatchX2 ))
			{
				/*
				 *	Enough room?
				 */
				CHECK_BLOCKS;

				/*
				 *	Terminate current color.
				 */
				scColors[ nBlock++ ].nColumn = nSize;

				/*
				 *	Setup match colors.
				 */
				scColors[ nBlock ].crColor   = crText;
				scColors[ nBlock ].crBgColor = lpp->crColors[ CARR_BRACKET_MATCH ];
				scColors[ nBlock ].nColumn   = nLength;
				scColors[ nBlock ].pHash     = NULL;
				scColors[ nBlock ].wFlags    = 0;

				/*
				 *	Continue parsing.
				 */
				break;
			}
			nSize++;
		}

		/*
		 *	Is the previous character a space/delimiter or are
		 *	we at the start of the line?
		 */
		if ( nIndex == 0 || _istspace( pcText[ nIndex - 1 ] ) || IsDelimiter( lpcd, pcText[ nIndex - 1 ] ))
		{
			/*
			 *	Is it a keyword
			 */
			if (( lpHash = IsKeyword( lpcd, &pcText[ nIndex ], nSize - nIndex )) != NULL )
			{
				/*
				 *	Color changes?
				 *	NOTE: Removed to accomodate case-fixing.
				 */
				/*if ( scColors[ nBlock ].crColor != lpHash->crColor )*/
				{
					/*
					 *	Enough room?
					 */
					CHECK_BLOCKS;

					/*
					 *	Terminate the current color.
					 */
					scColors[ nBlock++ ].nColumn = nIndex;

					/*
					 *	Setup the keyword color and the hash. We use the hash
					 *	when a text line is edited to fix the casing when 
					 *	case-fixing is turned on.
					 */
					scColors[ nBlock ].nColumn   = nLength;
					scColors[ nBlock ].crColor   = lpHash->crColor;
					scColors[ nBlock ].crBgColor = lpHash->crBkColor;
					scColors[ nBlock ].pHash     = lpHash;
					scColors[ nBlock ].wFlags    = 0;
				}
			}
		}

		/*
		 *	Are we at the end?
		 */
		if ( nSize >= nLength )
			break;

		/*
		 *	Adjust the index.
		 */
		nIndex = nSize - 1;
	}

	/*
	 *	Store the number of syntax
	 *	color block that are valid.
	 */
	if ( lpnBlocks )
		*lpnBlocks = nBlock + 1;

	return nInBlock;
}
Пример #4
0
/*
 *	Look for a hyperlink starting at position
 *	'nIndex' up to position 'nLength'.
 */
static int FindHyperlinksInBlock( LPCLASSDATA lpcd, TCHAR *pcText, int nIndex, int nLength, int nBlock, int nNumBlocks, int *lpnBlocks, SYNTAX_COLOR *scColors )
{
  int nHyperLength;   // Modified by Stephan (2005-06-12)
                      // To allow unquoted paths with space like c:\program files

	/*
	 *	Iterate all characters from 'nIndex'
	 *	up to 'nLength'.
	 */
	for ( ; nIndex < nLength; nIndex++ )
	{
		/*
		 *	Is this a hyperlink?
		 */
    nHyperLength = IsHyperlink( pcText, nIndex, nLength );
		if ( nHyperLength )
		{
			/*
			 *	Enough room in the color
			 *	blocks array?
			 */
			CHECK_BLOCKS;

			/*
			 *	Yes. Terminate current color.
			 */
			scColors[ nBlock++ ].nColumn = nIndex;

			/*
			 *	Start a new color. Actually this does not
			 *	start a new color but it sets the SCF_HYPERLINK
			 *	flag in a block with the same color.
			 *
			 *	The flag tell's the rendering engine to
			 *	render the text using the underlined font.
			 */
			scColors[ nBlock ].nColumn   = nLength;
			scColors[ nBlock ].crColor   = scColors[ nBlock - 1 ].crColor;
			scColors[ nBlock ].crBgColor = scColors[ nBlock - 1 ].crBgColor;
			scColors[ nBlock ].pHash     = NULL;
			scColors[ nBlock ].wFlags    = SCF_HYPERLINK;

			/*
			 *	Is it a quoted hyperlink?
			 */
			if ( nIndex && (pcText[ nIndex - 1 ] == _T( '"' ) || pcText[ nIndex - 1 ] == _T( '\'' )))   // Modified by Stephan (2005-05-30)
			{
				/*
				 *	Look for the next double quote or
				 *	the end of the line.
				 */
				while ( nIndex < nLength && pcText[ nIndex ] != _T( '"' ) && pcText[ nIndex ] != _T( '\'' ))   // Modified by Stephan (2005-05-30)
          nIndex++;
			}
			else if ( nIndex == 0 || ( _istspace( pcText[ nIndex - 1 ] )))
			{
				/*
				 *	Look for the next white space or
				 *	the end of the line.
				 */
        nIndex += nHyperLength;   // Modified by Stephan
				while ( nIndex < nLength && ! _istspace( pcText[ nIndex ] ) &&
                pcText[ nIndex ] != _T('(') && pcText[ nIndex ] != _T(',') &&
                pcText[ nIndex ] != _T(';') && pcText[ nIndex ] != _T(')') &&
				pcText[ nIndex ] != _T('\'') && pcText[ nIndex ] != _T(':'))   // Modified by Stephan (2005-05-28)
          nIndex++;
			}

			/*
			 *	Terminate this block.
			 */
			CHECK_BLOCKS;

			/*
			 *	Yes. Terminate current color.
			 */
			scColors[ nBlock++ ].nColumn = nIndex;

			/*
			 *	Erase the SCF_HYPERLINK flag which tells 
			 *	the rendering engine to switch back to 
			 *	the normal font.
			 */
			scColors[ nBlock ].nColumn   = nLength;
			scColors[ nBlock ].crColor   = scColors[ nBlock - 1 ].crColor;
			scColors[ nBlock ].crBgColor = scColors[ nBlock - 1 ].crBgColor;
			scColors[ nBlock ].pHash     = NULL;
			scColors[ nBlock ].wFlags    = 0;
		}
	}
	return nBlock;
}