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

📄 hexviewview.cpp

📁 VC++ 编程宝典,电子工业出版社,源代码,第三部分
💻 CPP
字号:
// HexViewView.cpp : implementation of the CHexViewView class
//

#include "stdafx.h"
#include "HexView.h"

#include "HexViewDoc.h"
#include "HexViewView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CHexViewView

IMPLEMENT_DYNCREATE(CHexViewView, CScrollView)

BEGIN_MESSAGE_MAP(CHexViewView, CScrollView)
	//{{AFX_MSG_MAP(CHexViewView)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
			ON_COMMAND(ID_VIEW_FONT, OnViewFont)
	//}}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()
{
	// TODO: add construction code here
	memset(&m_logfont, 0, sizeof(m_logfont));
 	m_nPointSize = 120;
 	_tcscpy(m_logfont.lfFaceName, _T("Fixedsys"));

	// start out with a system font

	CWindowDC dc(NULL);
	m_logfont.lfHeight = ::MulDiv(m_nPointSize, dc.GetDeviceCaps(LOGPIXELSY), 720);
	m_logfont.lfPitchAndFamily = FIXED_PITCH;

	m_pFont = new CFont;
	m_pFont->CreateFontIndirect(&m_logfont);
	m_pPrintFont = NULL;
	m_bPrinting = FALSE;
}

CHexViewView::~CHexViewView()
{
	if (m_pFont != NULL)
		delete m_pFont;
	if (m_pPrintFont != NULL)
		delete m_pPrintFont;

}

BOOL CHexViewView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CHexViewView drawing

void CHexViewView::OnDraw(CDC* pDC)
{
	CHexViewDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	CString strRender;
	CFont*	pOldFont;
	CSize	ScrolledSize;
	int		nStartLine;
	int		nHeight;
	CRect	ScrollRect;
	CPoint	ScrolledPos = GetScrollPosition();

	if (m_bPrinting)
	{
		// find the first line for this page

		ScrolledSize = CSize(m_nPageWidth, m_nPageHeight);
		ScrollRect = CRect(0, ScrolledPos.y,
			ScrolledSize.cx,
			ScrolledSize.cy + ScrolledPos.y);
		pOldFont = pDC->SelectObject(m_pPrintFont);
		nStartLine = m_nPrintLine;
	}
	else
	{
		CRect	rectClient;
		GetClientRect(&rectClient);

		// figure out how high each line is

		pOldFont = pDC->SelectObject(m_pFont);
		nHeight = MeasureFontHeight(m_pFont, pDC);
	
		// find a starting line based on scrolling

		ScrolledSize = CSize(rectClient.Width(), rectClient.Height());
		ScrollRect = CRect(rectClient.left, ScrolledPos.y,
			rectClient.right,
			ScrolledSize.cy + ScrolledPos.y);
		nStartLine = ScrolledPos.y/16;

		// make sure we are drawing where we should

		ScrollRect.top = nStartLine*nHeight;
	}

	if (pDoc->m_pFile != NULL)
	{

		int nLine;
		for (nLine = nStartLine; ScrollRect.top < ScrollRect.bottom; nLine++)
		{
			if (!pDoc->ReadLine(strRender, 16, nLine*16))
				break;

			nHeight = pDC->DrawText(strRender, -1,
				&ScrollRect, DT_TOP | DT_NOPREFIX | DT_SINGLELINE);
			ScrollRect.top += nHeight;
		}
	}

	pDC->SelectObject(pOldFont);
}

/////////////////////////////////////////////////////////////////////////////
// CHexViewView printing

BOOL CHexViewView::OnPreparePrinting(CPrintInfo* pInfo)
{
	BOOL bResult;
	CWinApp* pApp = AfxGetApp();

	// ask our app what the default printer is
	// if there isn't any, punt to MFC so it will generate an error

	if (!pApp->GetPrinterDeviceDefaults(&pInfo->m_pPD->m_pd) ||
		 pInfo->m_pPD->m_pd.hDevMode == NULL)
		return DoPreparePrinting(pInfo);

	HGLOBAL	hDevMode = pInfo->m_pPD->m_pd.hDevMode;
	HGLOBAL hDevNames = pInfo->m_pPD->m_pd.hDevNames;

	DEVMODE* pDevMode = (DEVMODE*) ::GlobalLock(hDevMode);
	DEVNAMES* pDevNames = (DEVNAMES*) ::GlobalLock(hDevNames);

	LPCSTR pstrDriverName = ((LPCSTR) pDevNames)+pDevNames->wDriverOffset;
	LPCSTR pstrDeviceName = ((LPCSTR) pDevNames)+pDevNames->wDeviceOffset;
	LPCSTR pstrOutputPort = ((LPCSTR) pDevNames)+pDevNames->wOutputOffset;

	CDC dcPrinter;
	if (dcPrinter.CreateDC(pstrDriverName, pstrDeviceName, pstrOutputPort, NULL))
	{
		CalcPageCount(&dcPrinter, pInfo);
		dcPrinter.DeleteDC();
		bResult = DoPreparePrinting(pInfo);
	}
	else
	{
		MessageBox("Could not create printer DC");
		bResult = FALSE;
	}

	::GlobalUnlock(hDevMode);
	::GlobalUnlock(hDevNames);

	return bResult;

}

