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

📄 hexviewview.cpp

📁 查看二进制文件的HexView的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* ---------------------------------------------------------------------------

   This code can be used as you wish but without warranties as to performance 
   of merchantability or any other warranties whether expressed or implied.
   
	 Written by Mike Funduc, Funduc Software Inc. 8/1/96

	 To download the code and more useful utilities (including Search and
	 Replace for Windows 95/NT, 3.1x) go to:
	 http://www.funduc.com

----------------------------------------------------------------------------*/

// hexviewView.cpp : implementation of the CHexviewView class
//

#include "stdafx.h"
#include "hexview.h"

#include "hexviewDoc.h"
#include "hexviewView.h"
#include "gotodlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

extern BOOL bDBCS;

/////////////////////////////////////////////////////////////////////////////
// CHexviewView

IMPLEMENT_DYNCREATE(CHexviewView, CScrollView)

BEGIN_MESSAGE_MAP(CHexviewView, CScrollView)
	//{{AFX_MSG_MAP(CHexviewView)
	ON_WM_DESTROY()
	ON_WM_VSCROLL()
	ON_WM_KEYDOWN()
	ON_WM_SIZE()
	ON_COMMAND(ID_VIEW_NEXTBLOCK, OnViewNextblock)
	ON_COMMAND(ID_VIEW_PREVIOUSBLOCK, OnViewPreviousblock)
	ON_UPDATE_COMMAND_UI(ID_VIEW_NEXTBLOCK, OnUpdateViewNextblock)
	ON_UPDATE_COMMAND_UI(ID_VIEW_PREVIOUSBLOCK, OnUpdateViewPreviousblock)
	ON_COMMAND(ID_VIEW_GOTO, OnViewGoto)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CHexviewView construction/destruction

CHexviewView::CHexviewView()
{
    m_cfFixedFont = new(CFont);
	if (bDBCS)
		m_cfFixedFont->CreateStockObject(SYSTEM_FIXED_FONT);
	else
		m_cfFixedFont->CreateStockObject(ANSI_FIXED_FONT);
	m_cfBoldFont = new CFont;
	    // try and create the new font for the list box
    // it should be the same as the old but without the BOLD weight
    LOGFONT oldFont;
    m_cfFixedFont->GetObject(sizeof(LOGFONT), &oldFont);
    
	oldFont.lfUnderline = TRUE;

    m_cfBoldFont->CreateFontIndirect(&oldFont);
    m_cfPrintFont = NULL;
    m_cfPrintBoldFont = NULL;

	m_iCurrentOffset = 0;

}

CHexviewView::~CHexviewView()
{
	delete m_cfBoldFont;
	delete m_cfPrintFont;
	delete m_cfPrintBoldFont;
}

/////////////////////////////////////////////////////////////////////////////
// CHexviewView drawing

void CHexviewView::OnDraw(CDC* pDC)
{
	CHexviewDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	DispData(pDC, m_iFirstLine, pDoc->TotalFileLength(), m_cfFixedFont,
							m_cfBoldFont, m_iWndLines, m_iFontHeight, m_iCurrentOffset, m_iFontWidth);
}

