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

📄 hexeditbase.cpp

📁 EZ-USB 开发板完整资料
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	CRect cRect(m_tPaintDetails.cPaintingRect);
	cRect.left-=2;
	cRect.right+=2;
	cRegn.CreateRectRgnIndirect((LPCRECT)cRect);
	cMemDC.SelectClipRgn(&cRegn);

	if(m_bShowAddress) {
		PaintAddresses(cMemDC);
	}
	PaintHexData(cMemDC);
	if(m_bShowAscii) {
		PaintAsciiData(cMemDC);
	}

	cPaintDC.BitBlt(0, 0, cClientRect.right, cClientRect.bottom, &cMemDC, 0, 0, SRCCOPY);
	if(pOldFont != NULL) {
		cMemDC.SelectObject(pOldFont);
	}
	if(pOldBitmap != NULL) {
		cMemDC.SelectObject(pOldBitmap);
	}
}

void CHexEditBase::MakeVisible(UINT nBegin, UINT nEnd, bool bUpdate)
{
	ASSERT(nBegin<=nEnd);

	UINT nAdrBeg = m_nScrollPostionY * m_tPaintDetails.nBytesPerRow;
	UINT nFullBytesPerScreen = m_tPaintDetails.nFullVisibleLines * m_tPaintDetails.nBytesPerRow;
	UINT nAdrEnd = nAdrBeg + nFullBytesPerScreen;
	UINT nLength = nEnd - nBegin;
	if( (nBegin > nAdrBeg) || (nEnd < nAdrEnd) ) {
		// don't do anything when it's simply not possible to see everything and
		// we already see one ful page.
		if(nLength > nFullBytesPerScreen) {
			if(nAdrBeg < nBegin) {
				SetScrollPositionY(nBegin/m_tPaintDetails.nBytesPerRow, false);
			} else if (nAdrEnd > nEnd) {
				SetScrollPositionY((nEnd-nFullBytesPerScreen+m_tPaintDetails.nBytesPerRow)/m_tPaintDetails.nBytesPerRow, false); 
			}
		} else {
			if(nAdrBeg > nBegin) {
				SetScrollPositionY(nBegin/m_tPaintDetails.nBytesPerRow, false);
			} else if (nAdrEnd < nEnd) {
				SetScrollPositionY((nEnd-nFullBytesPerScreen+m_tPaintDetails.nBytesPerRow)/m_tPaintDetails.nBytesPerRow, false); 
			}
		}
	}

	int iLineX = (int)((nBegin%m_tPaintDetails.nBytesPerRow)*3*m_tPaintDetails.nCharacterWidth + m_tPaintDetails.nHexPos + m_tPaintDetails.cPaintingRect.left) - (int)m_nScrollPostionX;
	int iLineX2 = (int)((2+(nEnd%m_tPaintDetails.nBytesPerRow)*3)*m_tPaintDetails.nCharacterWidth + m_tPaintDetails.nHexPos + m_tPaintDetails.cPaintingRect.left) - (int)m_nScrollPostionX;
	if(iLineX > iLineX2) {
		int iTemp = iLineX;
		iLineX = iLineX2;
		iLineX2 = iTemp;
	}
	if( (iLineX <= m_tPaintDetails.cPaintingRect.left) && (iLineX2 >= m_tPaintDetails.cPaintingRect.right) ) {
		// nothing to do here...
	} else if(iLineX < m_tPaintDetails.cPaintingRect.left) {
		SetScrollPositionX(m_nScrollPostionX + iLineX - m_tPaintDetails.cPaintingRect.left, false);
	} else if(iLineX2 >= m_tPaintDetails.cPaintingRect.right) {
		SetScrollPositionX(m_nScrollPostionX + iLineX2 - m_tPaintDetails.cPaintingRect.Width(), false);
	}

	if(bUpdate && ::IsWindow(m_hWnd)) {
		Invalidate();
	}
}

