⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nghtmlstaticctrl.cpp

📁 ResOrg 图形化管理Vc项目的资源ID的工具的源代码。 ResOrg - Manage and Renumber Resource Symbol IDs Introduction The
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// XHTMLStatic.cpp  Version 1.0
//
// Author:  Hans Dietrich
//          hdietrich2@hotmail.com
//
// Thanks to Charles Petzold for explaining how GetTextExtentPoint32() works,
// in his excellent "Programming Windows", Fifth Edition:
//     http://www.bookpool.com/.x/6o8gzz6xw6/sm/157231995X
//
// Thanks to Chris Maunder for showing how to set the cursor and receive mouse
// clicks for static controls, and for all the code that I used from his 
// CHyperLink class:
//     http://www.codeproject.com/miscctrl/hyperlink.asp
//
// This software is released into the public domain.
// You are free to use it in any way you like.
//
// This software is provided "as is" with no expressed
// or implied warranty.  I accept no liability for any
// damage or loss of business that this software may cause.
//
///////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "NGHtmlStaticCtrl.h"
#include "NGNamedColours.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


//#define _THEME


#ifdef _THEME
	#include <Uxtheme.h>
	#include <tmschema.h>

#pragma comment(lib, "UxTheme.lib")
#endif

///////////////////////////////////////////////////////////////////////////////
// CNGHtmlStaticCtrl

BEGIN_MESSAGE_MAP(CNGHtmlStaticCtrl, CStatic)

	//{{AFX_MSG_MAP(CNGHtmlStaticCtrl)
	ON_WM_CREATE()
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
	ON_WM_TIMER()
	ON_WM_SETCURSOR()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
    ON_MESSAGE(WM_SETTEXT, OnMsgSetText)
    ON_CONTROL_REFLECT(STN_CLICKED, OnClicked)

END_MESSAGE_MAP()


///////////////////////////////////////////////////////////////////////////////
// ctor
CNGHtmlStaticCtrl::CNGHtmlStaticCtrl()
{
	m_crBackGround		= CLR_DEFAULT;
	m_crText			= ::GetSysColor(COLOR_WINDOWTEXT);
	m_bTransparent		= FALSE;
	m_bUnderline		= FALSE;
	m_bBold				= FALSE;
	m_bItalic			= FALSE;
	m_bStrikeThrough	= FALSE;
	m_bHyperlinkTimer	= FALSE;
	m_bOnHyperlink		= FALSE;
	m_hLinkCursor		= NULL;
	m_hPrevCursor		= NULL;
	m_bInAnchor			= FALSE;
	m_AnchorRectPtrs.RemoveAll();
	m_AnchorUrls.RemoveAll();

    CString strWndDir;
    GetWindowsDirectory(strWndDir.GetBuffer(MAX_PATH), MAX_PATH);
    strWndDir.ReleaseBuffer();

    strWndDir += _T("\\winhlp32.exe");
    // This retrieves cursor #106 from winhlp32.exe, which is a hand pointer
    HMODULE hModule = ::LoadLibrary(strWndDir);
    if (hModule) 
	{
        HCURSOR hHandCursor = ::LoadCursor(hModule, MAKEINTRESOURCE(106));
        if (hHandCursor)
            m_hLinkCursor = CopyCursor(hHandCursor);
    }
    ::FreeLibrary(hModule);
}

///////////////////////////////////////////////////////////////////////////////
// dtor
CNGHtmlStaticCtrl::~CNGHtmlStaticCtrl()
{
	int n = m_AnchorRectPtrs.GetSize();

	for (int i = 0; i < n; i++)
	{
		CRect *pRect = (CRect *) m_AnchorRectPtrs[i];
		if (pRect)
			delete pRect;
	}

	m_AnchorRectPtrs.RemoveAll();
	m_AnchorUrls.RemoveAll();
}


int CNGHtmlStaticCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	int nResult = CStatic::OnCreate(lpCreateStruct);
	if (nResult != -1)
	{
		// We want to get mouse clicks via STN_CLICKED
		DWORD dwStyle = GetStyle();
		::SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyle | SS_NOTIFY);

		DWORD dwStyleEx = GetExStyle();

		m_bTransparent = ( (dwStyleEx & WS_EX_TRANSPARENT) > 0);

		CFont* cf = GetFont();
		LOGFONT lf;

		if (cf != NULL)
		{
			cf->GetObject(sizeof(lf), &lf);
		}
		else
		{
			GetObject(GetStockObject(SYSTEM_FONT), sizeof(lf), &lf);
		}

		m_font.DeleteObject();
		VERIFY(m_font.CreateFontIndirect(&lf));
	}
	return nResult;
}