void CHexviewView::DispData(CDC* pDC, int iFirstLine, int iTotalLines, 
							CFont *cfFixedFont, CFont *cfBoldFont,
							int iWndLines, int iFontHeight, int iCurrentOffset, 
							int iFontWidth, int iLine)
{
    CFont *pOldFont = pDC->SelectObject(cfFixedFont);

    CRect rcWnd;
    GetClientRect(&rcWnd);

    // compute the start point
    int iOffset = iFirstLine * 16 + iCurrentOffset;
    int iRemaining = iTotalLines - iOffset;
    CHexviewDoc* pDoc = GetDocument();
    BYTE *pData = pDoc->AdjustPointerAbsolute(0);
	bool bIgnoreThisChar = false;

	int x=0;
    if (!pData) 
	{
        pDC->TextOut(0, 0, "No data", 7);
    } 
	else 
	{
        char buf[100], buf2[100];
        while ((iRemaining > 0) && (iLine < iWndLines)) 
		{
            sprintf(buf, "%8.8lX  ", iOffset);
            BYTE *p = pData + iOffset;
            int iCount = iRemaining;
            for (int i = 0; i < 16; i++) 
			{
                if (iCount > 0) 
				{
                    sprintf(&buf[strlen(buf)],
                            "%2.2X ",
                            *p);
                } 
				else 
				{
                    strcat(buf, "   ");
                }
                iCount--;
                p++;
            }
            strcat(buf, "  ");
            p = pData + iOffset;
            iCount = iRemaining;
            for (i = 0; i < 16; i++) 
			{
				// If bIgnoreThisChar is true, this is that case that last line endded
				// with lead byte of double byte char and the value of this tail byte 
				// is in the range  of lead byte. Yuk!

				// If this is double byte char, need to deal with it now!
				// IsDBCSLeadByte() may return TRUE for tail byte if its value is
				// in the range of lead bytes'
                if ((bDBCS) && (IsDBCSLeadByte(*p)) && !bIgnoreThisChar)
                {
					sprintf(&buf[strlen(buf)], "%c%c", *p, *(p + 1));
					iCount-=2;
					p+=2;
					i++;
					if (i >= 16)
						bIgnoreThisChar = true;
	                continue;
                }
                if ((iCount > 0) && isprint(*p) && !bIgnoreThisChar) 
				{
                    sprintf(&buf[strlen(buf)], "%c", *p);
                } 
				else if (iCount > 0) 
				{
                    strcat(buf, ".");
                } 
				else 
				{
                    strcat(buf, " ");
                }
				bIgnoreThisChar = false;
                iCount--;
                p++;
            }

			// Need to blank out rest of this line
			// This is to make all lines same length, otherwise, list control will have junk displayed.
#define	LINE_LENGTH		78
			if ((i = strlen(buf)) < LINE_LENGTH)
			{
				memset(&buf[i], ' ', LINE_LENGTH-i);
				buf[LINE_LENGTH]=0;
			}

			if ((iOffset + 16 >= pDoc->m_lStartOffset) && (iOffset < pDoc->m_lEndOffset))
			{
				strcpy(buf2, buf);
				CSize szExtent;
				int nStartOnLine = max(0, pDoc->m_lStartOffset - iOffset);
				int nItemsOnLine = min(pDoc->m_lEndOffset, iOffset + 16) - max(pDoc->m_lStartOffset, iOffset);
				// Characters before highlight
				pDC->TextOut(0, iLine * iFontHeight, buf, nStartOnLine * 3 + 10);
				szExtent = pDC->GetTextExtent(buf, nStartOnLine * 3 + 10);
				memcpy(buf, buf2 + nStartOnLine * 3 + 10, (16 - nStartOnLine) * 3 + 2);
				buf[(16 - nStartOnLine) * 3 + 2] = 0;
				pDC->SelectObject(cfBoldFont);
				// Highlight characters
				pDC->TextOut(szExtent.cx, iLine * iFontHeight, buf, nItemsOnLine * 3);
				szExtent += pDC->GetTextExtent(buf, nItemsOnLine * 3);
				pDC->SelectObject(cfFixedFont);
				strcpy(buf, buf2 + (nStartOnLine + nItemsOnLine) * 3 + 10);
				// Characters after highlight
				pDC->TextOut(szExtent.cx, iLine * iFontHeight, buf, strlen(buf));
				pDC->MoveTo(0, (iLine + 1) * iFontHeight);
			}
			else  // Just a regular line
				pDC->TextOut(0, iLine * iFontHeight, buf, strlen(buf));
            iOffset += 16;
            iRemaining -= 16;
            iLine++;
        }
        if (iLine < iWndLines) 
		{
            CRect rc = rcWnd;
            rc.top = iLine * iFontHeight;
            pDC->ExtTextOut(0, iLine * iFontHeight, ETO_OPAQUE,
                            &rc, "", 0, NULL);
        }
    }
    pDC->SelectObject(pOldFont);
}

