Exemplo n.º 1
0
BOOL CSkinItemEdit::OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* lpResult)
{
	*lpResult = CSkinItem::DefWndProc(uMsg, wParam, lParam);

	CWnd* pWnd = CWnd::FromHandle(m_hWnd);
	CDC* pDC = NULL;
	if (m_bSystemEdit)
		pDC = pWnd->GetDC();
	else 
		pDC = pWnd->GetWindowDC();

	DrawFrame(pDC);

	pWnd->ReleaseDC(pDC);

	return TRUE;
}
int ControlLayoutHelper::CalculateHeaderTextHeight(CWnd& calculateWnd)
{
	if(calculateWnd.GetSafeHwnd() == NULL)
		return 0;
	
	CDC* pDC = calculateWnd.GetWindowDC();

	CRect groupRect(0,0,0,0);

	if(NULL != pDC)
	{
		CString wndText;
		calculateWnd.GetWindowText(wndText);

		pDC->DrawText(wndText, &groupRect, DT_CALCRECT);
	}

	return groupRect.Height();
}
Exemplo n.º 3
0
void ZoomBox_NcPaint(HWND hwnd, HRGN hrgn)
/************************************************************************/
{
	CRect  r, rTitle, rMenu, rCaption, rCookie;
	TCHAR Caption[80];


	GetWindowRect(hwnd,&r);
	r.OffsetRect(-r.left, -r.top);
	CalcTitleRect(hwnd,TRUE, rTitle);
	CalcSysMenuRect(hwnd,TRUE, rMenu);
	rCookie.SetRect(
		rMenu.left + SYS_COOKIE_OFFSET + 1,
		rMenu.top  + SYS_COOKIE_OFFSET + 1,
		rMenu.left + SYS_COOKIE_OFFSET + SYS_COOKIE_WIDTH,
		rMenu.top  + SYS_COOKIE_OFFSET + SYS_COOKIE_HEIGHT);

	// Exclude the Caption Bar area and Have default draw
    HDC hDC = ::GetDCEx(hwnd, hrgn,
	    DCX_USESTYLE | DCX_WINDOW | DCX_INTERSECTRGN | DCX_LOCKWINDOWUPDATE);
	int level = ::SaveDC(hDC);
	CRgn rgn1;
	CRgn rgn2;
	rCaption.UnionRect((LPRECT)&rTitle,(LPRECT)&rMenu);
	::ClientToScreen(hwnd,(LPPOINT)&rCaption);
	::ClientToScreen(hwnd,(LPPOINT)&rCaption.right);
	rgn1.FromHandle(hrgn);
	rgn2.CreateRectRgn(rCaption.left,rCaption.top,rCaption.right,rCaption.bottom);
	int ret = rgn2.CombineRgn(&rgn1,&rgn2,RGN_DIFF);
/*
ERROR		    0
NULLREGION	    1
SIMPLEREGION	    2
COMPLEXREGION	    3
*/
	DefWindowProc(hwnd, WM_NCPAINT, (WPARAM)(HRGN)(rgn2.GetSafeHandle()),
		(LPARAM)0L); 
	::RestoreDC(hDC,level);
	::ReleaseDC(hwnd,hDC);


	// Draw the title bar, sys menu cookie, and border	
	CWnd *pWnd = CWnd::FromHandle(hwnd);
	CDC *pDC = pWnd->GetWindowDC(); 
	if (!pDC)
    	return;
	
	CBrush TitleBrush(GetSysColor(COLOR_ACTIVECAPTION));
	CBrush FrameBrush(COLOR_BORDER);
	CBrush MenuBrush(COLOR_SYSMENU);
	CBrush CkBrush(COLOR_COOKIEFILL);
	CBrush CkBrushShadow(COLOR_SYSSHADOW);
	
	pDC->FillRect(rTitle, &TitleBrush);
	pDC->FillRect(rMenu,  &MenuBrush);
	
	pDC->FrameRect(rTitle,  &FrameBrush);
	pDC->FrameRect(r,       &FrameBrush);
	pDC->FrameRect(rMenu,   &FrameBrush);
	pDC->FrameRect(rCookie, &CkBrushShadow);
	rCookie.OffsetRect(-1, -1);
	pDC->FillRect(rCookie,  &CkBrush);
	pDC->FrameRect(rCookie, &FrameBrush);

	CFont fnt;
	int FntHeight = 12;
	if (fnt.CreateFont(FntHeight,0,0,0,FW_NORMAL,FALSE,FALSE,0,0,OUT_DEFAULT_PRECIS,
		CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,
		DEFAULT_PITCH|FF_DONTCARE|TMPF_TRUETYPE,NULL))
	{
		pDC->SelectObject(&fnt);
		pDC->SetBkMode(TRANSPARENT);
		pDC->SetTextColor(GetSysColor(COLOR_CAPTIONTEXT));
		if (::GetWindowText(hwnd,Caption,80) == 0)
			lstrcpy(Caption,_T("QuickZoom"));
		pDC->DrawText((LPCSTR)Caption,-1,&rTitle,DT_CENTER|DT_VCENTER);
		fnt.DeleteObject();
	}
	
	pWnd->ReleaseDC(pDC);
}
Exemplo n.º 4
0
void CSkinWin::OnNcPaint(HRGN rgn1)
{  
    CWnd *pWnd = CWnd::FromHandle(m_hWnd);
    CDC * pDC = pWnd->GetWindowDC();
    CRect wr;
    pWnd->GetWindowRect( wr );
    //SKIN_SHANG 右边框
	//wr.left+=m_BorderRightWidth;

    DWORD style = GetWindowLong( m_hWnd, GWL_STYLE );
    DWORD nCaption = style & WS_CAPTION ;
    if (nCaption == 0)
	{
		//wyw
		pWnd->ReleaseDC(pDC);

        return;
    }

//f ( (DWORD)rgn) 
//pDC->SelectClipRgn( CRgn::FromHandle(rgn) );

    //m_bActive = GetActiveWindow() == m_hWnd;
    int state = 0;
    if ( m_bActive)
        state = 0;
    else 
		state = 1;
    
    pDC->ExcludeClipRect(0, 0, wr.Width(), m_TitleHeight );
    DrawFrame(pDC, 0, 0, wr.Width(), wr.Height(), state, 0);    
    pDC->SelectClipRgn( NULL ); 

    CDC memDC, *pNewDC;
    CMyBitmap bmp;
    CBitmap  *obmp;
    memDC.CreateCompatibleDC( pDC );
    bmp.CreateCompatibleBitmap( pDC, wr.Width(), m_TitleHeight );
    obmp = memDC.SelectObject(&bmp);
    pNewDC = &memDC;
    
    DrawTitle( pNewDC, m_BorderLeftWidth , 0, 
               wr.Width() - m_BorderRightWidth - m_BorderLeftWidth + 1, state );
    DrawLeft( pNewDC, 0, 0, m_bmpLeft.Height(), state );
	//SKIN_SHANG 右边框
    DrawRight( pNewDC, wr.Width() - m_BorderRightWidth , 0, m_bmpRight.Height(), state );
    
    CRgn newrgn;
    newrgn.CreateRectRgn( 0, 0, wr.Width(), wr.Height());

    if ( m_bTrans )
	{
		CRgn rgn;
		rgn.CreateRectRgn( 0, m_TitleHeight, wr.Width(), wr.Height() );
		
 		HRGN hrgn = bmp.CreateRgnFromFile( m_colTrans );
//wyw 防止内存增大 		
//		newrgn.CombineRgn( &rgn, CRgn::FromHandle(hrgn), RGN_XOR);

 		pDC->SelectClipRgn( &newrgn ); 
 		
 		//wyw
 		DeleteObject(hrgn);
		rgn.DeleteObject();
	}
	else
		SetWindowRgn(m_hWnd, newrgn, FALSE);

    if (m_sysmenu){
		if( m_downHitTest == HTCLOSE )
			DrawButton( pNewDC, 0, 1 );
		else if ( m_moveHitTest == HTCLOSE)
			DrawButton( pNewDC, 0, 2 );
		else
			DrawButton( pNewDC, 0, 0 );
	}
	/*if ( m_downHitTest == HTMAXBUTTON )
        DrawButton( pNewDC, 1, 1 );
    else if ( m_moveHitTest == HTMAXBUTTON)
        DrawButton( pNewDC, 1, 2 );
    else
        DrawButton( pNewDC, 1, 0 );  

    if ( m_downHitTest == HTMINBUTTON )
        DrawButton( pNewDC, 2, 1 );
    else if ( m_moveHitTest == HTMINBUTTON)
        DrawButton( pNewDC, 2, 2 );
    else
        DrawButton( pNewDC, 2, 0 ); // liub_modify 去除弹出面板(去掉按钮)
   if ( m_downHitTest == HTMINBUTTON )
        DrawButton( pNewDC, 2, 1 );
    else if ( m_moveHitTest == HTMINBUTTON)
        DrawButton( pNewDC, 2, 2 );
    else
        DrawButton( pNewDC, 2, 0 );    */
	if ( m_downHitTest == HTMINBUTTON )
        DrawButton( pNewDC, 1, 1 );
    else if ( m_moveHitTest == HTMINBUTTON)
        DrawButton( pNewDC, 1, 2 );
    else
        DrawButton( pNewDC, 1, 0 ); 

          

    int cx = GetSystemMetrics(SM_CXSMICON);
    int cy = GetSystemMetrics(SM_CYSMICON);
    HICON hi = (HICON)SendMessage( m_hWnd, WM_GETICON, ICON_SMALL, 0);
    if ( !hi )
    {
//#ifdef IDR_MAINFRAME
        hi = AfxGetApp()->LoadIcon(g_SetData.Main_szMainIcon);
//#endif
    }
    //draw icon
//     ::DrawIconEx( pNewDC->GetSafeHdc(), m_BorderLeftWidth, 5, (HICON)
//         CopyImage( hi, IMAGE_ICON, 
//         cx, cy, 0), cx, cy, 0, 0, DI_NORMAL);

#if 0 //wyw
	//draw icon
	::DrawIconEx( pNewDC->GetSafeHdc(), m_BorderLeftWidth, 5, (HICON)
		CopyImage( hi, IMAGE_ICON, cx, cy, 0), cx, cy, 0, 0, DI_NORMAL);
#else
	if (NULL != hi) {
		HICON hIcon = (HICON)CopyImage( hi, IMAGE_ICON, cx, cy, 0);
		ASSERT(NULL != hIcon);
		::DrawIconEx( pNewDC->GetSafeHdc(), m_BorderLeftWidth, 5, hIcon, cx, cy, 0, 0, DI_NORMAL);
		DestroyIcon(hIcon);
	}
#endif

    //draw text
    if ( m_title.IsEmpty() )
        pWnd->GetWindowText(m_title);

    if (m_bActive)
        pNewDC->SetTextColor( m_colTitle1 );
    else
        pNewDC->SetTextColor( m_colTitle2 );

    CFont font, *ofont;
    font.CreatePointFont( GetSystemMetrics(SM_CYSMCAPTION), _T("System") );
    ofont = pNewDC->SelectObject(&font);

    pNewDC->SetBkMode(TRANSPARENT);
    pNewDC->DrawText( m_title, CRect( m_textShift, m_textShiftVer, wr.Width() - m_bmpTitle.Width() + m_titleoff2, 
        m_TitleHeight ), DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_WORD_ELLIPSIS  );

    pNewDC->SelectObject(&font);

    pDC->BitBlt( 0, 0, wr.Width(),
        m_TitleHeight, pNewDC, 0, 0, SRCCOPY );

    pDC->SelectClipRgn(NULL);

	//wyw
	memDC.SelectObject(obmp);

	#ifdef FEATURE_VERSION_ITELCO
		if(m_pHookedWnd == AfxGetMainWnd())
		{
			pWnd = CWnd::FromHandle(m_hWnd);
			pDC = pWnd->GetWindowDC();
			CRect rtWnd,rtTitle;
			pWnd->GetWindowRect(&rtWnd); 
			CRect m_rtIcon;
			rtTitle.left = GetSystemMetrics(SM_CXFRAME); 
			rtTitle.top = GetSystemMetrics(SM_CYFRAME); 
			//rtTitle.right = rtWnd.right - rtWnd.left - GetSystemMetrics(SM_CXFRAME); 
			rtTitle.bottom = rtTitle.top + GetSystemMetrics(SM_CYSIZE); 

			m_rtIcon.left = rtTitle.left + 350;  
			m_rtIcon.top = rtTitle.top - 1; 
			//m_rtIcon.right = m_rtIcon.left + 323;   //323
			//m_rtIcon.bottom = m_rtIcon.top + 20;    //25

			HICON hLogInfo;

			hLogInfo = (HICON)::LoadImage(NULL,
										  g_SetData.Main_szTitleLogoIcon, 
										  IMAGE_ICON,
										  248, 24, 
										  LR_LOADFROMFILE|LR_DEFAULTCOLOR);
			DWORD dword = GetLastError();

			//IDR_MAINFRAME  IDI_ICON_INFO
			BOOL BRes = ::DrawIconEx(pDC->m_hDC, m_rtIcon.left, m_rtIcon.top,
									 hLogInfo, 0,
									 0, 0, NULL, DI_NORMAL); 
			dword = GetLastError();

		}
	#endif

	//wyw
	font.DeleteObject();
	bmp.DeleteObject();
	newrgn.DeleteObject();
	memDC.DeleteDC();
	pWnd->ReleaseDC(pDC);
}
Exemplo n.º 5
0
CString CRichEditCtrlExtn::GetTextFormatting(const CString &csHTML, int &iError)
{
  CString csText, csToken, csHTMLTag;
  int iCurrentFontSize, iCurrentFontPointSize;
  int iDefaultFontSize, iDefaultFontPointSize;
  int iTextPosition(0);
  int curPos, oldPos;

  int ierrorcode(0);
  bool bHTMLTag;

  m_vFormat.clear();
  m_vALink.clear();

  st_format this_format;

  ALink this_ALink;

  std::bitset<3> bsFontChange;  // facename, size, color

  std::vector<CString> vLastFacenames;
  std::vector<COLORREF> vLastColours;
  std::vector<int> vLastSizes;
  std::vector<int> vFontChangeStart;
  std::vector<std::bitset<3>> vFontChange;
  std::stack<st_format> format_stack;
  std::stack<int> type_stack;

  // Validate the HTML
  curPos = 0;
  oldPos = 0;
  int iBold(0), iItalic(0), iUnderline(0), iFont(0), iAnchor(0);
  bool bNestedBold(false), bNestedItalic(false), bNestedUnderline(false),
       bNestedAnchor(false), bOverlapped(false);

  csToken = csHTML.Tokenize(L"<>", curPos);
  while (csToken != L"" && curPos != -1) {
    oldPos = curPos - csToken.GetLength() - 1;
    CString a = csHTML.Mid(oldPos - 1, 1);
    CString b = csHTML.Mid(curPos - 1, 1);
    if (csHTML.Mid(oldPos - 1, 1) == L"<" &&
      csHTML.Mid(curPos - 1, 1) == L">") {
        bHTMLTag = true;
    } else
      bHTMLTag = false;

    if (bHTMLTag) {
      // Must be a HTML Tag
      csHTMLTag = csToken;
      csHTMLTag.MakeLower();
      if (csHTMLTag == L"b") {
        type_stack.push(Bold);
        iBold++;
        if (iBold != 1) bNestedBold = true;
        goto vnext;
      } else if (csHTMLTag == L"/b") {
        int &iLastType = type_stack.top();
        if (iLastType != Bold)
          bOverlapped = true;
        iBold--;
        type_stack.pop();
        goto vnext;
      } else if (csHTMLTag == L"i") {
        type_stack.push(Italic);
        iItalic++;
        if (iItalic != 1) bNestedItalic = true;
        goto vnext;
      } else if (csHTMLTag == L"/i") {
        int &iLastType = type_stack.top();
        if (iLastType != Italic)
          bOverlapped = true;
        iItalic--;
        type_stack.pop();
        goto vnext;
      } else if (csHTMLTag == L"u") {
        type_stack.push(Underline);
        iUnderline++;
        if (iUnderline != 1) bNestedUnderline = true;
        goto vnext;
      } else if (csHTMLTag == L"/u") {
        int &iLastType = type_stack.top();
        if (iLastType != Underline)
          bOverlapped = true;
        iUnderline--;
        type_stack.pop();
        goto vnext;
      } else if (csHTMLTag.Left(4) == L"font") {
        type_stack.push(Font);
        iFont++;
        goto vnext;
      } else if (csHTMLTag == L"/font") {
        int &iLastType = type_stack.top();
        if (iLastType != Font)
          bOverlapped = true;
        iFont--;
        type_stack.pop();
        goto vnext;
      } else if (csHTMLTag.Left(6) == L"a href") {
        type_stack.push(Link);
        iAnchor++;
        if (iAnchor != 1) bNestedAnchor = true;
        goto vnext;
      } else if (csHTMLTag == L"/a") {
        int &iLastType = type_stack.top();
        if (iLastType != Link)
          bOverlapped = true;
        iAnchor--;
        type_stack.pop();
        goto vnext;
      } else { // unsupported tag or typo - return raw string
        return csHTML;
      }
    }

vnext:
    oldPos = curPos;
    csToken = csHTML.Tokenize(L"<>", curPos);
  };

  if (bNestedBold)
    ierrorcode += 1;
  if (iBold != 0)
    ierrorcode += 2;
  if (bNestedItalic)
    ierrorcode += 4;
  if (iItalic != 0)
    ierrorcode += 8;
  if (bNestedUnderline)
    ierrorcode += 16;
  if (iUnderline != 0)
    ierrorcode += 32;
  if (bNestedAnchor)
    ierrorcode += 64;
  if (iAnchor != 0)
    ierrorcode += 128;
  if (iFont != 0)
    ierrorcode += 256;
  if (bOverlapped)
    ierrorcode +=512;

  iError = ierrorcode;

  if (ierrorcode != 0) {
    return L"";
  }

  // Now really process the HTML
  NONCLIENTMETRICS ncm ={0};
  ncm.cbSize = sizeof(NONCLIENTMETRICS);

  SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
                       sizeof(NONCLIENTMETRICS), &ncm, NULL);

  CWnd *pWndDesk = GetDesktopWindow();
  CDC *pDCDesk = pWndDesk->GetWindowDC();
  int logPixY = pDCDesk->GetDeviceCaps(LOGPIXELSY);
  pWndDesk->ReleaseDC(pDCDesk);

  iDefaultFontPointSize = MulDiv(ncm.lfMessageFont.lfHeight, 72, logPixY);
  iCurrentFontPointSize = iDefaultFontPointSize;
  iDefaultFontSize = ConvertPointsToSize(iCurrentFontPointSize);
  iCurrentFontSize = iDefaultFontSize;

  curPos = 0;
  oldPos = 0;

  csToken = csHTML.Tokenize(L"<>", curPos);
  while (csToken != L"" && curPos != -1) {
    oldPos = curPos - csToken.GetLength() - 1;
    CString a = csHTML.Mid(oldPos - 1, 1);
    CString b = csHTML.Mid(curPos - 1, 1);
    if (csHTML.Mid(oldPos - 1, 1) == L"<" &&
        csHTML.Mid(curPos - 1, 1) == L">") {
      bHTMLTag = true;
    } else
      bHTMLTag = false;

    if (!bHTMLTag && iAnchor != 0)
      goto next;

    if (bHTMLTag) {
      // Must be a HTML Tag
      csHTMLTag = csToken;
      csHTMLTag.MakeLower();
      if (csHTMLTag == L"b") {
        this_format.entrytype = Bold;
        this_format.iStart = iTextPosition;
        format_stack.push(this_format);
        goto next;
      } else
      if (csHTMLTag == L"/b") {
        st_format& cur_format = format_stack.top();
        cur_format.iEnd = iTextPosition;
        m_vFormat.push_back(cur_format);
        format_stack.pop();
        goto next;
      } else
      if (csHTMLTag == L"i") {
        this_format.entrytype = Italic;
        this_format.iStart = iTextPosition;
        format_stack.push(this_format);
        goto next;
      } else
      if (csHTMLTag == L"/i") {
        st_format& cur_format = format_stack.top();
        cur_format.iEnd = iTextPosition;
        m_vFormat.push_back(cur_format);
        format_stack.pop();
        goto next;
      } else
      if (csHTMLTag == L"u") {
        this_format.entrytype = Underline;
        this_format.iStart = iTextPosition;
        format_stack.push(this_format);
        goto next;
      } else
      if (csHTMLTag == L"/u") {
        st_format& cur_format = format_stack.top();
        cur_format.iEnd = iTextPosition;
        m_vFormat.push_back(cur_format);
        format_stack.pop();
        goto next;
      } else
      if (csHTMLTag == L"/font") {
        if (vFontChange.empty()) { // malformed <font> token
          return csHTML;
        }
        std::bitset<3> &bsLastFont = vFontChange.back();
        int &iFontChangeStart = vFontChangeStart.back();
        st_format& cur_format = format_stack.top();
        if (bsLastFont.test(FACENAMECHANGED)) {
          CString &csLastFaceName = vLastFacenames.back();
          cur_format.entrytype = Name;
          cur_format.iStart = iFontChangeStart;
          cur_format.iEnd = iTextPosition;
          SecureZeroMemory(cur_format.tcszFACENAME, sizeof(cur_format.tcszFACENAME));
#if (_MSC_VER >= 1400)
          wcscpy_s(cur_format.tcszFACENAME, LF_FACESIZE, (LPCWSTR)csLastFaceName);
#else
          wcscpy(cur_format.tcszFACENAME, (LPCWSTR)csLastFaceName);
#endif
          m_vFormat.push_back(cur_format);
          vLastFacenames.pop_back();
        }
        if (bsLastFont.test(SIZECHANGED)) {
          int &iLastSize = vLastSizes.back();
          cur_format.entrytype = Size;
          cur_format.iStart = iFontChangeStart;
          cur_format.iEnd = iTextPosition;
          cur_format.iSize = iLastSize;
          m_vFormat.push_back(cur_format);
          vLastSizes.pop_back();
          if (!vLastSizes.empty()) {
            int &i = vLastSizes.back();
            iCurrentFontPointSize = i;
            iCurrentFontSize = ConvertPointsToSize(iCurrentFontPointSize);
          } else {
            iCurrentFontPointSize = iDefaultFontPointSize;
            iCurrentFontSize = iDefaultFontSize;
          }
        }
        if (bsLastFont.test(COLOURCHANGED)) {
          COLORREF &c = vLastColours.back();
          cur_format.entrytype = Colour;
          cur_format.iStart = iFontChangeStart;
          cur_format.iEnd = iTextPosition;
          cur_format.cr = c;
          m_vFormat.push_back(cur_format);
          vLastColours.pop_back();
        }
        vFontChange.pop_back();
        vFontChangeStart.pop_back();
        format_stack.pop();
        goto next;
      } else if (csHTMLTag == L"/a") {
        goto next;
      }

      // Check for fonts
      // <font face="xxxxx" size="n" color="xxxxx">....</font>
      if (csHTMLTag.Left(5) == L"font ") {
        CString csFontToken, csFontVerb, csFontVerbValue;
        int curFontPos(0);

        bsFontChange.reset();
        csFontToken = csHTMLTag.Tokenize(L"\"", curFontPos);
        csFontVerb = csFontToken.Right(6);
        csFontVerb.TrimLeft();
        // Skip over first token of 'font verb='
        csFontVerbValue = csHTMLTag.Tokenize(L"\"", curFontPos);
        while (csFontVerbValue != L"" && curFontPos != -1) {
          if (csFontVerb == L"face=") {
            bsFontChange.set(FACENAMECHANGED);
            vLastFacenames.push_back(csFontVerbValue);
          } else
            if (csFontVerb == L"size=") {
              bsFontChange.set(SIZECHANGED);
              iCurrentFontPointSize = ConvertSizeToPoints(csFontVerbValue, iCurrentFontSize);
              vLastSizes.push_back(iCurrentFontPointSize);
            } else
              if (csFontVerb == L"color=") {
                bsFontChange.set(COLOURCHANGED);
                COLORREF crNewFontColour = ConvertColourToColorRef(csFontVerbValue);
                vLastColours.push_back(crNewFontColour);
              }

              csFontVerb = csHTMLTag.Tokenize(L"\"", curFontPos);
              if (csFontVerb.IsEmpty() && curFontPos == -1)
                break;
              csFontVerbValue = csHTMLTag.Tokenize(L"\"", curFontPos);
        };
        vFontChange.push_back(bsFontChange);
        vFontChangeStart.push_back(iTextPosition);
        format_stack.push(this_format);
        goto next;
      }

      // check for hyperlink
      // <a href="http://www.microsoft.com">Friendly name</a>

      if (csHTMLTag.Left(7) == L"a href=") {
        long dwTEnd;
        CString csURL;
        dwTEnd = csHTMLTag.Find(L"\"", 8);
        if (dwTEnd >= 0) {
          csURL = csHTMLTag.Mid(8, dwTEnd - 8);
          if (!csURL.IsEmpty()) {
            csURL.MakeLower();
#if (_MSC_VER >= 1400)
            wcscpy_s(this_ALink.tcszURL, _MAX_PATH, csURL);
#else
            wcscpy(this_ALink.tcszURL, csURL);
#endif
          }
        }
        // Now get Friendly Name (note doing this within the while loop!)
        oldPos = curPos;
        csToken = csHTML.Tokenize(L"<>", curPos);
        csText += csToken;
        this_ALink.iStart = iTextPosition;
        iTextPosition += csToken.GetLength();
        this_ALink.iEnd = iTextPosition;
        m_vALink.push_back(this_ALink);
        goto next;
      }
    }

    csToken.Replace(L"&lt;", L"<");
    csToken.Replace(L"&gt;", L">");
    // Real text or unknown HTML tag
    if (bHTMLTag) {
      // We didn't recognise it! Put back the < & >
      csText += L"<" + csToken + L">";
      iTextPosition += csToken.GetLength() + 2;
    } else {
      csText += csToken;
      iTextPosition += csToken.GetLength();
    }

next:
    oldPos = curPos;
    csToken = csHTML.Tokenize(L"<>", curPos);
  };

  return csText;
}