void CHexEditBase::SetScrollbarRanges()
{
	if(!(GetStyle() & ES_MULTILINE)) {
		return;
	}

	SCROLLINFO tScrollInfo;
	memset(&tScrollInfo, 0, sizeof(SCROLLINFO));
	tScrollInfo.cbSize = sizeof(SCROLLINFO);
	if(m_nScrollRangeY > 0) {
		ShowScrollBar(SB_VERT, TRUE);
		EnableScrollBar(SB_VERT);
		tScrollInfo.fMask = SIF_ALL ;
		tScrollInfo.nPage = m_tPaintDetails.nFullVisibleLines;
		tScrollInfo.nMax = m_nScrollRangeY + tScrollInfo.nPage - 1;
		if(m_nScrollPostionY > m_nScrollRangeY) {
			m_nScrollPostionY = m_nScrollRangeY;
		}
		tScrollInfo.nPos = m_nScrollPostionY;
		SetScrollInfo(SB_VERT, &tScrollInfo, TRUE);
	} else {
		ShowScrollBar(SB_VERT, FALSE);
	}
	if(m_nScrollRangeX > 0) {
		EnableScrollBar(SB_HORZ);
		ShowScrollBar(SB_HORZ, TRUE);
		tScrollInfo.fMask = SIF_ALL ;
		tScrollInfo.nPage = m_tPaintDetails.cPaintingRect.Width();
		tScrollInfo.nMax = m_nScrollRangeX + tScrollInfo.nPage - 1;
		if(m_nScrollPostionX > m_nScrollRangeX) {
			m_nScrollPostionX = m_nScrollRangeX;
		}
		tScrollInfo.nPos = m_nScrollPostionX;
		SetScrollInfo(SB_HORZ, &tScrollInfo, TRUE);
	} else {
		ShowScrollBar(SB_HORZ, FALSE);
	}
}

void CHexEditBase::OnSetFocus(CWnd*) 
{	
	if(m_pData != NULL) {
		SetEditCaretPos(m_nCurrentAddress, m_bHighBits);
		Invalidate();
	}
}

void CHexEditBase::OnKillFocus(CWnd* pNewWnd) 
{
	DestoyEditCaret();
	CWnd::OnKillFocus(pNewWnd);
	Invalidate();
}

void CHexEditBase::OnSize(UINT nType, int cx, int cy) 
{
	CWnd::OnSize(nType, cx, cy);
	CalculatePaintingDetails(CClientDC(this));
	SetEditCaretPos(m_nCurrentAddress, m_bHighBits);
	SetScrollbarRanges();
}

void CHexEditBase::MoveScrollPostionY(int iDelta, bool bUpdate)
{
	if(iDelta > 0) {
		SetScrollPositionY(m_nScrollPostionY+iDelta, bUpdate);
	} else {
		int iPositon = (int)m_nScrollPostionY;
		iPositon -= (-iDelta);
		if(iPositon < 0) {
			iPositon = 0;
		}
		SetScrollPositionY((UINT)iPositon, bUpdate);
	}
}

void CHexEditBase::MoveScrollPostionX(int iDelta, bool bUpdate)
{
	if(iDelta > 0) {
		SetScrollPositionX(m_nScrollPostionX+iDelta, bUpdate);
	} else {
		int iPositon = (int)m_nScrollPostionX;
		iPositon -= (-iDelta);
		if(iPositon < 0) {
			iPositon = 0;
		}
		SetScrollPositionX((UINT)iPositon, bUpdate);
	}
}

void CHexEditBase::GetAddressFromPoint(const CPoint& cPt, UINT& nAddress, bool& bHighBits)
{	
	CPoint cPoint(cPt);
	cPoint.x += m_nScrollPostionX;
	cPoint.y -= m_tPaintDetails.cPaintingRect.top;
	if((GetStyle() & ES_MULTILINE)) {
		cPoint.x += (m_tPaintDetails.nCharacterWidth>>1) - CONTROL_BORDER_SPACE ;
	} else {
		cPoint.x += (m_tPaintDetails.nCharacterWidth>>1);
	}
	if(cPoint.y < 0) {
		cPoint.y = 0;
	} else if(cPoint.y > (int)(m_tPaintDetails.nVisibleLines*m_tPaintDetails.nLineHeight)) {
		cPoint.y = m_tPaintDetails.nVisibleLines*m_tPaintDetails.nLineHeight;
	}
	if((int)cPoint.x < (int)m_tPaintDetails.nHexPos) {
		cPoint.x = m_tPaintDetails.nHexPos;
	} else if(cPoint.x > (int)(m_tPaintDetails.nHexPos + m_tPaintDetails.nHexLen - DATA_ASCII_SPACE)) {
		cPoint.x = m_tPaintDetails.nHexPos + m_tPaintDetails.nHexLen - DATA_ASCII_SPACE;
	}
	cPoint.x -= m_tPaintDetails.nHexPos;
	UINT nRow = cPoint.y / m_tPaintDetails.nLineHeight;
	UINT nCharColumn  = cPoint.x / m_tPaintDetails.nCharacterWidth;
	UINT nColumn = nCharColumn / 3;
	bHighBits = nCharColumn % 3 == 0;
	nAddress = nColumn + (nRow + m_nScrollPostionY) * m_tPaintDetails.nBytesPerRow;
	if(nAddress >= m_nLength) {
		nAddress = m_nLength - 1;
		bHighBits = false;
	}
}

