📄 hexeditbase.cpp
字号:
// position & size of the ascii-data
if(m_bShowAscii) {
m_tPaintDetails.nAsciiPos = m_tPaintDetails.nHexPos + m_tPaintDetails.nHexLen;
m_tPaintDetails.nAsciiLen = m_tPaintDetails.nBytesPerRow * m_tPaintDetails.nCharacterWidth;
iWidth = m_tPaintDetails.nAsciiPos + m_tPaintDetails.nAsciiLen;
} else {
m_tPaintDetails.nAsciiPos = 0;
m_tPaintDetails.nAsciiLen = 0;
}
if(pOldFont != NULL) {
pOldFont = cDC.SelectObject(pOldFont);
}
// calculate scrollranges
// Y-Bar
UINT nTotalLines;
nTotalLines = (m_nLength + m_tPaintDetails.nBytesPerRow-1)/m_tPaintDetails.nBytesPerRow;
if(nTotalLines > m_tPaintDetails.nFullVisibleLines) {
m_nScrollRangeY = nTotalLines - m_tPaintDetails.nFullVisibleLines;
} else {
m_nScrollRangeY = 0;
}
if(m_nScrollPostionY > m_nScrollRangeY) {
m_nScrollPostionY = m_nScrollRangeY;
}
// X-Bar
if(iWidth > m_tPaintDetails.cPaintingRect.Width()) {
m_nScrollRangeX = iWidth - m_tPaintDetails.cPaintingRect.Width();
} else {
m_nScrollRangeX = 0;
}
if(m_nScrollPostionX > m_nScrollRangeX) {
m_nScrollPostionX = m_nScrollRangeX;
}
PostMessage(UM_SETSCROLRANGE, 0 ,0);
}
void CHexEditBase::PaintAddresses(CDC& cDC)
{
ASSERT(m_tPaintDetails.nBytesPerRow > 0);
if((m_nLength < 1) || (m_pData == NULL)) {
return;
}
UINT nAdr;
UINT nEndAdr;
CString cAdrFormatString;
CRect cAdrRect(m_tPaintDetails.cPaintingRect);
_TCHAR pBuf[32];
CBrush cBkgBrush;
// create the format string
cAdrFormatString.Format(_T("%%0%uX"), m_nAdrSize);
// the Rect for painting & background
cBkgBrush.CreateSolidBrush(m_tAdrBkgCol);
cAdrRect.left += m_tPaintDetails.nAddressPos - m_nScrollPostionX;
cAdrRect.right = cAdrRect.left + m_tPaintDetails.nAddressLen - ADR_DATA_SPACE; // without border
cDC.FillRect(cAdrRect, &cBkgBrush);
cAdrRect.bottom = cAdrRect.top + m_tPaintDetails.nLineHeight;
// start & end-address
nAdr = m_nScrollPostionY * m_tPaintDetails.nBytesPerRow;
nEndAdr = nAdr + m_tPaintDetails.nVisibleLines*m_tPaintDetails.nBytesPerRow;
if(nEndAdr >= m_nLength) {
nEndAdr = m_nLength-1;
}
// paint
cDC.SetBkMode(OPAQUE);
cDC.SetTextColor(m_tAdrTxtCol);
cDC.SetBkColor(m_tAdrBkgCol);
for(; nAdr<=nEndAdr; nAdr+=m_tPaintDetails.nBytesPerRow) {
_sntprintf(pBuf, 32, (LPCTSTR)cAdrFormatString, nAdr); // slightly faster then CString::Format
cDC.DrawText(pBuf, (LPRECT)cAdrRect, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
cAdrRect.OffsetRect(0, m_tPaintDetails.nLineHeight);
}
}
UINT CHexEditBase::CreateHighlightingPolygons(const CRect& cHexRect,
UINT nBegin, UINT nEnd, POINT *pPoints)
{
ASSERT(pPoints != NULL);
ASSERT(nBegin <= nEnd);
ASSERT(m_nLength < 0x7ffff000); // to make sure we don't have an overflow
ASSERT(nBegin < m_nLength);
ASSERT(nEnd < m_nLength);
ASSERT(m_tPaintDetails.nBytesPerRow > 0);
// iBegin & iEnd represents the relative Address (relativ accoring the scrollposition)
int iBegin = nBegin - m_nScrollPostionY*m_tPaintDetails.nBytesPerRow;
int iEnd = 1+nEnd - m_nScrollPostionY*m_tPaintDetails.nBytesPerRow;
int iBeginRow = iBegin/(int)m_tPaintDetails.nBytesPerRow;
int iBeginColumn = iBegin%(int)m_tPaintDetails.nBytesPerRow;
int iEndRow = iEnd/(int)m_tPaintDetails.nBytesPerRow;
int iEndColumn = iEnd%(int)m_tPaintDetails.nBytesPerRow;
int iCount = 0;
// iBegin, iEnd may be negativ
if( (iEnd <= 0) || (iBegin >= (int)(m_tPaintDetails.nVisibleLines * m_tPaintDetails.nBytesPerRow)) ) {
return 0; // nothing to see, polygon has 0-length
}
if( (iEndRow == iBeginRow+1) && (iEndColumn == 0) ) {
iEndRow = iBeginRow;
iEndColumn = m_tPaintDetails.nBytesPerRow;
}
// first two or one point(s)
if(iBeginRow < -1) {
// we don't see the beginning (or any parts of it)
pPoints[iCount].x = (short)cHexRect.left-2;
pPoints[iCount].y = (short)cHexRect.top-1;
++iCount;
} else {
if(iBeginColumn < 0 && iBeginRow == 0) {
// must be the case where a part of the first line is not visible
iBeginColumn += m_tPaintDetails.nBytesPerRow;
iBeginRow = -1;
}
if(iBeginColumn < 0) {
iBeginColumn = 0;
}
pPoints[iCount].x = (short)cHexRect.left - 2 + iBeginColumn * 3 * m_tPaintDetails.nCharacterWidth;
pPoints[iCount].y = (short)cHexRect.top + (1+iBeginRow) * m_tPaintDetails.nLineHeight;
++iCount;
pPoints[iCount].x = pPoints[iCount-1].x;
pPoints[iCount].y = pPoints[iCount-1].y - m_tPaintDetails.nLineHeight;
++iCount;
}
if( iBeginRow == iEndRow ) {
// a simple one (two more points and we are finished
pPoints[iCount].x = (short)cHexRect.left + 2 + (iEndColumn*3 - 1) * m_tPaintDetails.nCharacterWidth;
pPoints[iCount].y = (short)cHexRect.top + iEndRow * m_tPaintDetails.nLineHeight;
++iCount;
pPoints[iCount].x = pPoints[iCount-1].x;
pPoints[iCount].y = pPoints[iCount-1].y + m_tPaintDetails.nLineHeight;
++iCount;
} else {
// iEndRow > iBeginRow
pPoints[iCount].x = (short)cHexRect.right + 1;
pPoints[iCount].y = iCount > 1 ? pPoints[1].y : pPoints[0].y;
++iCount;
pPoints[iCount].x = (short)cHexRect.right + 1;
pPoints[iCount].y = (short)cHexRect.top + iEndRow*m_tPaintDetails.nLineHeight;
++iCount;
if(iEndColumn>0) {
pPoints[iCount].x = (short)cHexRect.left + 2 + (iEndColumn*3 - 1) * m_tPaintDetails.nCharacterWidth;
pPoints[iCount].y = pPoints[iCount-1].y;
++iCount;
pPoints[iCount].x = pPoints[iCount-1].x;
pPoints[iCount].y = pPoints[iCount-1].y + m_tPaintDetails.nLineHeight;
++iCount;
}
pPoints[iCount].x = (short)cHexRect.left - 2;
pPoints[iCount].y = pPoints[iCount-1].y;
++iCount;
pPoints[iCount].x = (short)cHexRect.left - 2;
pPoints[iCount].y = pPoints[0].y;
++iCount;
}
ASSERT(iCount <= MAX_HIGHLIGHT_POLYPOINTS);
return iCount;
}
void CHexEditBase::PaintHexData(CDC& cDC)
{
ASSERT(m_tPaintDetails.nBytesPerRow > 0);
ASSERT(m_tPaintDetails.nBytesPerRow*3 < 1021);
if((m_nLength < 1) || (m_pData == NULL)) {
return;
}
UINT nAdr;
UINT nEndAdr;
UINT nSelectionCount=0;
char pBuf[1024];
char *pBufPtr;
char *pSelectionBufPtrBegin;
char *pSelectionBufPtrEnd;
char *pHighlightedBufPtrBegin;
char *pHighlightedBufPtrEnd;
BYTE *pDataPtr;
BYTE *pEndDataPtr;
BYTE *pEndLineDataPtr;
BYTE *pSelectionPtrBegin;
BYTE *pSelectionPtrEnd;
BYTE *pHighlightedPtrBegin;
BYTE *pHighlightedPtrEnd;
CRect cHexRect(m_tPaintDetails.cPaintingRect);
CBrush cBkgBrush;
CBrush *pOldBrush = NULL;
CPen *pOldPen;
POINT pHighlightPolygon[MAX_HIGHLIGHT_POLYPOINTS];
// prepare the buffer for the formated hex-data
memset(pBuf, ' ', m_tPaintDetails.nBytesPerRow*3); // fill with spaces
pBuf[m_tPaintDetails.nBytesPerRow*3-1] = '\0'; // zero-terminate
// the Rect for painting & background
cBkgBrush.CreateSolidBrush(m_tHexBkgCol);
cHexRect.left += m_tPaintDetails.nHexPos - m_nScrollPostionX;
cHexRect.right = cHexRect.left + m_tPaintDetails.nHexLen - DATA_ASCII_SPACE;
cDC.FillRect(cHexRect, &cBkgBrush);
cHexRect.bottom = cHexRect.top + m_tPaintDetails.nLineHeight;
// highlighting section (only background and frame)
if( (m_nHighlightedBegin != NOSECTION_VAL) && (m_nHighlightedEnd != NOSECTION_VAL) ) {
nSelectionCount = CreateHighlightingPolygons(cHexRect, m_nHighlightedBegin, m_nHighlightedEnd, pHighlightPolygon);
CBrush cBrush(m_tHighlightBkgCol);
CPen cPen(PS_SOLID, 1, m_tHighlightFrameCol);
pOldBrush = cDC.SelectObject(&cBrush);
pOldPen = cDC.SelectObject(&cPen);
cDC.Polygon(pHighlightPolygon, nSelectionCount);
if(pOldBrush != NULL) {
cDC.SelectObject(pOldBrush);
}
if(pOldPen != NULL) {
cDC.SelectObject(pOldPen);
}
pHighlightedPtrBegin = m_pData + m_nHighlightedBegin;
pHighlightedPtrEnd = m_pData + m_nHighlightedEnd;
} else {
pHighlightedPtrBegin = m_pData + m_nHighlightedBegin;
pHighlightedPtrEnd = m_pData + m_nHighlightedEnd;
}
// selection (pointers)
if( (m_nSelectionBegin != NOSECTION_VAL) && (m_nSelectionEnd != NOSECTION_VAL) ) {
pSelectionPtrBegin = m_pData + m_nSelectionBegin;
pSelectionPtrEnd = m_pData + m_nSelectionEnd;
} else {
pSelectionPtrBegin = NULL;
pSelectionPtrEnd = NULL;
}
// start & end-address (& pointers)
nAdr = m_nScrollPostionY * m_tPaintDetails.nBytesPerRow;
nEndAdr = nAdr + m_tPaintDetails.nVisibleLines*m_tPaintDetails.nBytesPerRow;
if(nEndAdr >= m_nLength) {
nEndAdr = m_nLength-1;
}
pDataPtr = m_pData + nAdr;
pEndDataPtr = m_pData + nEndAdr;
if( (m_nHighlightedBegin != NOSECTION_VAL) && (m_nHighlightedEnd != NOSECTION_VAL) ) {
}
// paint
cDC.SetBkMode(TRANSPARENT);
while(pDataPtr<pEndDataPtr+1) {
pEndLineDataPtr = pDataPtr + m_tPaintDetails.nBytesPerRow;
if(pEndLineDataPtr>pEndDataPtr) {
pEndLineDataPtr = pEndDataPtr+1;
}
pSelectionBufPtrBegin = NULL;
pSelectionBufPtrEnd = NULL;
pHighlightedBufPtrBegin = NULL;
pHighlightedBufPtrEnd = NULL;
if( (pDataPtr >= pSelectionPtrBegin) && (pDataPtr <= pSelectionPtrEnd) ) {
pSelectionBufPtrBegin = pBuf;
}
if( (pDataPtr >= pHighlightedPtrBegin) && (pDataPtr <= pHighlightedPtrEnd) ) {
pHighlightedBufPtrBegin = pBuf;
}
for(pBufPtr=pBuf; pDataPtr<pEndLineDataPtr; ++pDataPtr) {
if(pDataPtr == pSelectionPtrBegin) {
pSelectionBufPtrBegin = pBufPtr;
}
if(pDataPtr == pSelectionPtrEnd) {
if(pSelectionBufPtrBegin == NULL) {
pSelectionBufPtrBegin = pBuf;
}
pSelectionBufPtrEnd = pBufPtr + 2;
}
if(pDataPtr == pHighlightedPtrBegin) {
pHighlightedBufPtrBegin = pBufPtr;
}
if(pDataPtr == pHighlightedPtrEnd) {
if(pHighlightedBufPtrBegin == NULL) {
pHighlightedBufPtrBegin = pBuf;
}
pHighlightedBufPtrEnd = pBufPtr + 2;
}
*pBufPtr++ = tabHexCharacters[*pDataPtr>>4];
*pBufPtr++ = tabHexCharacters[*pDataPtr&0xf];
*pBufPtr++;
}
*--pBufPtr = '\0';
// set end-pointers
if(pHighlightedBufPtrEnd == NULL) {
pHighlightedBufPtrEnd = pBufPtr;
}
if(pSelectionBufPtrEnd == NULL) {
pSelectionBufPtrEnd = pBufPtr;
}
// first draw all normal
cDC.SetTextColor(m_tHexTxtCol);
cDC.DrawText(pBuf, (LPRECT)cHexRect, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
// highlighted section now
if(pHighlightedBufPtrBegin != NULL) {
CRect cRect(cHexRect);
cRect.left += (int)((pHighlightedBufPtrBegin-pBuf) * m_tPaintDetails.nCharacterWidth);
*pHighlightedBufPtrEnd = '\0'; // set "end-mark"
cDC.SetTextColor(m_tHighlightTxtCol);
cDC.SetBkColor(m_tHighlightBkgCol);
cDC.DrawText(pHighlightedBufPtrBegin, (LPRECT)cRect, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
*pHighlightedBufPtrEnd = ' '; // restore the buffer
}
// selection
if(pSelectionBufPtrBegin != NULL) {
bool bHasFocus = GetFocus() == this;
if(bHasFocus || (GetStyle() & ES_MULTILINE)) { // todo: flag f黵 show selection always
CRect cRect(cHexRect);
cRect.left += (int)((pSelectionBufPtrBegin-pBuf) * m_tPaintDetails.nCharacterWidth);
cRect.right -= (int)((pBuf-1+m_tPaintDetails.nBytesPerRow*3-pSelectionBufPtrEnd) * m_tPaintDetails.nCharacterWidth);
CRect cSelectionRect(cRect);
cSelectionRect.InflateRect(0, -1, +1, 0);
cDC.FillRect(cSelectionRect, &CBrush(bHasFocus ? m_tSelectedFousBkgCol : m_tSelectedNoFocusBkgCol));
*pSelectionBufPtrEnd = '\0'; // set "end-mark"
cDC.SetTextColor(bHasFocus ? m_tSelectedFousTxtCol : m_tSelectedNoFocusTxtCol);
cDC.SetBkColor(m_tHighlightBkgCol);
cDC.DrawText(pSelectionBufPtrBegin, (LPRECT)cRect, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
*pSelectionBufPtrEnd = ' '; // restore the buffer
}
}
cHexRect.OffsetRect(0, m_tPaintDetails.nLineHeight);
}
if( (m_nHighlightedBegin != NOSECTION_VAL) && (m_nHighlightedEnd != NOSECTION_VAL) ) {
CPen cPen(PS_SOLID, 1, m_tHighlightFrameCol);
pOldPen = cDC.SelectObject(&cPen);
cDC.Polyline(pHighlightPolygon, nSelectionCount);
if(pOldBrush != NULL) {
cDC.SelectObject(pOldBrush);
}
if(pOldPen != NULL) {
cDC.SelectObject(pOldPen);
}
}
}
void CHexEditBase::PaintAsciiData(CDC& cDC)
{
ASSERT(m_tPaintDetails.nBytesPerRow > 0);
ASSERT(m_tPaintDetails.nBytesPerRow < 512);
if((m_nLength < 1) || (m_pData == NULL)) {
return;
}
UINT nAdr;
UINT nEndAdr;
CRect cAsciiRect(m_tPaintDetails.cPaintingRect);
char pBuf[512];
char *pBufPtr;
CBrush cBkgBrush;
BYTE *pDataPtr;
BYTE *pDataPtrEnd;
memset(pBuf, '\0', m_tPaintDetails.nBytesPerRow+1);
// the Rect for painting & background
cBkgBrush.CreateSolidBrush(m_tAsciiBkgCol);
cAsciiRect.left += m_tPaintDetails.nAsciiPos - m_nScrollPostionX;
cAsciiRect.right = cAsciiRect.left + m_tPaintDetails.nAsciiLen;
cDC.FillRect(cAsciiRect, &cBkgBrush);
cAsciiRect.bottom = cAsciiRect.top + m_tPaintDetails.nLineHeight;
// start & end-address
nAdr = m_nScrollPostionY * m_tPaintDetails.nBytesPerRow;
nEndAdr = nAdr + m_tPaintDetails.nVisibleLines*m_tPaintDetails.nBytesPerRow;
if(nEndAdr >= m_nLength) {
nEndAdr = m_nLength-1;
}
pDataPtr = m_pData + nAdr;
// paint
cDC.SetBkMode(OPAQUE);
cDC.SetTextColor(m_tAsciiTxtCol);
cDC.SetBkColor(m_tAsciiBkgCol);
for(; nAdr<=nEndAdr; nAdr+=m_tPaintDetails.nBytesPerRow) {
pDataPtrEnd = pDataPtr + m_tPaintDetails.nBytesPerRow;
if(pDataPtrEnd > m_pData + nEndAdr) {
pDataPtrEnd = m_pData + nEndAdr+1;
}
for(pBufPtr=pBuf; pDataPtr<pDataPtrEnd; ++pDataPtr, ++pBufPtr) {
*pBufPtr = isprint(*pDataPtr) ? (char)*pDataPtr : '.';
}
*pBufPtr = '\0';
cDC.DrawText(pBuf, (LPRECT)cAsciiRect, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
cAsciiRect.OffsetRect(0, m_tPaintDetails.nLineHeight);
}
}
void CHexEditBase::OnPaint()
{
CPaintDC cPaintDC(this);
CRect cClientRect;
CDC cMemDC;
CBitmap cBmp;
CBitmap *pOldBitmap;
CFont *pOldFont;
CBrush cBackBrush;
// memorybuffered output (via a memorybitmap)
cMemDC.CreateCompatibleDC(&cPaintDC);
GetClientRect(cClientRect);
cBmp.CreateCompatibleBitmap(&cPaintDC, cClientRect.right, cClientRect.bottom);
pOldBitmap = cMemDC.SelectObject(&cBmp);
pOldFont = cMemDC.SelectObject(&m_cFont);
if(m_bRecalc) {
CalculatePaintingDetails(cMemDC);
}
cBackBrush.CreateSolidBrush(m_tNotUsedBkCol);
cMemDC.FillRect(cClientRect, &cBackBrush);
CRgn cRegn;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -