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

📄 hexedvw.cpp

📁 一个完整的编辑器的代码(很值得参考
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// hexedvw.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "editcmd.h"
#include "hexedvw.h"

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

TCHAR hextable[16] = {_T ('0'), _T ('1'), _T ('2'), _T ('3'), _T ('4'), _T ('5'), _T ('6'), _T ('7'),
                     _T ('8'), _T ('9'), _T ('A'), _T ('B'), _T ('C'), _T ('D'), _T ('E'), _T ('F')};
#define TOHEX(a, b) {*b++ = hextable[a >> 4];*b++ = hextable[a&0xf];}
/////////////////////////////////////////////////////////////////////////////
// CHexEditView
#define DEMO
IMPLEMENT_DYNCREATE(CHexEditView, CView)

static LPBYTE s_pData = NULL;      // pointer to data
static int s_length = 0;     // length of data

CHexEditView::CHexEditView()
{
  m_pData = &s_pData;
  m_length = &s_length;
  m_topindex    = 0;
  m_bpr     = 16;    // byte per row 
  m_lpp     = 1;

  m_dwFlags = (HVW_SHOW_ADDRESS|HVW_SHOW_ASCII|HVW_SHOW_HEX|HVW_WIDE_ADDRESS);

  m_offAddress  = 0;
  m_offHex    = 0;
  m_offAscii    = 0;

  m_dwFlags |= HVW_UPDATE;     // update font info
  m_currentMode = EDIT_NONE;

  m_editPos.x = m_editPos.y = 0;
  m_currentAddress = 0;
  m_dwFlags |= HVW_HALF_PAGE;

  m_selStart  = 0xffffffff;
  m_selEnd  = 0xffffffff;

  m_Font.CreateFont(-12, 0,0,0,0,0,0,0,0,0,0,0,0, _T ("Courier New"));
}

CHexEditView::~CHexEditView()
{
}


BEGIN_MESSAGE_MAP(CHexEditView, CView)
  ON_WM_CONTEXTMENU()
  //{{AFX_MSG_MAP(CHexEditView)
  ON_WM_CHAR()
  ON_WM_KILLFOCUS()
  ON_WM_PAINT()
  ON_WM_SETFOCUS()
  ON_WM_SIZE()
  ON_WM_VSCROLL()
  ON_WM_HSCROLL()
  ON_WM_GETDLGCODE()
  ON_WM_ERASEBKGND()
  ON_WM_LBUTTONDOWN()
  ON_WM_LBUTTONDBLCLK()
  ON_WM_MOUSEMOVE()
  ON_WM_LBUTTONUP()
  ON_WM_KEYDOWN()
  ON_COMMAND(ID_EDIT_CLEAR, OnEditClear)
  ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  ON_COMMAND(ID_EDIT_CUT, OnEditCut)
  ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
  ON_COMMAND(ID_EDIT_SELECT_ALL, OnEditSelectAll)
  ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
  ON_COMMAND (ID_READ_ONLY, OnReadOnly)
  ON_UPDATE_COMMAND_UI (ID_READ_ONLY, OnReadOnly)
  ON_COMMAND (ID_FORMAT_SHOW_ADDRESS, OnFormatShowAddress)
  ON_UPDATE_COMMAND_UI (ID_FORMAT_SHOW_ADDRESS, OnUpdateFormatShowAddress)
  ON_COMMAND (ID_FORMAT_SHOW_ASCII, OnFormatShowAscii)
  ON_UPDATE_COMMAND_UI (ID_FORMAT_SHOW_ASCII, OnUpdateFormatShowAscii)
  ON_COMMAND (ID_FORMAT_SHOW_HEX, OnFormatShowHex)
  ON_UPDATE_COMMAND_UI (ID_FORMAT_SHOW_HEX, OnUpdateFormatShowHex)
  ON_COMMAND (ID_FORMAT_WIDE_ADDRESS, OnFormatWideAddress)
  ON_UPDATE_COMMAND_UI (ID_FORMAT_WIDE_ADDRESS, OnUpdateFormatWideAddress)
  ON_COMMAND_RANGE (ID_FORMAT_BPR_FIRST, ID_FORMAT_BPR_LAST, OnBpr)
  ON_UPDATE_COMMAND_UI_RANGE (ID_FORMAT_BPR_FIRST, ID_FORMAT_BPR_LAST, OnUpdateBpr)
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CHexEditView message handlers

void CHexEditView::OnDraw(CDC* pDC)
{
  CDocument* pDoc = GetDocument();
  ASSERT_VALID(pDoc);
  // TODO: add draw code for native data here
}

void CHexEditView::OnPaint() 
{
  CPaintDC pdc(this); // device context for painting

  CRect rc;
  GetClientRect(rc);
  
  CDC dc;
  dc.CreateCompatibleDC(CDC::FromHandle(pdc.m_ps.hdc));
  CBitmap bm;

  bm.CreateCompatibleBitmap(CDC::FromHandle(pdc.m_ps.hdc), rc.Width(), rc.Height());
  dc.SelectObject(bm);

  CBrush b;
  b.CreateSolidBrush(RGB(0xff,0xff,0xff));
  dc.FillRect(rc, &b);

  ASSERT(m_currentAddress >= 0);
  ASSERT(m_topindex >= 0);

  dc.SelectObject(m_Font);
  int   height    = 0;
  int   x,y;
  TCHAR  buf[256];

  x = rc.TopLeft().x;
  y = rc.TopLeft().y;

  dc.SetBoundsRect(&rc, DCB_DISABLE);

  if(m_pData && *m_pData)
  {
    //
    // get char dimensions
    //
    if(m_dwFlags & HVW_UPDATE)
    {
      dc.GetCharWidth(_T ('0'), _T ('0'), &m_nullWidth);
      CSize sz = dc.GetTextExtent(_T ("0"), 1);
      m_lineHeight = sz.cy;
      
      m_offHex  = m_dwFlags & HVW_SHOW_ADDRESS ? (m_dwFlags & HVW_WIDE_ADDRESS ? m_nullWidth * 9 : m_nullWidth * 5) : 0;
      m_offAscii  = m_dwFlags & HVW_SHOW_ADDRESS ? (m_dwFlags & HVW_WIDE_ADDRESS ? m_nullWidth * 9 : m_nullWidth * 5) : 0;
      m_offAscii += m_dwFlags & HVW_SHOW_HEX ? (m_bpr * 3 * m_nullWidth) : 0;

      m_lpp = rc.Height() / m_lineHeight;
      m_dwFlags &= ~HVW_HALF_PAGE;
      if(m_lpp * m_bpr > *m_length)
      {
        m_lpp = (*m_length + (m_bpr/2)) / m_bpr ;
        if(*m_length % m_bpr != 0)
        {
          m_dwFlags |= HVW_HALF_PAGE;
          m_lpp++;
        }
      }
      m_dwFlags &= ~HVW_UPDATE;
      UpdateScrollbars();
    }

    TRACE(_T ("%i %i\n"), m_topindex, m_selStart);
    
    height = rc.Height() / m_lineHeight;
    height *= m_lineHeight;

    if(m_dwFlags & HVW_SHOW_ADDRESS)
    {
      TCHAR fmt[8] = {_T ('%'), _T ('0'), _T ('8'), _T ('l'), _T ('X')};
      fmt[2] = m_dwFlags & HVW_WIDE_ADDRESS ? _T ('8') : _T ('4');
      int w = m_dwFlags & HVW_WIDE_ADDRESS ? 8 : 4;
      y = 0;
      CRect rcd = rc;
      rcd.TopLeft().x = m_offAddress;
      for(int  i = m_topindex; (i < *m_length) && (rcd.TopLeft().y < height); i+= m_bpr)
      {
        _stprintf(buf, fmt, i);
        dc.DrawText(buf, w, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
        rcd.TopLeft().y += m_lineHeight;
      }
    }
    if(m_dwFlags & HVW_SHOW_HEX)
    {
      y = 0;
      CRect rcd = rc;
      rcd.TopLeft().x = x = m_offHex;

      if(m_selStart != 0xffffffff && (m_currentMode == EDIT_HIGH || m_currentMode == EDIT_LOW))
      {
        int  i;
        int  n = 0;
        int  selStart = m_selStart, selEnd = m_selEnd;
        if(selStart > selEnd)
          selStart ^= selEnd ^= selStart ^= selEnd;

        for(i = m_topindex; (i < selStart) && (y < height); i++)
        {
          LPTSTR p = buf;
          TOHEX((*m_pData)[i], p);
          *p++ = _T (' ');
          dc.TextOut(x, y, buf, 3);
          x += m_nullWidth * 3;
          n++;
          if(n == m_bpr)
          {
            n = 0;
            x = m_offHex;
            y += m_lineHeight;
          }
        }
        dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
        dc.SetBkColor(GetSysColor(COLOR_HIGHLIGHT));
        for(; (i < selEnd) && (i < *m_length) && (y < height); i++)
        {
          LPTSTR p = buf;
          TOHEX((*m_pData)[i], p);
          *p++ = _T (' ');
          dc.TextOut(x, y, buf, 3);
          x += m_nullWidth * 3;
          n++;
          if(n == m_bpr)
          {
            n = 0;
            x = m_offHex;
            y += m_lineHeight;
          }
        }
        dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
        dc.SetBkColor(GetSysColor(COLOR_WINDOW));
        for(; (i < *m_length) && (y < height); i++)
        {
          LPTSTR p = buf;
          TOHEX((*m_pData)[i], p);
          *p++ = _T (' ');
          dc.TextOut(x, y, buf, 3);
          x += m_nullWidth * 3;
          n++;
          if(n == m_bpr)
          {
            n = 0;
            x = m_offHex;
            y += m_lineHeight;
          }
        }
      }
      else
      {
        for(int  i = m_topindex; (i < *m_length) && (rcd.TopLeft().y < height);)
        {
          LPTSTR p = buf;
          for(int  n = 0; (n < m_bpr) && (i < *m_length); n++)
          {
            TOHEX((*m_pData)[i], p);
            *p++ = _T (' ');
            i++;
          }
          while(n < m_bpr)
          {
            *p++ = _T (' '); *p++ = _T (' '); *p++ = _T (' ');
            n++;
          }

          dc.DrawText(buf, m_bpr*3, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
          rcd.TopLeft().y += m_lineHeight;
        }
      }
    }
    if(m_dwFlags & HVW_SHOW_ASCII)
    {
      y = 0;
      CRect rcd = rc;
      rcd.TopLeft().x = x = m_offAscii;
      if(m_selStart != 0xffffffff && m_currentMode == EDIT_ASCII)
      {
        int  i;
        int  n = 0;
        int  selStart = m_selStart, selEnd = m_selEnd;
        if(selStart > selEnd)
          selStart ^= selEnd ^= selStart ^= selEnd;

        for(i = m_topindex; (i < selStart) && (y < height); i++)
        {
          buf[0] = isprint((*m_pData)[i]) ? (*m_pData)[i] : _T ('.');
          dc.TextOut(x, y, buf, 1);
          x += m_nullWidth;
          n++;
          if(n == m_bpr)
          {
            n = 0;
            x = m_offAscii;
            y += m_lineHeight;
          }
        }
        dc.SetTextColor(GetSysColor(COLOR_HIGHLIGHTTEXT));
        dc.SetBkColor(GetSysColor(COLOR_HIGHLIGHT));
        for(; (i < selEnd) && (y < height); i++)
        {
          buf[0] = isprint((*m_pData)[i]) ? (*m_pData)[i] : _T ('.');
          dc.TextOut(x, y, buf, 1);
          x += m_nullWidth;
          n++;
          if(n == m_bpr)
          {
            n = 0;
            x = m_offAscii;
            y += m_lineHeight;
          }
        }
        dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
        dc.SetBkColor(GetSysColor(COLOR_WINDOW));
        for(; (i < *m_length) && y < height; i++)
        {
          buf[0] = isprint((*m_pData)[i]) ? (*m_pData)[i] : _T ('.');
          dc.TextOut(x, y, buf, 1);
          x += m_nullWidth;
          n++;
          if(n == m_bpr)
          {
            n = 0;
            x = m_offAscii;
            y += m_lineHeight;
          }
        }
      }
      else
      {
        for(int  i = m_topindex; (i < *m_length) && (rcd.TopLeft().y < height);)
        {
          LPTSTR p = buf;
          for(int  n = 0; (n < m_bpr) && (i < *m_length); n++)
          {
            *p++ = isprint((*m_pData)[i]) ? (*m_pData)[i] : _T ('.');
            i++;
          }
          dc.DrawText(buf, n, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
          rcd.TopLeft().y += m_lineHeight;
        }
      }
    }
  }
  pdc.BitBlt(0, 0, rc.Width(), rc.Height(), &dc, 0, 0, SRCCOPY);
}

void CHexEditView::OnSetFocus(CWnd* pOldWnd) 
{
  if(m_pData && *m_pData && !IsSelected())
  {
    if(m_editPos.x == 0 && (m_dwFlags & HVW_SHOW_ADDRESS))
      CreateAddressCaret();
    else
      CreateEditCaret();
    SetCaretPos(m_editPos);
    ShowCaret();
  }
  CWnd::OnSetFocus(pOldWnd);
}

void CHexEditView::OnKillFocus(CWnd* pNewWnd) 
{
  DestroyCaret();
  CWnd::OnKillFocus(pNewWnd);
}

void CHexEditView::OnSize(UINT nType, int cx, int cy) 
{
  CView::OnSize(nType, cx, cy);
}

void CHexEditView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
  pScrollBar;
  if(!m_pData || !*m_pData)
    return;

  int oa = m_topindex;
  switch(nSBCode)
  {
    case SB_LINEDOWN:
      if(m_topindex < *m_length - m_lpp*m_bpr)
      {
        //ScrollWindow(0, -m_lineHeight, rc);
        m_topindex += m_bpr;
        RedrawWindow();
      }
      break;
    
    case SB_LINEUP:
      if(m_topindex > 0)
      {
        //ScrollWindow(0, m_lineHeight, rc);
        m_topindex -= m_bpr;
        RedrawWindow();
      }
      break;
    
    case SB_PAGEDOWN:
      if(m_topindex < *m_length - m_lpp*m_bpr)
      {
        m_topindex += m_bpr * m_lpp;
        if(m_topindex > *m_length - m_lpp*m_bpr)
          m_topindex = *m_length - m_lpp*m_bpr;
        RedrawWindow();
      }
      break;

    case SB_PAGEUP:
      if(m_topindex > 0)
      {
        m_topindex -= m_bpr * m_lpp;
        if(m_topindex < 0)
          m_topindex = 0;
        RedrawWindow();
      }
      break;

    case SB_THUMBTRACK:
      m_topindex = nPos * m_bpr;
      RedrawWindow();
      break;
  }
  ::SetScrollPos(this->m_hWnd, SB_VERT, m_topindex / m_bpr, TRUE);
  if(!(m_dwFlags & HVW_NO_ADDRESS_CHANGE))
    m_currentAddress += (m_topindex - oa);
  RepositionCaret(m_currentAddress);
}

void CHexEditView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
  nSBCode;nPos; pScrollBar;
}

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

BOOL CHexEditView::PreCreateWindow(CREATESTRUCT& cs) 
{
  // cs.style |= WS_HSCROLL|WS_VSCROLL;
  // cs.style &= ~(WS_HSCROLL|WS_VSCROLL);
  return CView::PreCreateWindow(cs);
}

BOOL CHexEditView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
  // dwStyle |= WS_HSCROLL|WS_VSCROLL;
  dwStyle &= ~(WS_HSCROLL|WS_VSCROLL);
  BOOL bRet = CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
  if(bRet)
    SetFont(&m_Font);
  return bRet;
}

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

void CHexEditView::GetOptions(BOOL &a, BOOL &h, BOOL &c, BOOL &w, BOOL &r)
{
  a = (m_dwFlags & HVW_SHOW_ADDRESS) != 0;
  h = (m_dwFlags & HVW_SHOW_HEX) != 0;
  c = (m_dwFlags & HVW_SHOW_ASCII) != 0;
  w = (m_dwFlags & HVW_WIDE_ADDRESS) != 0;
  r = (m_dwFlags & HVW_READ_ONLY) != 0;
}

void CHexEditView::SetOptions(BOOL a, BOOL h, BOOL c, BOOL w, BOOL r)
{
  if (a)
    m_dwFlags |= HVW_SHOW_ADDRESS;
  else
    m_dwFlags &= ~HVW_SHOW_ADDRESS;
  if (h)
    m_dwFlags |= HVW_SHOW_HEX;
  else
    m_dwFlags &= ~HVW_SHOW_HEX;
  if (c)
    m_dwFlags |= HVW_SHOW_ASCII;
  else
    m_dwFlags &= ~HVW_SHOW_ASCII;
  if (w)
    m_dwFlags |= HVW_WIDE_ADDRESS;
  else
    m_dwFlags &= ~HVW_WIDE_ADDRESS;
  if (r)
    m_dwFlags |= HVW_READ_ONLY;

⌨️ 快捷键说明

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