xhtmlstatic.cpp
来自「管理项目进度工具的原代码」· C++ 代码 · 共 1,326 行 · 第 1/3 页
CPP
1,326 行
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;
TEXTMETRIC tm;
::GetTextMetrics(hdc, &tm);
do // for each text line
{
nWord = 0; // initialize number of spaces in line
// skip to first non-space in line
while (/**pText != _T('\0') && */*pText == _T(' '))
{
if (xNext)
strOut += *pText;
pText++;
}
for(;;) // process each word
{
CString strWord;
TCHAR *saved_pText = pText;
strWord = GetNextWord(&pText, &bReturnSeen);
CString strTrial;
strTrial = strOut + strWord;
// after each word, calculate extents
nWord++;
GetTextExtentPoint32(hdc, strTrial, strTrial.GetLength(), &size);
BOOL bOverflow = (size.cx >= (pRect->right - xNext - 2));
// don't get too close to margin,
// in case of italic text
if (bOverflow)
{
if (strOut.IsEmpty())
{
bOverflow = FALSE;
strOut = strWord;
}
}
else
{
strOut += strWord;
}
if (bReturnSeen || bOverflow || (*pText == _T('\0')))
{
if (strOut.IsEmpty())
break;
if (bOverflow)
pText = saved_pText;
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 ((m_yStart <= (pRect->bottom-size.cy)))// && (!IsBlank(strOut)))
{
TextOut(hdc, xStart, m_yStart, strOut, strOut.GetLength());
if (*pText || bReturnSeen)
m_yStart += size.cy;
}
// prepare for next line - clear out the error term
SetTextJustification(hdc, 0, 0);
strOut.Empty();
}
else // new word will fit
{
}
}
nWord--; // discount last space at end of line
// if end of text and no space characters, set pEnd to end
// prepare for next line - clear out the error term
SetTextJustification(hdc, 0, 0);
strOut.Empty();
} while (*pText && (m_yStart < pRect->bottom));
if (m_yStart > (pRect->bottom-size.cy))
pRect->top = pRect->bottom;
else
pRect->top = m_yStart;
return xLast;
}
///////////////////////////////////////////////////////////////////////////////
// GetNextWord
CString CXHTMLStatic::GetNextWord(TCHAR **ppText, BOOL * pbReturnSeen)
{
CString strWord;
strWord = _T("");
TCHAR *pText = *ppText;
*pbReturnSeen = FALSE;
// skip to next word
for(;;)
{
if (*pText == _T('\0'))
break;
// skip \r
if (*pText == _T('\r'))
pText++;
// \n = new line
if (*pText == _T('\n'))
{
strWord += _T(' ');
pText++;
*pbReturnSeen = TRUE;
break;
}
TCHAR c = *pText;
// process character entities
if (c == _T('\001'))
{
c = *++pText;
c = GetCharEntity(c);
}
strWord += c;
if (*pText++ == _T(' '))
break;
}
*ppText = pText;
return strWord;
}
///////////////////////////////////////////////////////////////////////////////
// PreSubclassWindow
void CXHTMLStatic::PreSubclassWindow()
{
// We want to get mouse clicks via STN_CLICKED
DWORD dwStyle = GetStyle();
::SetWindowLong(GetSafeHwnd(), GWL_STYLE, dwStyle | SS_NOTIFY);
CStatic::PreSubclassWindow();
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 CXHTMLStatic::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();
}
CStatic::OnTimer(nIDEvent);
}
///////////////////////////////////////////////////////////////////////////////
// OnSetCursor
BOOL CXHTMLStatic::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (!m_bOnHyperlink)
return CStatic::OnSetCursor(pWnd, nHitTest, message);
else
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// OnClicked
void CXHTMLStatic::OnClicked()
{
CPoint point;
::GetCursorPos(&point);
BOOL bOnHyperlink = FALSE;
int n = m_AnchorRectPtrs.GetSize();
if (n == 0)
return;
int i = 0;
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
BOOL CXHTMLStatic::GotoURL(LPCTSTR url, int showcmd)
{
BOOL bRet = FALSE;
ASSERT(url);
ASSERT(url[0] != _T('\0'));
TCHAR key[MAX_PATH * 2];
// check if this is "app:" protocol
int nAppSize = 0;
if (_tcsnicmp(url, _T("APP:"), 4) == 0)
nAppSize = 4;
else if (_tcsnicmp(url, _T("\"APP:"), 5) == 0)
nAppSize = 5;
if (nAppSize)
{
bRet = ProcessAppCommand(&url[nAppSize]);
}
else
{
// not "app" - assume http: or mailto:
// 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)
{
//fabio_2005
#if _MSC_VER >= 1400
_tcscat_s(key, _T("\\shell\\open\\command"));
#else
_tcscat(key, _T("\\shell\\open\\command"));
#endif
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
//fabio_2005
#if _MSC_VER >= 1400
_tcscat_s(pos,1, _T(" "));
_tcscat_s(pos,lstrlen( url), url);
#else
_tcscat(pos, _T(" "));
_tcscat(pos, url);
#endif
result = (HINSTANCE) WinExec((LPSTR)key,showcmd);
}
}
}
bRet = result > (HINSTANCE) HINSTANCE_ERROR;
}
return bRet;
}
///////////////////////////////////////////////////////////////////////////////
// ProcessAppCommand
BOOL CXHTMLStatic::ProcessAppCommand(LPCTSTR lpszCommand)
{
TRACE(_T("in CXHTMLStatic::ProcessAppCommand: %s\n"), lpszCommand);
BOOL bRet = FALSE;
CString strCommand(lpszCommand);
if (strCommand[0] == _T('"'))
strCommand = strCommand.Mid(1);
if (strCommand[strCommand.GetLength()-1] == _T('"'))
strCommand = strCommand.Left(strCommand.GetLength()-1);
if ((m_nAppCommands > 0) && (m_paAppCommands != NULL))
{
for (int i = 0; i < m_nAppCommands; i++)
{
if (_tcsicmp(m_paAppCommands[i].pszCommand, strCommand) == 0)
{
TRACE(_T("found app command %s\n"), strCommand);
if (m_paAppCommands[i].hWnd &&
::IsWindow(m_paAppCommands[i].hWnd))
{
::SendMessage(m_paAppCommands[i].hWnd,
m_paAppCommands[i].uMessage,
m_paAppCommands[i].wParam,
0);
bRet = TRUE;
break;
}
}
}
}
return bRet;
}
///////////////////////////////////////////////////////////////////////////////
// GetRegKey
LONG CXHTMLStatic::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 CXHTMLStatic::OnDestroy()
{
if (m_bHyperlinkTimer)
KillTimer(1);
m_bHyperlinkTimer = FALSE;
CStatic::OnDestroy();
}
///////////////////////////////////////////////////////////////////////////////
// SetWindowText
void CXHTMLStatic::SetWindowText(LPCTSTR lpszString)
{
Init();
CStatic::SetWindowText(lpszString);
RedrawWindow();
}
LRESULT CXHTMLStatic::OnShowAccelerators(WPARAM /*wp*/, LPARAM /*lp*/)
{
LRESULT lr = Default();
RedrawWindow();
return lr;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?