BOOL CHexEditBase::OnMouseWheel(UINT nFlags, short zDelta, CPoint)
{
	MoveScrollPostionY(-(zDelta/WHEEL_DELTA), true);
	return TRUE;
}

void CHexEditBase::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar*) 
{
	if(m_pData == NULL) {
		return;
	}

	switch(nSBCode) {
	case SB_LINEDOWN:
		MoveScrollPostionY(1, true);
		break;
	
	case SB_LINEUP:
		MoveScrollPostionY(-1, true);
		break;
	
	case SB_PAGEDOWN:
		MoveScrollPostionY(m_tPaintDetails.nFullVisibleLines, true);
		break;

	case SB_PAGEUP:
		MoveScrollPostionY(-(int)m_tPaintDetails.nFullVisibleLines, true);
		break;

	case SB_THUMBTRACK:
		// Windows only allows 16Bit track-positions in the callback message.
		// MFC hides this by providing a 32-bit value (nobody expects to
		// be an invalid value) which is unfortunately casted from a 16Bit value.
		// -- MSDN gives a hint (in the API-documentation) about this problem
		// -- and a solution as well. We should use GetScrollInfo here to receive
		// -- the correct 32-Bit value when our scrollrange exceeds the 16bit range
		// -- to keep it simple, I decided to always do it like this
		SCROLLINFO tScrollInfo;
		memset(&tScrollInfo, 0, sizeof(SCROLLINFO));
		if(GetScrollInfo(SB_VERT, &tScrollInfo, SIF_TRACKPOS)) {
			SetScrollPositionY(tScrollInfo.nTrackPos, true);
		}
#ifdef _DEBUG
		else {
			TRACE("CHexEditBase::OnVScroll: Error receiving trackposition while thumbtracking\n");
		}
#endif
		break;
	}
}

void CHexEditBase::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar*) 
{
	if(m_pData == NULL) {
		return;
	}

	switch(nSBCode) {
	case SB_LINEDOWN:
		MoveScrollPostionX(m_tPaintDetails.nCharacterWidth, true);
		break;
	
	case SB_LINEUP:
		MoveScrollPostionX(-(int)m_tPaintDetails.nCharacterWidth, true);
		break;
	
	case SB_PAGEDOWN:
		MoveScrollPostionX(m_tPaintDetails.cPaintingRect.Width(), true);
		break;

	case SB_PAGEUP:
		MoveScrollPostionX(-(int)m_tPaintDetails.cPaintingRect.Width(), true);
		break;

	case SB_THUMBTRACK:
		SetScrollPositionX(nPos, true);
		break;
	}
}

void CHexEditBase::SetEditCaretPos(UINT nOffset, bool bHighBits)
{	
	ASSERT(::IsWindow(m_hWnd));
	
	m_nCurrentAddress = nOffset;
	m_bHighBits = bHighBits;
		
	if((m_pData == NULL) || (m_nLength == NULL) ) {
		return;
	}	
	if(m_bRecalc) {
		CalculatePaintingDetails(CClientDC(this));
	}
	if(m_nCurrentAddress < m_nScrollPostionY*m_tPaintDetails.nBytesPerRow 
		|| (m_nCurrentAddress >= (m_nScrollPostionY + m_tPaintDetails.nVisibleLines)*m_tPaintDetails.nBytesPerRow) ) {
		// not in the visible range
		DestoyEditCaret();
		return;
	}
	if(GetFocus() != this) {
		// in case we missed once something...
		DestoyEditCaret();
		return;
	}
	UINT nRelAdr = m_nCurrentAddress - m_nScrollPostionY*m_tPaintDetails.nBytesPerRow;
	UINT nRow = nRelAdr / m_tPaintDetails.nBytesPerRow;
	UINT nColumn = nRelAdr % m_tPaintDetails.nBytesPerRow;
	UINT nCarretHeight;
	UINT nCarretWidth = m_tPaintDetails.nCharacterWidth;
	if(nRow == m_tPaintDetails.nVisibleLines-1) {
		// last row can be only half visible
		nCarretHeight = m_tPaintDetails.nLastLineHeight;
	} else {
		nCarretHeight = m_tPaintDetails.nLineHeight;
	}
	CPoint cCarretPoint(m_tPaintDetails.cPaintingRect.left 
		- m_nScrollPostionX + m_tPaintDetails.nHexPos 
		+ (nColumn * 3 + (bHighBits ? 0 : 1)) * m_tPaintDetails.nCharacterWidth,
		m_tPaintDetails.cPaintingRect.top + 1 + nRow * m_tPaintDetails.nLineHeight);
	if( (cCarretPoint.x + (short)m_tPaintDetails.nCharacterWidth <= m_tPaintDetails.cPaintingRect.left-2 ) 
		|| (cCarretPoint.x > m_tPaintDetails.cPaintingRect.right) ) {
		// we can't see it
		DestoyEditCaret();
		return;
	}
	if(cCarretPoint.x < m_tPaintDetails.cPaintingRect.left-2) {
		nCarretWidth -= m_tPaintDetails.cPaintingRect.left-2 - cCarretPoint.x;
		cCarretPoint.x = m_tPaintDetails.cPaintingRect.left-2;
	}
	if(cCarretPoint.x + (int)nCarretWidth > (int)m_tPaintDetails.cPaintingRect.right+2) {
		nCarretWidth = m_tPaintDetails.cPaintingRect.right + 2 - cCarretPoint.x;
	}

	CreateEditCaret(nCarretHeight-1, nCarretWidth);
	SetCaretPos(cCarretPoint);
	ShowCaret();
}