void CHexViewView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	// create the printer font using the point size the user requested
	// (having different printer fonts and screen fonts is the easiest way
	// to make sure they both look right.)  Since the scaling in the printer
	// is different than the screen, do the math for lfHeight again.

	LOGFONT	lfPrintFont;
	memcpy(&lfPrintFont, &m_logfont, sizeof(lfPrintFont));

	if (m_pPrintFont != NULL)
		delete m_pPrintFont;
	m_pPrintFont = new CFont;
	lfPrintFont.lfHeight = MulDiv(m_nPointSize, pDC->GetDeviceCaps(LOGPIXELSX), 720);
	m_pPrintFont->CreateFontIndirect(&lfPrintFont);

	// get these again, since the user may have changed the printer since
	// we set them up in 

	CalcPageCount(pDC, pInfo);
}

void CHexViewView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
	delete m_pPrintFont;
	m_pPrintFont = NULL;

}

/////////////////////////////////////////////////////////////////////////////
// CHexViewView diagnostics

#ifdef _DEBUG
void CHexViewView::AssertValid() const
{
	CView::AssertValid();
}

void CHexViewView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CHexViewDoc* CHexViewView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CHexViewDoc)));
	return (CHexViewDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CHexViewView message handlers

void CHexViewView::OnInitialUpdate() 
{
	CHexViewDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// hook up our initial size
	
	CSize sizeTotal(0, pDoc->m_lFileSize);
	SetScrollSizes(MM_TEXT, sizeTotal);
	
	CScrollView::OnInitialUpdate();
}

void CHexViewView::OnViewFont() 
{
	// let the user change their mind about the font

	LOGFONT	lfCopy;
	memcpy(&lfCopy, &m_logfont, sizeof(lfCopy));

	// pop up the existing font in the dialog

	CFontDialog dlg(&lfCopy);
	dlg.m_cf.Flags |= CF_FORCEFONTEXIST | CF_FIXEDPITCHONLY;

	// if they say so, create the font and put it in a 
	// member variable for use later

	if (dlg.DoModal() == IDOK)
	{
		CFont*	pFontCopy = new CFont;
		if (pFontCopy->CreateFontIndirect(&lfCopy))
		{
			m_nPointSize = dlg.GetSize();
			if (m_pFont != NULL)
				delete m_pFont;

			m_pFont = pFontCopy;
			memcpy(&m_logfont, &lfCopy, sizeof(lfCopy));
  			Invalidate();
		}
		else
		{
			delete pFontCopy;
			MessageBox(_T("Could not create new font!"));
		}
	}
}

void CHexViewView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
{
	CScrollView::OnPrepareDC(pDC, pInfo);

	// remember if we're printing or not

	if (pInfo == NULL)
		m_bPrinting = FALSE;
	else
	{
	// if we're printing, figure out what line of the file
	// to start printing first

		int nHeight = MeasureFontHeight(m_pPrintFont, pDC);

		m_nPrintLine = ::MulDiv(pInfo->m_nCurPage-1, m_nPageHeight, nHeight);
		m_bPrinting = TRUE;
	}
}

void CHexViewView::CalcPageCount(CDC* pDC, CPrintInfo* pInfo)
{
	// get a pointer to the document

	CHexViewDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	// figure out the page width and height
	// remember that the physical page size isn't completely
	// printable--subtract the nonprintable area from it.

	m_nPageWidth = pDC->GetDeviceCaps(PHYSICALWIDTH)
			- 2*(pDC->GetDeviceCaps(PHYSICALOFFSETX));
	m_nPageHeight = pDC->GetDeviceCaps(PHYSICALHEIGHT)
			- 2*(pDC->GetDeviceCaps(PHYSICALOFFSETY));

	// find out how high our font is
	// figure out how many lines of that font fit on a page

	int nHeight = MeasureFontHeight(m_pPrintFont, pDC);
 	int nPages;
	nPages = (pDoc->m_lFileSize/16*nHeight + (m_nPageHeight-1)) / m_nPageHeight;

	// set up printing info structure

	pInfo->SetMinPage(1);
	pInfo->SetMaxPage(nPages);
		
	return;
}

int CHexViewView::MeasureFontHeight(CFont* pFont, CDC* pDC)
{ 
	// how tall is the identified font in the identified DC?

	CFont* pOldFont;
	pOldFont = pDC->SelectObject(pFont);

	CRect rectDummy;
 	CString strRender = _T("1234567890ABCDEF- ");
	int nHeight = pDC->DrawText(strRender, -1, rectDummy,
		DT_TOP | DT_SINGLELINE | DT_CALCRECT);
	pDC->SelectObject(pOldFont);

	return nHeight;
}

⌨️ 快捷键说明

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