BOOL CNGHtmlStaticCtrl::OnEraseBkgnd(CDC* pDC)
{
	if (!m_bTransparent && (m_crBackGround != CLR_DEFAULT) )
	{
		CRect rect;
		GetClientRect(&rect);

		pDC->FillSolidRect(&rect, m_crBackGround);

		return TRUE;
	}

	return CStatic::OnEraseBkgnd(pDC);
}
   


LRESULT CNGHtmlStaticCtrl::OnMsgSetText(WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(wParam);
	UNREFERENCED_PARAMETER(lParam);

	Invalidate();

    return Default();
}


void CNGHtmlStaticCtrl::OnPaint() 
{
	CPaintDC dc(this); // device context for painting

	// get text from control
	CString strText;
	GetWindowText(strText);

	// Reset these flags just in case the HTML was badly formed and
	// we were left hanging...
	m_bBold				= FALSE;
	m_bUnderline		= FALSE;
	m_bItalic			= FALSE;
	m_bStrikeThrough	= FALSE;

	CString str1;
	int index;

	// set text and background colors
	COLORREF crText = m_crText;
	COLORREF prev_crText = crText;

	COLORREF crBackground = m_crBackGround;
	COLORREF prev_crBackground = crBackground;

	CFont *pOldFont = dc.SelectObject(&m_font);
	int n = strText.GetLength();


	CRect rect;
	GetClientRect(&rect);

/*	if (!m_bTransparent)
	{
		dc.FillSolidRect(&rect, m_crBackGround);
	}
*/
	int nInitialXOffset = 0;

	LOGFONT lf, prev_lf;
	CFont* cf = GetFont();
	if (cf)
		cf->GetObject(sizeof(lf), &lf);
	else
		GetObject(GetStockObject(SYSTEM_FONT), sizeof(lf), &lf);

	memcpy(&prev_lf, &lf, sizeof(lf));

	CString strAnchorText = _T("");

	while (n > 0)
	{
		///////////////////////////////////////////////////////////////////////
		if (strText.Left(3) == _T("<b>") ||			// check for <b>
			strText.Left(3) == _T("<B>"))			// check for <B>
		{
			n -= 3;
			index = strText.Find(_T('>'));
			if (index != -1)
				strText = strText.Mid(index+1);
			m_bBold++;// = TRUE;
			continue;
		}
		///////////////////////////////////////////////////////////////////////
		else if (strText.Left(4) == _T("</b>") ||	// check for </b>
				 strText.Left(4) == _T("</B>"))		// check for </B>
		{
			n -= 4;
			index = strText.Find(_T('>'));
			if (index != -1)
				strText = strText.Mid(index+1);
			if (m_bBold)
				m_bBold--;// = FALSE;
			continue;
		}
		///////////////////////////////////////////////////////////////////////
		else if (strText.Left(3) == _T("<i>") ||	// check for <i>
				 strText.Left(3) == _T("<I>"))		// check for <I>
		{
			n -= 3;
			index = strText.Find(_T('>'));
			if (index != -1)
				strText = strText.Mid(index+1);
			m_bItalic++;// = TRUE;
			continue;
		}
		///////////////////////////////////////////////////////////////////////
		else if (strText.Left(4) == _T("</i>") ||	// check for </i>
				 strText.Left(4) == _T("</I>"))		// check for </I>
		{
			n -= 4;
			index = strText.Find(_T('>'));
			if (index != -1)
				strText = strText.Mid(index+1);
			if (m_bItalic)
				m_bItalic--;// = FALSE;
			continue;
		}
		///////////////////////////////////////////////////////////////////////
		else if (strText.Left(3) == _T("<u>") ||	// check for <u>
				 strText.Left(3) == _T("<U>"))		// check for <U>
		{
			n -= 3;
			index = strText.Find(_T('>'));
			if (index != -1)
				strText = strText.Mid(index+1);
			m_bUnderline++;// = TRUE;
			continue;
		}
		///////////////////////////////////////////////////////////////////////
		else if (strText.Left(4) == _T("</u>") ||	// check for </u>
				 strText.Left(4) == _T("</U>"))		// check for </U>
		{
			n -= 4;
			index = strText.Find(_T('>'));
			if (index != -1)
				strText = strText.Mid(index+1);
			if (m_bUnderline)
				m_bUnderline--;// = FALSE;
			continue;
		}
		///////////////////////////////////////////////////////////////////////
		else if (strText.Left(8) == _T("<strike>") ||	// check for <strike>
				 strText.Left(8) == _T("<STRIKE>"))		// check for <STRIKE>
		{
			n -= 8;
			index = strText.Find(_T('>'));
			if (index != -1)
				strText = strText.Mid(index+1);
			m_bStrikeThrough++;// = TRUE;
			continue;
		}
		///////////////////////////////////////////////////////////////////////
		else if (strText.Left(9) == _T("</strike>") ||	// check for </strike>
				 strText.Left(9) == _T("</STRIKE>"))	// check for </STRIKE>
		{
			n -= 9;
			index = strText.Find(_T('>'));
			if (index != -1)
				strText = strText.Mid(index+1);
			if (m_bStrikeThrough)
				m_bStrikeThrough--;// = FALSE;
			continue;
		}
		///////////////////////////////////////////////////////////////////////
		else if (strText.Left(5) == _T("<font") ||		// check for <font
				 strText.Left(5) == _T("<FONT"))		// check for <FONT
		{
			index = strText.Find(_T('>'));
			if (index != -1)
			{
				CString strFont = strText.Mid(5, index-5);
				int m = strFont.GetLength();
				strText = strText.Mid(index+1);

				// loop to parse FONT attributes
				while (m > 0)
				{
					// trim left whitespace
					if ((strFont.GetLength() > 0) && (strFont[0] == _T(' ')))
					{
						m--;
						strFont = strFont.Mid(1);
						continue;
					}

					///////////////////////////////////////////////////////////
					if (strFont.Left(5) == _T("color") ||
						strFont.Left(5) == _T("COLOR"))
					{
						int index2 = strFont.Find(_T('"'));
						if (index2 != -1)
						{
							m -= index2 + 1;
							strFont = strFont.Mid(index2+1);

							index2 = strFont.Find(_T('"'));
							if (index2 != -1)
							{
								CString strColor = strFont.Left(index2);

								CNGNamedColours nc(strColor);
								crText = nc.GetRGB();
								strFont = strFont.Mid(index2+1);
								m = strFont.GetLength();
							}
						}
						else
							break;
					}
					///////////////////////////////////////////////////////////
					else if (strFont.Left(7) == _T("bgcolor") ||
							 strFont.Left(7) == _T("BGCOLOR"))
					{
						int index2 = strFont.Find(_T('"'));
						if (index2 != -1)
						{
							m -= index2 + 1;
							strFont = strFont.Mid(index2+1);

							index2 = strFont.Find(_T('"'));
							if (index2 != -1)
							{
								CString strBgColor = strFont.Left(index2);
								CNGNamedColours nc(strBgColor);
								crBackground = nc.GetRGB();
								strFont = strFont.Mid(index2+1);
								m = strFont.GetLength();
							}
						}
						else
							break;
					}
					///////////////////////////////////////////////////////////
					else if (strFont.Left(4) == _T("face") ||
							 strFont.Left(4) == _T("FACE"))
					{
						int index2 = strFont.Find(_T('"'));
						if (index2 != -1)
						{
							m -= index2 + 1;
							strFont = strFont.Mid(index2+1);
							index2 = strFont.Find(_T('"'));
							if (index2 != -1)
							{
								memset(lf.lfFaceName, 0, sizeof(lf.lfFaceName));
								_tcsncpy(lf.lfFaceName, strFont, index2);

								m -= index2 + 1;
								if (m > 0)
									strFont = strFont.Mid(index2+1);
								else
									strFont = _T("");
								m = strFont.GetLength();
							}
						}
						else
							break;
					}
					///////////////////////////////////////////////////////////
					else if (strFont.Left(4) == _T("size") ||
							 strFont.Left(4) == _T("SIZE"))
					{
						int index2 = strFont.Find(_T('"'));
						if (index2 != -1)
						{
							m -= index2 + 1;
							strFont = strFont.Mid(index2+1);
							index2 = strFont.Find(_T('"'));
							if (index2 != -1)
							{
								int nSize = 0;
								nSize = _ttoi(strFont);
								lf.lfHeight -= nSize;

								m -= index2 + 1;
								if (m > 0)
									strFont = strFont.Mid(index2+1);
								else
									strFont = _T("");
								m = strFont.GetLength();
							}
						}
						else
							break;
					}
					else
					{
						while ((strFont.GetLength() > 0) && 
							   (strFont[0] != _T(' ')))
						{
							m--;
							strFont = strFont.Mid(1);
						}
					}
				}
				n -= index + 1;
			}
			continue;
		}
		///////////////////////////////////////////////////////////////////////
		else if (strText.Left(7) == _T("</font>") ||	// check for </font>
				 strText.Left(7) == _T("</FONT>"))		// check for </FONT>
		{
			n -= 7;
			index = strText.Find(_T('>'));
			if (index != -1)
				strText = strText.Mid(index+1);
			crText = prev_crText;
			crBackground = prev_crBackground;
			memcpy(&lf, &prev_lf, sizeof(lf));
			continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -