hexviewView.cpp
上传用户:ycdyang2
上传日期:2007-01-07
资源大小:126k
文件大小:19k
源码类别:

编辑器/阅读器

开发平台:

Visual C++

  1. /* ---------------------------------------------------------------------------
  2.    This code can be used as you wish but without warranties as to performance 
  3.    of merchantability or any other warranties whether expressed or implied.
  4.    
  5.  Written by Mike Funduc, Funduc Software Inc. 8/1/96
  6.  To download the code and more useful utilities (including Search and
  7.  Replace for Windows 95/NT, 3.1x) go to:
  8.  http://www.funduc.com
  9. ----------------------------------------------------------------------------*/
  10. // hexviewView.cpp : implementation of the CHexviewView class
  11. //
  12. #include "stdafx.h"
  13. #include "hexview.h"
  14. #include "hexviewDoc.h"
  15. #include "hexviewView.h"
  16. #include "gotodlg.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. extern BOOL bDBCS;
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CHexviewView
  25. IMPLEMENT_DYNCREATE(CHexviewView, CScrollView)
  26. BEGIN_MESSAGE_MAP(CHexviewView, CScrollView)
  27. //{{AFX_MSG_MAP(CHexviewView)
  28. ON_WM_DESTROY()
  29. ON_WM_VSCROLL()
  30. ON_WM_KEYDOWN()
  31. ON_WM_SIZE()
  32. ON_COMMAND(ID_VIEW_NEXTBLOCK, OnViewNextblock)
  33. ON_COMMAND(ID_VIEW_PREVIOUSBLOCK, OnViewPreviousblock)
  34. ON_UPDATE_COMMAND_UI(ID_VIEW_NEXTBLOCK, OnUpdateViewNextblock)
  35. ON_UPDATE_COMMAND_UI(ID_VIEW_PREVIOUSBLOCK, OnUpdateViewPreviousblock)
  36. ON_COMMAND(ID_VIEW_GOTO, OnViewGoto)
  37. //}}AFX_MSG_MAP
  38. // Standard printing commands
  39. ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
  40. ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
  41. ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
  42. END_MESSAGE_MAP()
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CHexviewView construction/destruction
  45. CHexviewView::CHexviewView()
  46. {
  47.     m_cfFixedFont = new(CFont);
  48. if (bDBCS)
  49. m_cfFixedFont->CreateStockObject(SYSTEM_FIXED_FONT);
  50. else
  51. m_cfFixedFont->CreateStockObject(ANSI_FIXED_FONT);
  52. m_cfBoldFont = new CFont;
  53.     // try and create the new font for the list box
  54.     // it should be the same as the old but without the BOLD weight
  55.     LOGFONT oldFont;
  56.     m_cfFixedFont->GetObject(sizeof(LOGFONT), &oldFont);
  57.     
  58. oldFont.lfUnderline = TRUE;
  59.     m_cfBoldFont->CreateFontIndirect(&oldFont);
  60.     m_cfPrintFont = NULL;
  61.     m_cfPrintBoldFont = NULL;
  62. m_iCurrentOffset = 0;
  63. }
  64. CHexviewView::~CHexviewView()
  65. {
  66. delete m_cfBoldFont;
  67. delete m_cfPrintFont;
  68. delete m_cfPrintBoldFont;
  69. }
  70. /////////////////////////////////////////////////////////////////////////////
  71. // CHexviewView drawing
  72. void CHexviewView::OnDraw(CDC* pDC)
  73. {
  74. CHexviewDoc* pDoc = GetDocument();
  75. ASSERT_VALID(pDoc);
  76. DispData(pDC, m_iFirstLine, pDoc->TotalFileLength(), m_cfFixedFont,
  77. m_cfBoldFont, m_iWndLines, m_iFontHeight, m_iCurrentOffset, m_iFontWidth);
  78. }
  79. void CHexviewView::DispData(CDC* pDC, int iFirstLine, int iTotalLines, 
  80. CFont *cfFixedFont, CFont *cfBoldFont,
  81. int iWndLines, int iFontHeight, int iCurrentOffset, 
  82. int iFontWidth, int iLine)
  83. {
  84.     CFont *pOldFont = pDC->SelectObject(cfFixedFont);
  85.     CRect rcWnd;
  86.     GetClientRect(&rcWnd);
  87.     // compute the start point
  88.     int iOffset = iFirstLine * 16 + iCurrentOffset;
  89.     int iRemaining = iTotalLines - iOffset;
  90.     CHexviewDoc* pDoc = GetDocument();
  91.     BYTE *pData = pDoc->AdjustPointerAbsolute(0);
  92. bool bIgnoreThisChar = false;
  93. int x=0;
  94.     if (!pData) 
  95. {
  96.         pDC->TextOut(0, 0, "No data", 7);
  97.     } 
  98. else 
  99. {
  100.         char buf[100], buf2[100];
  101.         while ((iRemaining > 0) && (iLine < iWndLines)) 
  102. {
  103.             sprintf(buf, "%8.8lX  ", iOffset);
  104.             BYTE *p = pData + iOffset;
  105.             int iCount = iRemaining;
  106.             for (int i = 0; i < 16; i++) 
  107. {
  108.                 if (iCount > 0) 
  109. {
  110.                     sprintf(&buf[strlen(buf)],
  111.                             "%2.2X ",
  112.                             *p);
  113.                 } 
  114. else 
  115. {
  116.                     strcat(buf, "   ");
  117.                 }
  118.                 iCount--;
  119.                 p++;
  120.             }
  121.             strcat(buf, "  ");
  122.             p = pData + iOffset;
  123.             iCount = iRemaining;
  124.             for (i = 0; i < 16; i++) 
  125. {
  126. // If bIgnoreThisChar is true, this is that case that last line endded
  127. // with lead byte of double byte char and the value of this tail byte 
  128. // is in the range  of lead byte. Yuk!
  129. // If this is double byte char, need to deal with it now!
  130. // IsDBCSLeadByte() may return TRUE for tail byte if its value is
  131. // in the range of lead bytes'
  132.                 if ((bDBCS) && (IsDBCSLeadByte(*p)) && !bIgnoreThisChar)
  133.                 {
  134. sprintf(&buf[strlen(buf)], "%c%c", *p, *(p + 1));
  135. iCount-=2;
  136. p+=2;
  137. i++;
  138. if (i >= 16)
  139. bIgnoreThisChar = true;
  140.                 continue;
  141.                 }
  142.                 if ((iCount > 0) && isprint(*p) && !bIgnoreThisChar) 
  143. {
  144.                     sprintf(&buf[strlen(buf)], "%c", *p);
  145.                 } 
  146. else if (iCount > 0) 
  147. {
  148.                     strcat(buf, ".");
  149.                 } 
  150. else 
  151. {
  152.                     strcat(buf, " ");
  153.                 }
  154. bIgnoreThisChar = false;
  155.                 iCount--;
  156.                 p++;
  157.             }
  158. // Need to blank out rest of this line
  159. // This is to make all lines same length, otherwise, list control will have junk displayed.
  160. #define LINE_LENGTH 78
  161. if ((i = strlen(buf)) < LINE_LENGTH)
  162. {
  163. memset(&buf[i], ' ', LINE_LENGTH-i);
  164. buf[LINE_LENGTH]=0;
  165. }
  166. if ((iOffset + 16 >= pDoc->m_lStartOffset) && (iOffset < pDoc->m_lEndOffset))
  167. {
  168. strcpy(buf2, buf);
  169. CSize szExtent;
  170. int nStartOnLine = max(0, pDoc->m_lStartOffset - iOffset);
  171. int nItemsOnLine = min(pDoc->m_lEndOffset, iOffset + 16) - max(pDoc->m_lStartOffset, iOffset);
  172. // Characters before highlight
  173. pDC->TextOut(0, iLine * iFontHeight, buf, nStartOnLine * 3 + 10);
  174. szExtent = pDC->GetTextExtent(buf, nStartOnLine * 3 + 10);
  175. memcpy(buf, buf2 + nStartOnLine * 3 + 10, (16 - nStartOnLine) * 3 + 2);
  176. buf[(16 - nStartOnLine) * 3 + 2] = 0;
  177. pDC->SelectObject(cfBoldFont);
  178. // Highlight characters
  179. pDC->TextOut(szExtent.cx, iLine * iFontHeight, buf, nItemsOnLine * 3);
  180. szExtent += pDC->GetTextExtent(buf, nItemsOnLine * 3);
  181. pDC->SelectObject(cfFixedFont);
  182. strcpy(buf, buf2 + (nStartOnLine + nItemsOnLine) * 3 + 10);
  183. // Characters after highlight
  184. pDC->TextOut(szExtent.cx, iLine * iFontHeight, buf, strlen(buf));
  185. pDC->MoveTo(0, (iLine + 1) * iFontHeight);
  186. }
  187. else  // Just a regular line
  188. pDC->TextOut(0, iLine * iFontHeight, buf, strlen(buf));
  189.             iOffset += 16;
  190.             iRemaining -= 16;
  191.             iLine++;
  192.         }
  193.         if (iLine < iWndLines) 
  194. {
  195.             CRect rc = rcWnd;
  196.             rc.top = iLine * iFontHeight;
  197.             pDC->ExtTextOut(0, iLine * iFontHeight, ETO_OPAQUE,
  198.                             &rc, "", 0, NULL);
  199.         }
  200.     }
  201.     pDC->SelectObject(pOldFont);
  202. }
  203. void CHexviewView::OnInitialUpdate()
  204. {
  205.     CDC *pDC = GetDC();
  206.     CFont *pOldFont = pDC->SelectObject(m_cfFixedFont);
  207.     pDC->SelectObject(pOldFont);
  208.     CHexviewDoc* pDoc = GetDocument();
  209.     m_iLastLine = 0;
  210.     m_iWndLines = 0;
  211. m_iFirstLine = 0;
  212. CScrollView::OnInitialUpdate();
  213. UpdateScrollSizes();
  214. if (pDoc->m_lStartOffset > -1)
  215. {
  216. if (pDoc->m_lStartOffset > pDoc->TotalFileLength())
  217. {
  218. m_iFirstLine = 0;
  219. pDoc->m_lStartOffset = pDoc->m_lEndOffset = -1;
  220. }
  221. else
  222. {
  223. while (pDoc->m_lStartOffset > m_iCurrentOffset + pDoc->BlockLength(m_iCurrentOffset))
  224. {
  225. pDoc->GetNextBlock(m_iCurrentOffset);
  226. }
  227. m_iFirstLine = (pDoc->m_lStartOffset - m_iCurrentOffset) / 16;
  228. m_iLastLine = (pDoc->BlockLength(m_iCurrentOffset) + 15) / 16;
  229. UpdateScrollSizes();
  230. }
  231. }
  232. }
  233. void CHexviewView::UpdateScrollSizes()
  234. {
  235. // UpdateScrollSizes() is called when it is necessary to adjust the
  236. // scrolling range or page/line sizes.  There are two occassions
  237. // where this is necessary:  (1) when a new row is added-- see
  238. // UpdateRow()-- and (2) when the window size changes-- see OnSize().
  239. CRect rectClient;
  240. GetClientRect(&rectClient);
  241. CClientDC dc(this);
  242.     TEXTMETRIC tm;
  243.     dc.GetTextMetrics(&tm);
  244.     m_iFontHeight = tm.tmHeight + tm.tmExternalLeading;
  245.     m_iFontWidth = tm.tmMaxCharWidth;
  246.     CSize sz;
  247.     sz.cx = m_iFontWidth * 80;
  248.     CHexviewDoc* pDoc = GetDocument();
  249.     sz.cy = m_iViewHeight = (pDoc->BlockLength(m_iCurrentOffset) + 15) / 16;
  250. m_iLastLine = m_iViewHeight;
  251. // The vert scrolling range is the total display height of all
  252. // of the rows.
  253. CSize sizeTotal(sz.cx,
  254. m_iFontHeight * (min(m_iViewHeight, INT_MAX / m_iFontHeight - 1)));
  255.     m_iWndLines = max(1, (rectClient.bottom/m_iFontHeight));
  256. // The vertical per-page scrolling distance is equal to the
  257. // how many rows can be displayed in the current window, less
  258. // one row for paging overlap.
  259. CSize sizePage(sz.cx, m_iWndLines * m_iFontHeight);
  260. // The vertical per-line scrolling distance is equal to the
  261. // height of the row.
  262. CSize sizeLine(sz.cx, m_iFontHeight);
  263. SetScrollSizes(MM_TEXT, sizeTotal, sizePage, sizeLine);
  264. if (sizePage.cy >= sizeTotal.cy)
  265. {
  266. m_iFirstLine = 0;
  267.     SetScrollPos(SB_VERT, 0, TRUE);
  268. }
  269. else
  270. {
  271.         int iPos = 0;
  272. if ((m_iLastLine - m_iWndLines) * m_iFontHeight)  // No divide by 0
  273. iPos = (m_iViewHeight * m_iFirstLine) / (m_iLastLine - m_iWndLines) * m_iFontHeight;
  274. SetScrollPos(SB_VERT, iPos, TRUE);
  275. }
  276. }
  277. /////////////////////////////////////////////////////////////////////////////
  278. // CHexviewView printing
  279. BOOL CHexviewView::OnPreparePrinting(CPrintInfo* pInfo)
  280. {
  281. // default preparation
  282. return DoPreparePrinting(pInfo);
  283. }
  284. HFONT hOldFont = NULL;
  285. void CHexviewView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
  286. {
  287. // get current screen font object metrics
  288. CFont* pFont = GetFont();
  289. LOGFONT lf;
  290. LOGFONT lfSys;
  291. VERIFY(::GetObject(::GetStockObject(ANSI_FIXED_FONT), sizeof(LOGFONT),
  292. &lfSys));
  293. if (pFont)
  294. {
  295. VERIFY(pFont->GetObject(sizeof(LOGFONT), &lf));
  296. if (lstrcmpi((LPCTSTR)lf.lfFaceName, (LPCTSTR)lfSys.lfFaceName) == 0)
  297. return;
  298. lstrcpy(lf.lfFaceName, (LPCTSTR)lfSys.lfFaceName);
  299. }
  300. else
  301. {
  302. lf = lfSys;
  303. }
  304. // map to printer font metrics
  305. HDC hDCFrom = ::GetDC(NULL);
  306. lf.lfHeight = ::MulDiv(lf.lfHeight, pDC->GetDeviceCaps(LOGPIXELSY),
  307. ::GetDeviceCaps(hDCFrom, LOGPIXELSY));
  308. lf.lfWidth = ::MulDiv(lf.lfWidth, pDC->GetDeviceCaps(LOGPIXELSX),
  309. ::GetDeviceCaps(hDCFrom, LOGPIXELSX));
  310. ::ReleaseDC(NULL, hDCFrom);
  311. // create it, if it fails we just use the printer's default.
  312. if (m_cfPrintFont)
  313. delete m_cfPrintFont;
  314. if (m_cfPrintBoldFont)
  315. delete m_cfPrintBoldFont;
  316. m_cfPrintFont = new CFont;
  317. m_cfPrintBoldFont = new CFont;
  318. m_cfPrintFont->CreateFontIndirect(&lf);
  319. lf.lfUnderline = TRUE;
  320.     m_cfPrintBoldFont->CreateFontIndirect(&lf);
  321.     CFont *pOldFont = pDC->SelectObject(m_cfPrintFont);
  322.     TEXTMETRIC tm;
  323.     pDC->GetTextMetrics(&tm);
  324. int nPageHeight = pDC->GetDeviceCaps(VERTRES);
  325.     m_iFontHeight = tm.tmHeight + tm.tmExternalLeading;
  326. m_iWndLines = nPageHeight / m_iFontHeight - 5;
  327. CHexviewDoc* pDoc = GetDocument();
  328. ASSERT_VALID(pDoc);
  329. m_iFirstLine = 0;
  330. int nTotalLines = (pDoc->TotalFileLength() + 15) / 16;
  331. pInfo->SetMaxPage((nTotalLines + m_iWndLines - 1) / m_iWndLines);
  332. pDC->SelectObject(pOldFont);
  333. SYSTEMTIME sysTime;
  334. GetSystemTime(&sysTime);
  335. CString strDate;
  336. GetDateFormat(NULL, LOCALE_NOUSEROVERRIDE, &sysTime, NULL,
  337.           strDate.GetBuffer(255), 255);
  338. strDate.ReleaseBuffer();
  339. GetTimeFormat(NULL, LOCALE_NOUSEROVERRIDE, &sysTime, NULL,
  340.           m_strTimePrint.GetBuffer(255), 255);
  341. m_strTimePrint.ReleaseBuffer();
  342. m_strTimePrint = strDate + "  " + m_strTimePrint;
  343. }
  344. void CHexviewView::OnEndPrinting(CDC* pDC, CPrintInfo* /*pInfo*/)
  345. {
  346. UpdateScrollSizes();
  347. }
  348. /////////////////////////////////////////////////////////////////////////////
  349. // CHexviewView diagnostics
  350. #ifdef _DEBUG
  351. void CHexviewView::AssertValid() const
  352. {
  353. CScrollView::AssertValid();
  354. }
  355. void CHexviewView::Dump(CDumpContext& dc) const
  356. {
  357. CScrollView::Dump(dc);
  358. }
  359. CHexviewDoc* CHexviewView::GetDocument() // non-debug version is inline
  360. {
  361. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CHexviewDoc)));
  362. return (CHexviewDoc*)m_pDocument;
  363. }
  364. #endif //_DEBUG
  365. /////////////////////////////////////////////////////////////////////////////
  366. // CHexviewView message handlers
  367. void CHexviewView::OnDestroy() 
  368. {
  369. delete m_cfFixedFont;
  370. CScrollView::OnDestroy();
  371. }
  372. void CHexviewView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo) 
  373. {
  374. // TODO: Add your specialized code here and/or call the base class
  375. CScrollView::OnPrepareDC(pDC, pInfo);
  376.     CPoint pt = pDC->GetViewportOrg();
  377.     pt.y = 0;
  378.     pDC->SetViewportOrg(pt);
  379. }
  380. void CHexviewView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
  381. {
  382.     switch (nSBCode) 
  383. {
  384.     case SB_TOP:
  385.         m_iFirstLine = 0;
  386.         break;
  387.     
  388.     case SB_BOTTOM:
  389.         m_iFirstLine = m_iLastLine;
  390.         break;
  391.     
  392.     case SB_LINEUP:
  393.         m_iFirstLine--;
  394.         break;
  395.         
  396.     case SB_PAGEUP:    
  397.         m_iFirstLine -= m_iWndLines;
  398.         break;
  399.     case SB_LINEDOWN:
  400.         m_iFirstLine++;
  401.         break;
  402.     case SB_PAGEDOWN:
  403.         m_iFirstLine += m_iWndLines;
  404.         break;
  405.     
  406.     case SB_THUMBPOSITION:
  407.     case SB_THUMBTRACK:
  408.         m_iFirstLine = (nPos * m_iLastLine) / (m_iFontHeight * m_iViewHeight);
  409.         if (m_iFirstLine == m_iLastLine - m_iWndLines - 1)
  410.             m_iFirstLine = m_iLastLine - m_iWndLines;
  411.         break;
  412.     default:
  413.         return;
  414.     }
  415. if (m_iFirstLine >= m_iLastLine - m_iWndLines) 
  416. {
  417.         m_iFirstLine = m_iLastLine - m_iWndLines;
  418.     }
  419.     if (m_iFirstLine < 0) m_iFirstLine = 0;
  420.     if (m_iWndLines >= m_iLastLine) 
  421. {
  422.         m_iFirstLine = 0;
  423.     } 
  424.     int iPos = 0;
  425.     if (m_iWndLines < m_iLastLine) 
  426.         iPos = ((m_iViewHeight * m_iFirstLine) / (m_iLastLine - m_iWndLines)) * m_iFontHeight;
  427. TRACE("First Line: %d, Last Line: %d, Window lines: %d, Position: %dn", 
  428. m_iFirstLine, m_iLastLine, m_iWndLines, iPos);
  429.     SetScrollPos(SB_VERT, iPos, TRUE);
  430.     Invalidate(TRUE);
  431. }
  432. void CHexviewView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  433. {
  434. // TODO: Add your message handler code here and/or call default
  435.    switch (nChar) 
  436.    {
  437.     case VK_HOME:
  438.         OnVScroll(SB_TOP, 0, NULL);
  439.         break;
  440.     case VK_END:
  441.         OnVScroll(SB_BOTTOM, 0, NULL);
  442.         break;
  443.     case VK_UP:
  444.         OnVScroll(SB_LINEUP, 0, NULL);
  445.         break;
  446.     case VK_DOWN:
  447.         OnVScroll(SB_LINEDOWN, 0, NULL);
  448.         break;
  449.     case VK_PRIOR:
  450.         OnVScroll(SB_PAGEUP, 0, NULL);
  451.         break;
  452.     case VK_NEXT:
  453.         OnVScroll(SB_PAGEDOWN, 0, NULL);
  454.         break;
  455.     
  456.     default:    
  457.         CScrollView::OnKeyDown(nChar, nRepCnt, nFlags);
  458.         break;
  459.     }
  460. }
  461. void CHexviewView::OnPrint(CDC* pDC, CPrintInfo* pInfo) 
  462. {
  463.     CFont *pOldFont = pDC->SelectObject(m_cfPrintFont);
  464. // get string to show as "filename" in header/footer
  465. LPCTSTR pszFileName = GetDocument()->GetPathName();
  466. if (pszFileName[0] == 0)
  467. pszFileName = GetDocument()->GetTitle();
  468. // go thru global CPageSetupDlg to format the header and footer
  469. CString strHeader;
  470. strHeader = pszFileName;
  471. CString strFooter;
  472. CHexviewDoc* pDoc = GetDocument();
  473. int nTotalLines = (pDoc->TotalFileLength() + 15) / 16;
  474. wsprintf(strFooter.GetBuffer(81), "Page %d of %d", pInfo->m_nCurPage,
  475. (nTotalLines + m_iWndLines - 1) / m_iWndLines);
  476. strFooter.ReleaseBuffer();
  477. TEXTMETRIC tm;
  478. pDC->GetTextMetrics(&tm);
  479. int cyChar = tm.tmHeight;
  480. CRect rectPage = pInfo->m_rectDraw;
  481. // draw and exclude space for header
  482. if (!strHeader.IsEmpty())
  483. {
  484. pDC->TextOut(rectPage.left, rectPage.top, strHeader);
  485. int nAlign = pDC->SetTextAlign(TA_NOUPDATECP | TA_RIGHT | TA_TOP);
  486. strHeader = _T("Printed by HexView: http://www.funduc.com");
  487. pDC->TextOut(rectPage.right, rectPage.top, strHeader);
  488. pDC->SetTextAlign(nAlign);
  489. rectPage.top += cyChar + cyChar / 4;
  490. pDC->MoveTo(rectPage.left, rectPage.top);
  491. pDC->LineTo(rectPage.right, rectPage.top);
  492. rectPage.top += cyChar / 4;
  493. pInfo->m_rectDraw.top = rectPage.top;
  494. }
  495. // allow space for footer
  496. if (!strFooter.IsEmpty())
  497. pInfo->m_rectDraw.bottom -= cyChar + cyChar/4 + cyChar/4;
  498. int nPageHeight = pDC->GetDeviceCaps(VERTRES);
  499.     int iFontHeight = tm.tmHeight + tm.tmExternalLeading;
  500.     int iFontWidth = tm.tmMaxCharWidth;
  501. int iWndLines = nPageHeight / iFontHeight - 5;
  502. int iFirstLine = (pInfo->m_nCurPage -1) * iWndLines;
  503. iFirstLine += (2 * (pInfo->m_nCurPage -1));
  504. // Print the rows for the current page.
  505. int yTopOfPage = (pInfo->m_nCurPage -1) * iWndLines
  506. * iFontHeight;
  507. ASSERT_VALID(pDoc);
  508. DispData(pDC, iFirstLine, pDoc->TotalFileLength(), m_cfPrintFont,
  509. m_cfPrintBoldFont, iWndLines + 4, iFontHeight, 0, iFontWidth, 2);
  510. // draw footer
  511. if (!strFooter.IsEmpty())
  512. {
  513. rectPage.bottom -= cyChar;
  514. pDC->TextOut(rectPage.left, rectPage.bottom, strFooter);
  515. int nAlign = pDC->SetTextAlign(TA_NOUPDATECP | TA_RIGHT | TA_TOP);
  516. pDC->TextOut(rectPage.right, rectPage.bottom, m_strTimePrint);
  517. pDC->SetTextAlign(nAlign);
  518. rectPage.bottom -= cyChar / 4;
  519. pDC->MoveTo(rectPage.left, rectPage.bottom);
  520. pDC->LineTo(rectPage.right, rectPage.bottom);
  521. rectPage.bottom -= cyChar / 4;
  522. }
  523.     pDC->SelectObject(pOldFont);
  524. }
  525. void CHexviewView::OnSize(UINT nType, int cx, int cy) 
  526. {
  527. UpdateScrollSizes();
  528. CScrollView::OnSize(nType, cx, cy);
  529. }
  530. void CHexviewView::OnViewNextblock() 
  531. {
  532. CHexviewDoc* pDoc = GetDocument();
  533. ASSERT_VALID(pDoc);
  534. if (pDoc->GetNextBlock(m_iCurrentOffset))
  535. {
  536. m_iFirstLine = 0;
  537. m_iLastLine = (pDoc->BlockLength(m_iCurrentOffset) + 15) / 16;
  538.     SetScrollPos(SB_VERT, 0, TRUE);
  539. UpdateScrollSizes();
  540. Invalidate();
  541. }
  542. }
  543. void CHexviewView::OnViewPreviousblock() 
  544. {
  545. CHexviewDoc* pDoc = GetDocument();
  546. ASSERT_VALID(pDoc);
  547. if (pDoc->GetPrevBlock(m_iCurrentOffset))
  548. {
  549. m_iFirstLine = 0;
  550. m_iLastLine = (pDoc->BlockLength(m_iCurrentOffset) + 15) / 16;
  551.     SetScrollPos(SB_VERT, 0, TRUE);
  552. UpdateScrollSizes();
  553. Invalidate();
  554. }
  555. }
  556. void CHexviewView::OnUpdateViewNextblock(CCmdUI* pCmdUI) 
  557. {
  558. CHexviewDoc* pDoc = GetDocument();
  559. ASSERT_VALID(pDoc);
  560. int iCurrentOffset = m_iCurrentOffset;
  561. pCmdUI->Enable(pDoc->GetNextBlock(iCurrentOffset));
  562. }
  563. void CHexviewView::OnUpdateViewPreviousblock(CCmdUI* pCmdUI) 
  564. {
  565. CHexviewDoc* pDoc = GetDocument();
  566. ASSERT_VALID(pDoc);
  567. int iCurrentOffset = m_iCurrentOffset;
  568. pCmdUI->Enable(pDoc->GetPrevBlock(iCurrentOffset));
  569. }
  570. void CHexviewView::OnViewGoto() 
  571. {
  572. CGotoDlg dlgGoto;
  573. CHexviewDoc* pDoc = GetDocument();
  574. ASSERT_VALID(pDoc);
  575. if (pDoc->m_lStartOffset != -1)  // Show the initial offset
  576. dlgGoto.m_lNewOffset = pDoc->m_lStartOffset;
  577. else  // Show the top of current block
  578. dlgGoto.m_lNewOffset = m_iCurrentOffset;
  579. if (dlgGoto.DoModal() == IDOK)
  580. {
  581. // Bogus offset
  582. if (dlgGoto.m_lNewOffset > pDoc->TotalFileLength())
  583. {
  584. m_iFirstLine = 0;
  585. }
  586. else
  587. {
  588. // Find the right block
  589. while (dlgGoto.m_lNewOffset > m_iCurrentOffset + pDoc->BlockLength(m_iCurrentOffset))
  590. {
  591. pDoc->GetNextBlock(m_iCurrentOffset);
  592. }
  593. m_iFirstLine = (dlgGoto.m_lNewOffset - m_iCurrentOffset) / 16;
  594. m_iLastLine = (pDoc->BlockLength(m_iCurrentOffset) + 15) / 16;
  595. UpdateScrollSizes();
  596. }
  597. Invalidate();
  598. }
  599. }