void CHexviewView::OnInitialUpdate()
{
    CDC *pDC = GetDC();
    CFont *pOldFont = pDC->SelectObject(m_cfFixedFont);
    pDC->SelectObject(pOldFont);
    CHexviewDoc* pDoc = GetDocument();
    m_iLastLine = 0;
    m_iWndLines = 0;
	m_iFirstLine = 0;

	CScrollView::OnInitialUpdate();

	UpdateScrollSizes();
	if (pDoc->m_lStartOffset > -1)
	{
		if (pDoc->m_lStartOffset > pDoc->TotalFileLength())
		{
			m_iFirstLine = 0;
			pDoc->m_lStartOffset = pDoc->m_lEndOffset = -1;
		}
		else
		{
			while (pDoc->m_lStartOffset > m_iCurrentOffset + pDoc->BlockLength(m_iCurrentOffset))
			{
				pDoc->GetNextBlock(m_iCurrentOffset);
			}
			m_iFirstLine = (pDoc->m_lStartOffset - m_iCurrentOffset) / 16;
			m_iLastLine = (pDoc->BlockLength(m_iCurrentOffset) + 15) / 16;
			UpdateScrollSizes();
		}
	}
}

void CHexviewView::UpdateScrollSizes()
{
	// UpdateScrollSizes() is called when it is necessary to adjust the
	// scrolling range or page/line sizes.  There are two occassions
	// where this is necessary:  (1) when a new row is added-- see
	// UpdateRow()-- and (2) when the window size changes-- see OnSize().
	CRect rectClient;
	GetClientRect(&rectClient);

	CClientDC dc(this);
    TEXTMETRIC tm;
    dc.GetTextMetrics(&tm);
    m_iFontHeight = tm.tmHeight + tm.tmExternalLeading;
    m_iFontWidth = tm.tmMaxCharWidth;

    CSize sz;
    sz.cx = m_iFontWidth * 80;
    CHexviewDoc* pDoc = GetDocument();
    sz.cy = m_iViewHeight = (pDoc->BlockLength(m_iCurrentOffset) + 15) / 16;

	m_iLastLine = m_iViewHeight;

	// The vert scrolling range is the total display height of all
	// of the rows.
	CSize sizeTotal(sz.cx,
		m_iFontHeight * (min(m_iViewHeight, INT_MAX / m_iFontHeight - 1)));

    m_iWndLines = max(1, (rectClient.bottom/m_iFontHeight));
	// The vertical per-page scrolling distance is equal to the
	// how many rows can be displayed in the current window, less
	// one row for paging overlap.
	CSize sizePage(sz.cx, m_iWndLines * m_iFontHeight);

	// The vertical per-line scrolling distance is equal to the
		// height of the row.
	CSize sizeLine(sz.cx, m_iFontHeight);

	SetScrollSizes(MM_TEXT, sizeTotal, sizePage, sizeLine);

	if (sizePage.cy >= sizeTotal.cy)
	{
		m_iFirstLine = 0;
	    SetScrollPos(SB_VERT, 0, TRUE);
	}
	else
	{
        int iPos = 0;
		if ((m_iLastLine - m_iWndLines) * m_iFontHeight)  // No divide by 0
			iPos = (m_iViewHeight * m_iFirstLine) / (m_iLastLine - m_iWndLines) * m_iFontHeight;
		SetScrollPos(SB_VERT, iPos, TRUE);
	}
}

/////////////////////////////////////////////////////////////////////////////
// CHexviewView printing

BOOL CHexviewView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

HFONT hOldFont = NULL;

void CHexviewView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	// get current screen font object metrics
	CFont* pFont = GetFont();
	LOGFONT lf;
	LOGFONT lfSys;
	VERIFY(::GetObject(::GetStockObject(ANSI_FIXED_FONT), sizeof(LOGFONT),
			&lfSys));
	if (pFont)
	{
		VERIFY(pFont->GetObject(sizeof(LOGFONT), &lf));
		if (lstrcmpi((LPCTSTR)lf.lfFaceName, (LPCTSTR)lfSys.lfFaceName) == 0)
			return;
		lstrcpy(lf.lfFaceName, (LPCTSTR)lfSys.lfFaceName);
	}
	else
	{
		lf = lfSys;
	}

⌨️ 快捷键说明

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