📄 nghtmlstaticctrl.cpp
字号:
}
///////////////////////////////////////////////////////////////////////
// <a href=www.xyz.com>XYZ Web Site</a>
else if (strText.Left(8) == _T("<a href=") || // check for <a href=
strText.Left(8) == _T("<A HREF=")) // check for <A HREF=
{
index = strText.Find(_T('>'));
if (index != -1)
{
strAnchorText = strText.Mid(8, index-8);
strText = strText.Mid(index+1);
n = strText.GetLength();
m_bInAnchor = TRUE;
continue;
}
}
///////////////////////////////////////////////////////////////////////
else if (strText.Left(4) == _T("</a>") || // check for </a>
strText.Left(4) == _T("</A>")) // check for </A>
{
strText = strText.Mid(4);
n -= 4;
m_bInAnchor = FALSE;
continue;
}
///////////////////////////////////////////////////////////////////////
// <br> or \r\n or plain text
else
{
str1 = strText;
index = str1.Find(_T('<'));
if (index != -1)
{
if (strText.Left(4) == _T("<br>") || // check for <br>
strText.Left(4) == _T("<BR>")) // check for <BR>
{
n -= 4;
str1 = _T("\r\n ");
strText = strText.Mid(4);
}
else
{
str1 = strText.Left(index);
if (str1.GetLength() <= 0)
{
if (strText.GetLength() != 0)
{
str1 = strText[0];
index = 1;
n -= 1;
}
}
strText = strText.Mid(index);
}
}
else
{
str1 = strText;
strText = _T("");
}
}
lf.lfWeight = m_bBold ? FW_BOLD : FW_NORMAL;
lf.lfUnderline = (BYTE) m_bUnderline;
lf.lfItalic = (BYTE) m_bItalic;
lf.lfStrikeOut = (BYTE) m_bStrikeThrough;
m_font.DeleteObject();
VERIFY(m_font.CreateFontIndirect(&lf));
dc.SetTextColor(crText);
if (m_bTransparent)
{
dc.SetBkMode(TRANSPARENT);
}
else if (crBackground != CLR_DEFAULT)
{
dc.SetBkColor(crBackground);
}
dc.SelectObject(&m_font);
CRect rectDraw;
rectDraw = rect;
nInitialXOffset = FormatText(dc.m_hDC, str1, &rect, nInitialXOffset);
if (m_bInAnchor)
{
SIZE size;
GetTextExtentPoint32(dc.m_hDC, str1, str1.GetLength(), &size);
rectDraw.bottom = rectDraw.top + size.cy;
rectDraw.right = rectDraw.left + size.cx;
// save rect for this text - save in window coordinates
CRect *pRect = new CRect(rectDraw);
m_AnchorRectPtrs.Add(pRect);
m_AnchorUrls.Add(strAnchorText);
if (!m_bHyperlinkTimer)
{
m_bHyperlinkTimer = TRUE;
SetTimer(1, 80, NULL);
}
}
n -= str1.GetLength();
}
// Restore DC's State
dc.SelectObject(pOldFont);
// Do not call CStatic::OnPaint() for painting messages
}
///////////////////////////////////////////////////////////////////////////////
// IsBlank
BOOL CNGHtmlStaticCtrl::IsBlank(LPCTSTR lpszText)
{
TCHAR c;
while ((c = *lpszText++) != _T('\0'))
if (c != _T(' ') && c != _T('\t'))
return FALSE;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// FormatText
int CNGHtmlStaticCtrl::FormatText(HDC hdc,
LPCTSTR lpszText,
RECT * pRect,
int nInitialXOffset)
{
int xStart, yStart, nWord, xNext, xLast;
TCHAR *pText = (TCHAR *) lpszText;
TCHAR *pBegin, *pEnd;
SIZE size;
yStart = pRect->top;
xNext = nInitialXOffset;
xLast = 0;
if (pRect->top >= (pRect->bottom-1))
return 0;
// set initial size
TCHAR * szTest = _T("abcdefgABCDEFG");
GetTextExtentPoint32(hdc, szTest, _tcslen(szTest), &size);
// prepare for next line - clear out the error term
SetTextJustification(hdc, 0, 0);
CString strOut = _T("");
BOOL bReturnSeen = FALSE;
do // for each text line
{
nWord = 0; // initialize number of spaces in line
pBegin = pText; // set pointer to char at beginning of line
// skip to first non-space in line
while (*pText != _T('\0') && *pText == _T(' '))
{
if (xNext)
strOut += *pText;
pText++;
}
for(;;) // until the line is known
{
pEnd = pText; // set pointer to char at end of line
// skip to next word
while (*pText != _T('\0') && *pText == _T(' '))
strOut += *pText++;
// skip \r
if (*pText == _T('\r'))
pText++;
// \n = new line
if (*pText == _T('\n'))
{
strOut += _T(' ');
pText++;
bReturnSeen = TRUE;
}
if (!bReturnSeen)
{
// skip to next space
while (*pText != _T('\0') && *pText != _T(' '))
strOut += *pText++;
}
// after each word, calculate extents
nWord++;
GetTextExtentPoint32(hdc, strOut, strOut.GetLength(), &size);
if (size.cx >= (pRect->right - xNext - 5)) // don't get too close to margin,
// in case of italic text
{
if ((pEnd - pBegin) != 0)
{
strOut = strOut.Left(pEnd - pBegin);
break;
}
pText = pBegin;
xNext = 0;
yStart += size.cy;
}
if (*pText == _T('\0'))
{
pEnd = pText;
strOut = strOut.Left(pEnd - pBegin);
break;
}
if (bReturnSeen)
{
pEnd = pText;
strOut = strOut.Left(pEnd - pBegin);
break;
}
}
nWord--; // discount last space at end of line
// if end of text and no space characters, set pEnd to end
GetTextExtentPoint32(hdc, strOut, strOut.GetLength(), &size);
xStart = pRect->left;
xStart += xNext;
xNext = 0;
xLast = xStart + size.cx;
// display the text
if ((yStart <= (pRect->bottom-size.cy)) && (!IsBlank(strOut)))
TextOut(hdc, xStart, yStart, strOut, strOut.GetLength());
// prepare for next line - clear out the error term
SetTextJustification(hdc, 0, 0);
strOut.Empty();
pText = pEnd;
if (*pText)
{
yStart += size.cy;
}
bReturnSeen = FALSE;
} while (*pText && (yStart < pRect->bottom));
if (yStart > (pRect->bottom-size.cy))
pRect->top = pRect->bottom;
else
pRect->top = yStart;
return xLast;
}
///////////////////////////////////////////////////////////////////////////////
// PreSubclassWindow
//
// The override is called when the window is about to be subclassed
// (by DDX_Control or similar)
//
// It is used here to initialise the contents of the window
// This code is needed as OnCreate() will not be called if the window is subclassed!
//
void CNGHtmlStaticCtrl::PreSubclassWindow()
{
// We want to get mouse clicks via STN_CLICKED
DWORD dwStyle = GetStyle();
::SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyle | SS_NOTIFY);
CStatic::PreSubclassWindow();
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));
}
///////////////////////////////////////////////////////////////////////////////
// OnTimer
void CNGHtmlStaticCtrl::OnTimer(UINT /*nIDEvent*/)
{
int n = m_AnchorRectPtrs.GetSize();
if (n == 0)
return;
CPoint point;
::GetCursorPos(&point);
m_bOnHyperlink = FALSE;
for (int i = 0; i < n; i++)
{
CRect *pRect = (CRect *) m_AnchorRectPtrs[i];
CRect rect = *pRect;
ClientToScreen(&rect);
if (rect.PtInRect(point)) // Cursor is currently over control
{
if (m_hLinkCursor)
{
HCURSOR hPrevCursor = ::SetCursor(m_hLinkCursor);
if (m_hPrevCursor == NULL)
m_hPrevCursor = hPrevCursor;
m_bOnHyperlink = TRUE;
break;
}
}
}
if (!m_bOnHyperlink && m_hPrevCursor)
{
::SetCursor(m_hPrevCursor);
m_hPrevCursor = NULL;
RedrawWindow();
}
}
///////////////////////////////////////////////////////////////////////////////
// OnSetCursor
BOOL CNGHtmlStaticCtrl::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (!m_bOnHyperlink)
return CStatic::OnSetCursor(pWnd, nHitTest, message);
else
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// OnClicked
void CNGHtmlStaticCtrl::OnClicked()
{
CPoint point;
::GetCursorPos(&point);
BOOL bOnHyperlink = FALSE;
int n = m_AnchorRectPtrs.GetSize();
if (n == 0)
return;
int i;
for (i = 0; i < n; i++)
{
CRect *pRect = (CRect *) m_AnchorRectPtrs[i];
CRect rect = *pRect;
ClientToScreen(&rect);
if (rect.PtInRect(point)) // Cursor is currently over control
{
bOnHyperlink = TRUE;
break;
}
}
if (bOnHyperlink)
GotoURL(m_AnchorUrls[i], SW_SHOW);
}
///////////////////////////////////////////////////////////////////////////////
// GoToURL
HINSTANCE CNGHtmlStaticCtrl::GotoURL(LPCTSTR url, int showcmd)
{
ASSERT(url);
ASSERT(url[0] != _T('\0'));
TCHAR key[MAX_PATH + MAX_PATH];
// First try ShellExecute()
HINSTANCE result = ShellExecute(NULL, _T("open"), url, NULL,NULL, showcmd);
// If it failed, get the .htm regkey and lookup the program
if ((UINT)result <= HINSTANCE_ERROR)
{
if (GetRegKey(HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS)
{
_tcscat(key, _T("\\shell\\open\\command"));
if (GetRegKey(HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS)
{
TCHAR *pos;
pos = _tcsstr(key, _T("\"%1\""));
if (pos == NULL) { // No quotes found
pos = _tcsstr(key, _T("%1")); // Check for %1, without quotes
if (pos == NULL) // No parameter at all...
pos = key+lstrlen(key)-1;
else
*pos = _T('\0'); // Remove the parameter
}
else
*pos = _T('\0'); // Remove the parameter
_tcscat(pos, _T(" "));
_tcscat(pos, url);
result = (HINSTANCE) WinExec((LPSTR)key,showcmd);
}
}
}
return result;
}
///////////////////////////////////////////////////////////////////////////////
// GetRegKey
LONG CNGHtmlStaticCtrl::GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata)
{
HKEY hkey;
LONG retval = RegOpenKeyEx(key, subkey, 0, KEY_QUERY_VALUE, &hkey);
*retdata = 0;
if (retval == ERROR_SUCCESS)
{
long datasize = MAX_PATH;
TCHAR data[MAX_PATH];
retval = RegQueryValue(hkey, NULL, data, &datasize);
if (retval == ERROR_SUCCESS)
{
lstrcpy(retdata, data);
RegCloseKey(hkey);
}
}
return retval;
}
///////////////////////////////////////////////////////////////////////////////
// OnDestroy
void CNGHtmlStaticCtrl::OnDestroy()
{
if (m_bHyperlinkTimer)
KillTimer(1);
m_bHyperlinkTimer = FALSE;
CStatic::OnDestroy();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -