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

📄 bcgpeditctrl.cpp

📁 远程网络监视程序的源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	SetCaret (m_nCurrOffset, FALSE);

	if (m_nTotalLines - m_nHiddenLines < m_rectText.Height () / m_nLineHeight &&
		m_nTopVisibleOffset > 0)
	{
		OnScroll (SB_VERT, SB_THUMBPOSITION, 0);
	}
	else
	{
		SetScrollPos (SB_VERT, m_nScrollOffsetVert, FALSE);
	}
	
	SetScrollPos (SB_HORZ, m_nScrollOffsetHorz, FALSE);
}
//*****************************************************************************
int CBCGPEditCtrl::HitTest (CPoint& pt, BOOL bNormalize, BOOL bIgnoreTextBounds)
{
	if (!m_rectText.PtInRect (pt) && !bIgnoreTextBounds)
	{
		return -1;
	}

	int x = -1;
	int y = m_rectText.top; // - m_nScrollOffsetVert * m_nLineHeight;
	int nOffset = 0;

	CClientDC dc (this);
	CFont* pOldFont = SelectFont (&dc);

	// --------------
	// Calculate row:
	// --------------
	int nRow = max (0, (pt.y + m_nScrollOffsetVert * m_nLineHeight) / m_nLineHeight);
	int nColumn = 0;
	int iRowOffset = m_nTopVisibleOffset;
	
	int nStrartFrom = m_nScrollOffsetVert;
	if (pt.y < 0)
	{
		iRowOffset = GetRowStart (nRow, TRUE);
		nStrartFrom = nRow;
	}

	for (int i = nStrartFrom; i <= nRow; i++)
	{
		int iNextRow = m_strBuffer.Find (_T('\n'), iRowOffset);
		while (iNextRow != -1 && FindCollapsedBlock (iNextRow) != NULL) // skip hidden text
		{
			iNextRow = m_strBuffer.Find (_T('\n'), iNextRow + 1);
		}

		if (i == nRow)
		{
			// -----------------
			// Calculate column:
			// -----------------
			CString strRow;
			if (iNextRow < 0)
			{
				strRow = m_strBuffer.Mid (iRowOffset);
			}
			else
			{
				strRow = m_strBuffer.Mid (iRowOffset, iNextRow - iRowOffset);
			}

			int nXRight = m_rectText.left + GetStringExtent (&dc, strRow, strRow.GetLength ()).cx;

			if (pt.x >= nXRight)
			{
				x = nXRight;
				nOffset = (iNextRow < 0) ? m_strBuffer.GetLength () : iNextRow;
				nColumn = iNextRow - iRowOffset; 
			}
			else
			{
				int cxPrev = m_rectText.left;

				int nScrollOffsetPix = m_nScrollOffsetHorz * m_nMaxCharWidth; //GetHorzRowExtent (&dc, iRowOffset);
				int nOffsetInRowPix = 0;

				nOffset = -1;		

				int nStartOffsetToCheck = 0;	
				int nExtent = 0; //GetStringExtent (&dc, (LPCTSTR) strRow, nStartOffsetToCheck).cx;

				for (int iIdx = nStartOffsetToCheck; iIdx < strRow.GetLength (); iIdx++)
				{
					TCHAR chNext = strRow [iIdx];
					int nSymExtraLen = 0;
					int nCharWidth = 0;
					
					CBCGPOutlineBaseNode* pHiddenText = FindCollapsedBlock (iRowOffset + iIdx);
					if (pHiddenText != NULL)
					{
						OnCalcOutlineSymbol (&dc, CPoint (m_rectText.left + nExtent, y), pHiddenText);
						nCharWidth = pHiddenText->m_rectTool.Width ();
						nSymExtraLen = pHiddenText->m_nEnd - pHiddenText->m_nStart;
					}
					else if (m_bEnableSymSupport)
					{
						BCGP_EDIT_SYM_DEF symDef;
						if (LookUpSymbol (strRow, iIdx, strRow.GetLength (), chNext, symDef, nSymExtraLen))
						{
							IMAGEINFO imgInfo;
							m_pSymbolsImgList->GetImageInfo (symDef.m_nIndex, &imgInfo);
							nCharWidth = imgInfo.rcImage.right - imgInfo.rcImage.left;
						}
					}
					if (nCharWidth == 0 && !m_mapCharWidth.Lookup (chNext, nCharWidth))
					{
						nCharWidth = GetStringExtent (&dc, CString (chNext), 1).cx;
						m_mapCharWidth.SetAt (chNext, nCharWidth);
					}

					if (pHiddenText != NULL)
					{
					}
					else if (chNext == _T ('\t'))
					{
						int nRestOfTab = m_nTabSize - nColumn % m_nTabSize;
						
						nColumn += nRestOfTab; 
						nCharWidth = nRestOfTab * nCharWidth / m_nTabSize;
					}
					else
					{
						nColumn++;
					}

					nExtent += nCharWidth;

					int cx = m_rectText.left + nExtent;
					int nAddition = (iIdx == strRow.GetLength () - 1) ? 0 : nCharWidth / 2;

					if (cx >= pt.x + nScrollOffsetPix + nAddition)
					{
						x = cxPrev;
						nOffset = iRowOffset + iIdx;
						nOffsetInRowPix = cx - m_rectText.left;
						break;
					}
					else if (iIdx == (strRow.GetLength () - 1)) 
                    { 
                            x = cx; 
                            nOffset = iRowOffset + strRow.GetLength(); 
                            break; 
                    } 


					cxPrev = cx;
					iIdx += nSymExtraLen;
				}

				if (nOffset == -1)
				{
					nOffset = iRowOffset + iIdx;
				}

				nColumn++;
			}

			break;
		}

		iRowOffset = iNextRow + 1;
		y += m_nLineHeight;

		if (iNextRow == -1 && x == -1)
		{
			x = m_rectText.left;
			y -= m_nLineHeight;
			nOffset = m_strBuffer.GetLength ();
			break;
		}
	}

	dc.SelectObject (pOldFont);

	if (bNormalize)
	{
		pt.x = x;
		pt.y = y;
	}

	OnSetCaret	();
	return nOffset;
}
//******************************************************************************
BOOL CBCGPEditCtrl::SetCaret (int nOffset, BOOL bScrollToCaret, BOOL bRedrawOnScroll)
{
	CPoint pt;
	CPoint ptRowColumn;

	if (!OffsetToPoint (nOffset, pt, &ptRowColumn))
	{
		return FALSE;
	}

	m_nCurrOffset = nOffset;
	m_ptCaret = pt;


	BOOL bScrollRequired = FALSE;
	BOOL bCaretSet = FALSE;
	
	if (bScrollToCaret)
	{
		int nDeltaX = 0;
		
		if (m_ptCaret.x < m_rectText.left + m_nMaxCharWidth)
		{
			nDeltaX = ((m_ptCaret.x - m_rectText.left) / m_nMaxCharWidth) - m_nScrollLeftOffset;
		}
		else if (m_ptCaret.x >= m_rectText.right - m_nMaxCharWidth)
		{
			int nScrollOffset = m_rectText.Width () / m_nMaxCharWidth * m_nScrollRightOffset / 100;
			if (nScrollOffset < 1)
			{
				nScrollOffset = 1;
			}
			nDeltaX = ((m_ptCaret.x - m_rectText.right) / m_nMaxCharWidth) + nScrollOffset;
		}

		if (nDeltaX != 0)
		{
			int nScrollValue = m_nScrollOffsetHorz + nDeltaX;
			if (nDeltaX < 0)
			{
				int nRowEndOffset = 0;
				int nNumColumnsInRow = GetNumOfColumnsInRowByOffset (nOffset, nRowEndOffset, TRUE);
				if (nScrollValue > nNumColumnsInRow - m_nScrollLeftOffset)
				{
					nScrollValue = max (0, nNumColumnsInRow - m_nScrollLeftOffset);
				}
			}
			bScrollRequired = OnScroll (SB_HORZ, SB_THUMBPOSITION, nScrollValue);
			OffsetToPoint (nOffset, pt, &ptRowColumn);
			m_nCurrOffset = nOffset;
			m_ptCaret = pt;
			SetCaretPos (m_ptCaret);
			OnSetCaret	();
			bCaretSet = TRUE;
		}

		int nDeltaY = 0;
		if (m_ptCaret.y < m_rectText.top + m_nLineHeight)
		{
			nDeltaY = ((m_ptCaret.y - m_rectText.top) / m_nLineHeight);
		}
		else if (m_ptCaret.y >= m_rectText.bottom - m_nLineHeight * 2)
		{
			nDeltaY = ((m_ptCaret.y - m_rectText.bottom + m_nLineHeight * 2) / m_nLineHeight);
		}

		if (nDeltaY != 0)
		{
			bScrollRequired = OnScroll (SB_VERT, SB_THUMBPOSITION, m_nScrollOffsetVert + nDeltaY);
			OffsetToPoint (nOffset, pt, &ptRowColumn);
			m_nCurrOffset = nOffset;
			m_ptCaret = pt;
			SetCaretPos (m_ptCaret);
			OnSetCaret	();
			bCaretSet = TRUE;
		}
	}

	m_nCurRow	 = RowFromOffset (m_nCurrOffset);//ptRowColumn.y;
	m_nCurColumn = GetColumnFromOffset (m_nCurrOffset, FALSE);

	if (!bCaretSet && bScrollToCaret)
	{
		SetCaretPos (m_ptCaret);
		OnSetCaret	();
	}

	if (bRedrawOnScroll && bScrollRequired)
	{
		RedrawWindow ();
	}

	return TRUE;
}
//***************************************************************************************
int CBCGPEditCtrl::GetColumnFromOffset (int nOffset, BOOL bSkipHidden) const
{
	int nRowStart = GetRowStartByOffset (nOffset, bSkipHidden);
	
	if (m_bKeepTabs)
	{
		int nColumn = 0;
		int nNumChars = nOffset - nRowStart;
		LPCTSTR lpcszRowStart = ((LPCTSTR) m_strBuffer) + nRowStart;
		for (int i = 0; i < nNumChars; i++)
		{
			CBCGPOutlineBaseNode* pHiddenText = NULL;
			pHiddenText = bSkipHidden ? FindCollapsedBlock (nRowStart + i) : NULL;
			if (pHiddenText == NULL)
			{
				TCHAR chNext = lpcszRowStart [i];
				if (chNext == _T ('\t'))
				{
					int nRestOfTab = m_nTabSize - nColumn % m_nTabSize;
					nColumn += nRestOfTab; 
				}
				else
				{
					nColumn++;
				}
			}
			else
			{
				nColumn += pHiddenText->m_strReplace.GetLength ();
				i += pHiddenText->m_nEnd - (nRowStart + i); // skip the rest of the hidden text
			}
		}
		return nColumn;
	}
	
	else if (bSkipHidden)
	{
		int nColumn = 0;
		for (int i = nRowStart; i < nOffset; )
		{
			CBCGPOutlineBaseNode* pHiddenText = FindCollapsedBlockInRange (i, nOffset, TRUE);
			if (pHiddenText != NULL)
			{
				ASSERT_VALID (pHiddenText);

				nColumn += pHiddenText->m_nStart - i;
				
				if (nOffset == pHiddenText->m_nStart)
				{
					break;
				}

				nColumn += pHiddenText->m_strReplace.GetLength ();
				i += max (pHiddenText->m_nEnd - i + 1, 1); // skip the rest of the hidden text
			}
			else
			{
				nColumn += nOffset - i;
				break;
			}
		}
		return nColumn;
	}

	return nOffset - nRowStart;
}
//******************************************************************************
void CBCGPEditCtrl::OnChangeFont (CDC* pDC)
{
	CClientDC dc (this);

	if (pDC == NULL)
	{
		pDC = &dc;
	}

	CFont* pOldFont = SelectFont (pDC);

	TEXTMETRIC tm;
	pDC->GetTextMetrics (&tm);

	if (m_pSymbolsImgList != NULL)
	{
		IMAGEINFO imgInfo;
		memset (&imgInfo, 0, sizeof (IMAGEINFO));
		if (m_pSymbolsImgList->GetImageInfo (0, &imgInfo))
		{
			int nImgHeight = imgInfo.rcImage.bottom - imgInfo.rcImage.top;
			if (nImgHeight > m_nLineHeight)
			{
				m_nLineVertSpacing += nImgHeight - m_nLineHeight;
			}
		}
	}

	m_nLineHeight = tm.tmHeight + m_nLineVertSpacing;
	m_nMaxCharWidth = tm.tmMaxCharWidth;
	m_nAveCharWidth = tm.tmAveCharWidth;

	pDC->SelectObject (pOldFont);

	m_mapCharWidth.RemoveAll ();

	//------------------
	// Initialize caret:
	//------------------
	::DestroyCaret ();

	CSize sizeCaret = GetCaretSize ();
	::CreateCaret (GetSafeHwnd (), NULL, sizeCaret.cx, sizeCaret.cy);

	UpdateScrollBars ();

	if (!m_bReadOnly)
	{
		SetCaret (m_nCurrOffset);
		ShowCaret ();
	}
}
//******************************************************************************
BOOL CBCGPEditCtrl::OffsetToPoint (int nOffset, CPoint& pt, LPPOINT ptRowColumn, LPINT pnScrollOffset)
{
	ASSERT_VALID (this);

	nOffset = min (max (nOffset, 0), m_strBuffer.GetLength ());

	CClientDC dc (this);
	CFont* pOldFont = SelectFont (&dc);

	int nRow = -1;
	int iRowOffset = 0;
	int nLowBound = 0;

	if (nOffset >= m_nTopVisibleOffset)
	{
		nLowBound = m_nTopVisibleOffset;
	}
	
	// --------------
	// Calculate row:
	// --------------
	CBCGPOutlineBaseNode* pHiddenText = NULL;
	if (nOffset - 1 >= nLowBound)
	{
		pHiddenText = FindCollapsedBlockInRange (nLowBound, nOffset - 1, FALSE);
	}
	for (int i = nOffset - 1; i >= nLowBound; )
	{
		if (pHiddenText != NULL && pHiddenText->m_nEnd >= i)
		{
			// skip hidden text
			i -= max (i - pHiddenText->m_nStart + 1, 1);

			if (i >= nLowBound)
			{
				pHiddenText = FindCollapsedBlockInRange (nLowBound, i, FALSE);
			}
		}
		else
		{
			if (m_strBuffer [i] == _T('\n'))
			{
				if (nRow == -1)
				{
					nRow = 1;
				}
				else
				{
					nRow ++;
				}
			}

			i--;
		}
	}

	if (nRow == -1)
	{
		nRow = 0;
	}

	if (nOffset >= m_nTopVisibleOffset)
	{
		nRow += m_nScrollOffsetVert;
	}

	// -----------------
	// Calculate column:
	// -----------------
	iRowOffset = GetRowStartByOffset (nOffset, TRUE);
	int nScrolledExtent = m_nScrollOffsetHorz * m_nMaxCharWidth;

	int nStringExtent = 0;
	for (i = iRowOffset; i < nOffset; )
	{
		CBCGPOutlineBaseNode* pHiddenText = FindCollapsedBlockInRange (i, nOffset, TRUE);
		if (pHiddenText != NULL)
		{
			ASSERT_VALID (pHiddenText);

			nStringExtent += GetStringExtent (&dc, (LPCTSTR) m_strBuffer + i, pHiddenText->m_nStart - i).cx;

			if (nOffset == pHiddenText->m_nStart)
			{
				break;
			}

			OnCalcOutlineSymbol (&dc, pHiddenText->m_rectTool.TopLeft (), pHiddenText);
			nStringExtent += pHiddenText->m_rectTool.Width ();
			
			i += max (pHiddenText->m_nEnd - i + 1, 1);
		}
		else
		{
			nStringExtent += GetStringExtent (&dc, (LPCTSTR) m_strBuffer + i, nOffset - i).cx;
			break;
		}
	}

	pt.x = m_rectText.left + nStringExtent - nScrolledExtent - 1;

	pt.x = max (pt.x, m_rectText.left);

	if (pnScrollOffset != NULL)
	{
		*pnScrollOffset = 0;
	
		if (pt.x < m_rectText.left)
		{
			for (int i = nOffset - iRowOffset; 
				i < m_strBuffer.GetLength () && m_strBuffer [i] != _T('\n'); i++)
			{
				(*pnScrollOffset)++;
			}
		}
		else if (pt.x >= m_rectText.right)
		{
		}
	}

	pt.y = m_rectText.top + (nRow - m_nScrollOffsetVert) * m_nLineHeight;

	dc.SelectObject (pOldFont);

	if (ptRowColumn != NULL)
	{
		ptRowColumn->x = GetColumnFromOffset (nOffset, TRUE);
		ptRowColumn->y = nRow;
	}

	return TRUE;
}
//**************************************************************************************
BOOL CBCGPEditCtrl::Left (BOOL bRedrawOnScroll)
{
	if (m_nCurrOffset == 0)
	{
		OnFailedOperation (g_dwOpLeft);
		return FALSE;
	}

	int nCharCount = 1;
	CBCGPOutlineBaseNode* pHiddenText = FindCollapsedBlock (m_nCurrOffset - 1);
	if (pHiddenText != NULL)
	{
		nCharCount += pHiddenText->m_nEnd - pHiddenText->m_nStart;
	}
	else if (m_bEnableSymSupport && m_nCurrOffset > 0)
	{

⌨️ 快捷键说明

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