void CHexEditBase::CreateEditCaret(UINT nCaretHeight, UINT nCaretWidth)
{
	if(!m_bHasCaret || (nCaretHeight != m_nCurCaretHeight) 
		|| (nCaretWidth != m_nCurCaretWidth) ) {
		m_bHasCaret = true;
		m_nCurCaretHeight = nCaretHeight;
		m_nCurCaretWidth = nCaretWidth;
		CreateSolidCaret(m_nCurCaretWidth, m_nCurCaretHeight);
	}
}

void CHexEditBase::DestoyEditCaret() {
	m_bHasCaret = false;
	DestroyCaret();
}

UINT CHexEditBase::OnGetDlgCode() 
{
	return DLGC_WANTALLKEYS;
}

BOOL CHexEditBase::PreCreateWindow(CREATESTRUCT& cs) 
{
	return CWnd::PreCreateWindow(cs);
}

BOOL CHexEditBase::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
	if(!CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext)) {
		return FALSE;
	}
	return TRUE;
}

BOOL CHexEditBase::OnEraseBkgnd(CDC*) 
{
	return TRUE;
}

void CHexEditBase::OnLButtonDown(UINT, CPoint point) 
{
	SetFocus();
	if(m_pData == NULL) {
		return;
	}
	GetAddressFromPoint(point, m_nCurrentAddress, m_bHighBits);
	SetEditCaretPos(m_nCurrentAddress, m_bHighBits);
	int iDragCX = GetSystemMetrics(SM_CXDRAG);
	int iDragCY = GetSystemMetrics(SM_CYDRAG);
	m_cDragRect = CRect(point.x - (iDragCX>>1), point.y - (iDragCY>>1),
		point.x + (iDragCX>>1) + (iDragCX&1), //(we don't want to loose a pixel, when it's so small)
		point.y + (iDragCY>>1) + (iDragCY&1));

	m_nSelectingEnd = NOSECTION_VAL;
	m_nSelectionBegin = NOSECTION_VAL;
	m_nSelectingEnd = NOSECTION_VAL;
	m_nSelectingBeg = m_nCurrentAddress;
	SetCapture();
}

void CHexEditBase::OnLButtonUp(UINT, CPoint) 
{
	if(GetCapture() == this) {
		ReleaseCapture();
	}
	StopMouseRepeat(); // in case it's started, otherwise it doesn't matter either
	Invalidate();
}

void CHexEditBase::OnLButtonDblClk(UINT, CPoint point) 
{
	SetFocus();
	if(m_pData == NULL) {
		return;
	}
	GetAddressFromPoint(point, m_nCurrentAddress, m_bHighBits);
	SetEditCaretPos(m_nCurrentAddress, m_bHighBits);
	if( (m_nHighlightedBegin <= m_nCurrentAddress) 
		&& (m_nHighlightedEnd >= m_nCurrentAddress) ) {
		// well it's christmas and we can doubleclick the highlighted section ;)
		m_nSelectionEnd = m_nHighlightedEnd;
		m_nSelectionBegin = m_nHighlightedBegin;
	} else {
		// or just a whole byte
		m_nSelectionEnd = m_nCurrentAddress;
		m_nSelectionBegin = m_nCurrentAddress;
	}
	Invalidate();
}

void CHexEditBase::OnMouseMove(UINT nFlags, CPoint point) 
{
	if(m_pData == NULL) {
		return;
	}

⌨️ 快捷键说明

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