解决方案 »

  1.   

    http://www.codeproject.com/Articles/457/frhed-free-hex-editor
      

  2.   


    思路:建个单文档MFC程序,点击打开文件,把文件数据按二进制读出存到变量并转换成字符串,写到视图客户区
      

  3.   

    不做选中效果和修改效果比较简单弄个单文档, 加载文件。 根据文件大小设置滚动条,然后根据滚动条位置在OnDraw里画出来就好了。
      

  4.   

    .h文件/////////////////////////////////////////////////////////////////////////////
    // CNXHexEdit window
    #if !defined(CNXHexEdit_H__D5E20CE5_DB96_4a1e_A14C_D75167087C6D__INCLUDED_)
    #define CNXHexEdit_H__D5E20CE5_DB96_4a1e_A14C_D75167087C6D__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000class CNXHexEdit : public CEdit
    {
    // Construction
    public:
    CNXHexEdit(); enum EDITMODE{
    EDIT_NONE,
    EDIT_ASCII,
    EDIT_HIGH,
    EDIT_LOW
    } ;
    // Attributes
    public:
    LPBYTE m_pData; // pointer to data
    int m_length; // length of data
    int m_topindex; // offset of first visible byte on screen int m_currentAddress; // address under cursor
    EDITMODE m_currentMode; // current editing mode: address/hex/ascii
    int m_selStart; // start address of selection
    int m_selEnd; // end address of selection int m_bpr; // byte per row 
    int m_lpp; // lines per page
    BOOL m_bShowAddress;
    BOOL m_bShowAscii;
    BOOL m_bShowHex;
    BOOL m_bAddressIsWide;

    BOOL m_bNoAddressChange; // internally used
    BOOL m_bHalfPage;

    CFont m_Font;
    int m_lineHeight;
    int m_nullWidth;
    BOOL m_bUpdate; int m_offHex,
    m_offAscii,
    m_offAddress; CPoint m_editPos;// Operations
    public:// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CNXHexEdit)
    public:
    virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
    protected:
    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    //}}AFX_VIRTUAL// Implementation
    public:
    int GetData(LPBYTE p, int len);
    void SetData(LPBYTE p, int len);
    CSize GetSel(void);
    void SetSel(int s, int e);
    void SetBPR(int bpr);
    void SetOptions(BOOL a, BOOL h, BOOL c, BOOL w);
    virtual ~CNXHexEdit(); // Generated message map functions
    protected:
    void ScrollIntoView(int p);
    void RepositionCaret(int p);
    void Move(int x, int y);
    inline BOOL IsSelected(void);
    void UpdateScrollbars(void);
    void CreateEditCaret(void);
    void CreateAddressCaret(void);
    CPoint CalcPos(int x, int y);
    void SelInsert(int s, int l);
    void SelDelete(int s, int e);
    inline void NormalizeSel(void);
    afx_msg void OnContextMenu(CWnd*, CPoint point);
    //{{AFX_MSG(CNXHexEdit)
    afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
    afx_msg void OnKillFocus(CWnd* pNewWnd);
    afx_msg void OnPaint();
    afx_msg void OnSetFocus(CWnd* pOldWnd);
    afx_msg void OnSize(UINT nType, int cx, int cy);
    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
    afx_msg UINT OnGetDlgCode();
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
    afx_msg void OnEditClear();
    afx_msg void OnEditCopy();
    afx_msg void OnEditCut();
    afx_msg void OnEditPaste();
    afx_msg void OnEditSelectAll();
    afx_msg void OnEditUndo();
    //}}AFX_MSG DECLARE_MESSAGE_MAP()
    };#endif
      

  5.   

    .cpp文件// HexEdit.cpp : Defines the class behaviors for the application.
    //#include "stdafx.h"
    #include "HexEditCtrl.h"
    #include <ctype.h>
    #include <afxole.h>
    #include <afxdisp.h>
    #include "resource.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    char hextable[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    #define TOHEX(a, b) {*b++ = hextable[a >> 4];*b++ = hextable[a&0xf];}
    /////////////////////////////////////////////////////////////////////////////
    // CNXHexEditCNXHexEdit::CNXHexEdit()
    {
    #if !defined(DEMO)
    m_pData = NULL; // pointer to data
    m_length = 0; // length of data
    #else
    m_pData = (LPBYTE)malloc(0x40);
    for(int i = 0; i < 0x40; i++)
    m_pData[i] = i;
    #endif
    m_length = 0x40;
    m_topindex = 0;
    m_bpr = 8; // byte per row 
    m_lpp = 1; m_bShowHex = TRUE;
    m_bShowAscii = TRUE;
    m_bShowAddress = TRUE;
    m_bAddressIsWide= TRUE; // 4/8 byte address m_offAddress = 0;
    m_offHex = 0;
    m_offAscii = 0; m_bUpdate = TRUE; // update font info
    m_bNoAddressChange = FALSE;
    m_currentMode = EDIT_NONE; m_editPos.x = m_editPos.y = 0;
    m_currentAddress = 0;
    m_bHalfPage = TRUE; m_selStart = 0xffffffff;
    m_selEnd = 0xffffffff; m_Font.CreateFont(-12, 0,0,0,0,0,0,0,0,0,0,0,0, "Courier New"); AfxOleInit();
    }CNXHexEdit::~CNXHexEdit()
    {
    }
    BEGIN_MESSAGE_MAP(CNXHexEdit, CEdit)
    ON_WM_CONTEXTMENU()
    //{{AFX_MSG_MAP(CNXHexEdit)
    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)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CNXHexEdit message handlers
    void CNXHexEdit::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;
    char buf[256]; x = rc.TopLeft().x;
    y = rc.TopLeft().y; dc.SetBoundsRect(&rc, DCB_DISABLE); if(m_pData)
    {
    //
    // get char dimensions
    //
    if(m_bUpdate)
    {
    dc.GetCharWidth('0', '0', &m_nullWidth);
    CSize sz = dc.GetTextExtent("0", 1);
    m_lineHeight = sz.cy;

    m_offHex = m_bShowAddress ? (m_bAddressIsWide ? m_nullWidth * 9 : m_nullWidth * 5) : 0;
    m_offAscii = m_bShowAddress ? (m_bAddressIsWide ? m_nullWidth * 9 : m_nullWidth * 5) : 0;
    m_offAscii += m_bShowHex  ? (m_bpr * 3 * m_nullWidth) : 0; m_lpp = rc.Height() / m_lineHeight;
    m_bHalfPage = FALSE;
    if(m_lpp * m_bpr > m_length)
    {
    m_lpp = (m_length + (m_bpr/2)) / m_bpr ;
    if(m_length % m_bpr != 0)
    {
    m_bHalfPage = TRUE;
    m_lpp++;
    }
    }
    m_bUpdate = FALSE;
    UpdateScrollbars();
    } TRACE("%i %i\n", m_topindex, m_selStart);

    height = rc.Height() / m_lineHeight;
    height *= m_lineHeight; if(m_bShowAddress)
    {
    char fmt[8] = {'%','0','8','l','X'};
    fmt[2] = m_bAddressIsWide ? '8' : '4';
    int w = m_bAddressIsWide ? 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)
    {
    sprintf(buf, fmt, i);
    dc.DrawText(buf, w, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
    rcd.TopLeft().y += m_lineHeight;
    }
    }
    if(m_bShowHex)
    {
    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++)
    {
    char* p = &buf[0];
    TOHEX(m_pData[i], p);
    *p++ = ' ';
    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++)
    {
    char* p = &buf[0];
    TOHEX(m_pData[i], p);
    *p++ = ' ';
    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++)
    {
    char* p = &buf[0];
    TOHEX(m_pData[i], p);
    *p++ = ' ';
    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);)
    {
    char* p = &buf[0];
    for(int  n = 0; (n < m_bpr) && (i < m_length); n++)
    {
    TOHEX(m_pData[i], p);
    *p++ = ' ';
    i++;
    }
    while(n < m_bpr)
    {
    *p++ = ' '; *p++ = ' '; *p++ = ' ';
    n++;
    } dc.DrawText(buf, m_bpr*3, rcd, DT_LEFT|DT_TOP|DT_SINGLELINE|DT_NOPREFIX);
    rcd.TopLeft().y += m_lineHeight;
    }
    }
    }
    if(m_bShowAscii)
    {
    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] : '.';
    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] : '.';
    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] : '.';
    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);)
    {
    char* p = &buf[0];
    for(int  n = 0; (n < m_bpr) && (i < m_length); n++)
    {
    *p++ = isprint(m_pData[i]) ? m_pData[i] : '.';
    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 CNXHexEdit::OnSetFocus(CWnd* pOldWnd) 
    {
    if(m_pData && !IsSelected())
    {
    if(m_editPos.x == 0 && m_bShowAddress)
    CreateAddressCaret();
    else
    CreateEditCaret();
    SetCaretPos(m_editPos);
    ShowCaret();
    }
    CWnd::OnSetFocus(pOldWnd);
    }void CNXHexEdit::OnKillFocus(CWnd* pNewWnd) 
    {
    DestroyCaret();
    CWnd::OnKillFocus(pNewWnd);
    }void CNXHexEdit::OnSize(UINT nType, int cx, int cy) 
    {
    CEdit::OnSize(nType, cx, cy);
    }void CNXHexEdit::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
    {
    pScrollBar;
    if(!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_bNoAddressChange)
    m_currentAddress += (m_topindex - oa);
    RepositionCaret(m_currentAddress);
    }void CNXHexEdit::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
    {
    nSBCode;nPos; pScrollBar;
    }UINT CNXHexEdit::OnGetDlgCode() 
    {
    return DLGC_WANTALLKEYS;
    }BOOL CNXHexEdit::PreCreateWindow(CREATESTRUCT& cs) 
    {
    cs.style |= WS_HSCROLL|WS_VSCROLL;
    return CEdit::PreCreateWindow(cs);
    }BOOL CNXHexEdit::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
    {
    dwStyle |= WS_HSCROLL|WS_VSCROLL;
    BOOL bRet = CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
    if(bRet)
    SetFont(&m_Font);
    return bRet;
    }
      

  6.   

    BOOL CNXHexEdit::OnEraseBkgnd(CDC* pDC) 
    {
    pDC;
    return TRUE;
    }void CNXHexEdit::SetOptions(BOOL a, BOOL h, BOOL c, BOOL w)
    {
    m_bShowHex = h;
    m_bShowAscii = c;
    m_bShowAddress = a;
    m_bAddressIsWide= w; // 4/8 byte address
    m_bUpdate = TRUE;
    }void CNXHexEdit::SetBPR(int bpr)
    {
    m_bpr = bpr;
    m_bUpdate = TRUE;
    }void CNXHexEdit::OnLButtonDown(UINT nFlags, CPoint point) 
    {
    SetFocus();
    if(!m_pData)
    return; if(nFlags & MK_SHIFT)
    {
    m_selStart = m_currentAddress;
    }
    CPoint pt = CalcPos(point.x, point.y);
    if(pt.x > -1)
    {
    m_editPos = pt;
    pt.x *= m_nullWidth;
    pt.y *= m_lineHeight;

    if(pt.x == 0 && m_bShowAddress)
    CreateAddressCaret();
    else
    CreateEditCaret(); SetCaretPos(pt);
    if(nFlags & MK_SHIFT)
    {
    m_selEnd = m_currentAddress;
    if(m_currentMode == EDIT_HIGH || m_currentMode == EDIT_LOW)
    m_selEnd++;
    RedrawWindow();
    }
    }
    if(!(nFlags & MK_SHIFT))
    {
    if(DragDetect(this->m_hWnd, point))
    {
    m_selStart = m_currentAddress;
    m_selEnd   = m_selStart;
    SetCapture();
    }
    else
    {
    BOOL bsel = m_selStart != 0xffffffff; m_selStart = 0xffffffff;
    m_selEnd   = 0xffffffff;
    if(bsel)
    RedrawWindow();
    }
    }
    if(!IsSelected())
    {
    ShowCaret();
    }
    }void CNXHexEdit::OnLButtonDblClk(UINT nFlags, CPoint point) 
    {
    nFlags; point;
    }CPoint CNXHexEdit::CalcPos(int x, int y)
    {
    y /= m_lineHeight;
    if(y < 0 || y > m_lpp)
    return CPoint(-1, -1); if(y * m_bpr > m_length)
    return CPoint(-1, -1); x += m_nullWidth;
    x /= m_nullWidth; int xp; if(m_bShowAddress && x <= (m_bAddressIsWide ? 8 : 4))
    {
    m_currentAddress = m_topindex + (m_bpr * y);
    m_currentMode = EDIT_NONE;
    return CPoint(0, y);
    } xp = (m_offHex  / m_nullWidth) + m_bpr * 3;
    if(m_bShowHex && x < xp)
    {
    if(x%3)
    x--;
    m_currentAddress = m_topindex + (m_bpr * y) + (x - (m_offHex  / m_nullWidth)) / 3;
    m_currentMode =  ((x%3) & 0x01) ? EDIT_LOW : EDIT_HIGH;
    return CPoint(x, y);
    } xp = (m_offAscii  / m_nullWidth) + m_bpr;
    if(m_bShowAscii && x <= xp)
    {
    m_currentAddress = m_topindex + (m_bpr * y) + (x - (m_offAscii  / m_nullWidth));
    m_currentMode = EDIT_ASCII;
    return CPoint(x, y);
    } return CPoint(-1,-1);
    }void CNXHexEdit::CreateAddressCaret()
    {
    DestroyCaret();
    CreateSolidCaret(m_nullWidth * (m_bAddressIsWide ? 8 : 4), m_lineHeight);
    }void CNXHexEdit::CreateEditCaret()
    {
    DestroyCaret();
    CreateSolidCaret(m_nullWidth, m_lineHeight);
    }void CNXHexEdit::OnMouseMove(UINT nFlags, CPoint point) 
    {
    if(!m_pData)
    return; if(nFlags & MK_LBUTTON && m_selStart != 0xffffffff)
    {
    CRect rc;
    GetClientRect(&rc);
    if(!rc.PtInRect(point))
    {
    if(point.y < 0)
    {
    OnVScroll(SB_LINEUP, 0, NULL);
    point.y = 0;
    }
    else if(point.y > rc.Height())
    {
    OnVScroll(SB_LINEDOWN, 0, NULL);
    point.y = rc.Height() -1;
    }
    } //
    // we are selecting
    //
    int  seo = m_selEnd;
    CPoint pt = CalcPos(point.x, point.y);
    if(pt.x > -1)
    {
    m_selEnd = m_currentAddress;
    if(m_currentMode == EDIT_HIGH || m_currentMode == EDIT_LOW)
    m_selEnd++;
    }
    if(IsSelected())
    DestroyCaret(); if(seo != m_selEnd)
    RedrawWindow();
    }
    }void CNXHexEdit::UpdateScrollbars()
    {
    SCROLLINFO si; si.cbSize = sizeof(SCROLLINFO);
    si.fMask = SIF_ALL;
    si.nMin = 0;
    si.nMax = (m_length / m_bpr) - 1;
    si.nPage = m_lpp;
    si.nPos = m_topindex / m_bpr; ::SetScrollInfo(this->m_hWnd, SB_VERT, &si, TRUE);
    if(si.nMax > (int)si.nPage)
    ::EnableScrollBar(this->m_hWnd, SB_VERT, ESB_ENABLE_BOTH); CRect rc;
    GetClientRect(&rc); si.nMin = 0;
    si.nMax =((m_bShowAddress ? (m_bAddressIsWide ? 8 : 4) : 0) +
      (m_bShowHex ? m_bpr * 3 : 0) +
      (m_bShowAscii ? m_bpr : 0) ) * m_nullWidth;
    si.nPage = 1;
    si.nPos = 0;
    ::SetScrollInfo(this->m_hWnd, SB_HORZ, &si, TRUE);
    }
    inline BOOL CNXHexEdit::IsSelected()
    {
    return m_selStart != 0xffffffff;
    }void CNXHexEdit::OnLButtonUp(UINT nFlags, CPoint point) 
    {
    if(IsSelected())
    ReleaseCapture(); CWnd::OnLButtonUp(nFlags, point);
    }void CNXHexEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
    {
    nFlags;nRepCnt;
    if(!m_pData)
    return;
    if(nChar == '\t')
    return;
    if(GetKeyState(VK_CONTROL) & 0x80000000)
    {
    switch(nChar)
    {
    case 0x03:
    if(IsSelected())
    OnEditCopy();
    return;
    case 0x16:
    OnEditPaste();
    return;
    case 0x18:
    if(IsSelected())
    OnEditCut();
    return;
    case 0x1a:
    OnEditUndo();
    return;
    }
    } if(nChar == 0x08)
    {
    if(m_currentAddress > 0)
    {
    m_currentAddress--;
    SelDelete(m_currentAddress, m_currentAddress+1);
    RepositionCaret(m_currentAddress);
    RedrawWindow();
    }
    return;
    } SetSel(-1, -1);
    switch(m_currentMode)
    {
    case EDIT_NONE:
    return;
    case EDIT_HIGH:
    case EDIT_LOW:
    if((nChar >= '0' && nChar <= '9') || (nChar >= 'a' && nChar <= 'f'))
    {
    UINT b = nChar - '0';
    if(b > 9) 
    b = 10 + nChar - 'a'; if(m_currentMode == EDIT_HIGH)
    {
    m_pData[m_currentAddress] = (unsigned char)((m_pData[m_currentAddress] & 0x0f) | (b << 4));
    }
    else
    {
    m_pData[m_currentAddress] = (unsigned char)((m_pData[m_currentAddress] & 0xf0) | b);
    }
    Move(1,0);
    }
    break;
    case EDIT_ASCII:
    m_pData[m_currentAddress] = (unsigned char)nChar;
    Move(1,0);
    break;
    }
    RedrawWindow();
    }void CNXHexEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
    {
    nFlags; nRepCnt; BOOL bShift = GetKeyState(VK_SHIFT) & 0x80000000;
    BOOL bac = m_bNoAddressChange;
    m_bNoAddressChange = TRUE;
    switch(nChar)
    {
    case VK_DOWN:
    if(bShift)
    {
    if(!IsSelected())
    {
    m_selStart = m_currentAddress;
    }
    Move(0,1);
    m_selEnd   = m_currentAddress;
    if(m_currentMode == EDIT_HIGH || m_currentMode == EDIT_LOW)
    m_selEnd++;
    RedrawWindow();
    break;
    }
    else
    SetSel(-1, -1);
    Move(0,1);
    break;
    case VK_UP:
    if(bShift)
    {
    if(!IsSelected())
    {
    m_selStart = m_currentAddress;
    }
    Move(0,-1);
    m_selEnd   = m_currentAddress;
    RedrawWindow();
    break;
    }
    else
    SetSel(-1, -1);
    Move(0,-1);
    break;
    case VK_LEFT:
    if(bShift)
    {
    if(!IsSelected())
    {
    m_selStart = m_currentAddress;
    }
    Move(-1,0);
    m_selEnd   = m_currentAddress;
    RedrawWindow();
    break;
    }
    else
    SetSel(-1, -1);
    Move(-1,0);
    break;
    case VK_RIGHT:
    if(bShift)
    {
    if(!IsSelected())
    {
    m_selStart = m_currentAddress;
    }
    Move(1,0);
    m_selEnd   = m_currentAddress;
    if(m_currentMode == EDIT_HIGH || m_currentMode == EDIT_LOW)
    m_selEnd++;
    RedrawWindow();
    break;
    }
    else
    SetSel(-1, -1);
    Move(1,0);
    break;
    case VK_PRIOR:
    if(bShift)
    {
    if(!IsSelected())
    {
    m_selStart = m_currentAddress;
    }
    OnVScroll(SB_PAGEUP, 0, NULL);
    Move(0,0);
    m_selEnd   = m_currentAddress;
    RedrawWindow();
    break;
    }
    else
    SetSel(-1, -1);
    OnVScroll(SB_PAGEUP, 0, NULL);
    Move(0,0);
    break;
    case VK_NEXT:
    if(bShift)
    {
    if(!IsSelected())
    {
    m_selStart = m_currentAddress;
    }
    OnVScroll(SB_PAGEDOWN, 0, NULL);
    Move(0,0);
    m_selEnd   = m_currentAddress;
    RedrawWindow();
    break;
    }
    else
    SetSel(-1, -1);
    OnVScroll(SB_PAGEDOWN, 0, NULL);
    Move(0,0);
    break;
    case VK_HOME:
    if(bShift)
    {
    if(!IsSelected())
    {
    m_selStart = m_currentAddress;
    }
    if(GetKeyState(VK_CONTROL) & 0x80000000)
    {
    OnVScroll(SB_THUMBTRACK, 0, NULL);
    Move(0,0);
    }
    else
    {
    m_currentAddress /= m_bpr;
    m_currentAddress *= m_bpr;
    Move(0,0);
    }
    m_selEnd   = m_currentAddress;
    RedrawWindow();
    break;
    }
    else
    SetSel(-1, -1);
    if(GetKeyState(VK_CONTROL) & 0x80000000)
    {
    OnVScroll(SB_THUMBTRACK, 0, NULL);
    m_currentAddress = 0;
    Move(0,0);
    }
    else
    {
    m_currentAddress /= m_bpr;
    m_currentAddress *= m_bpr;
    Move(0,0);
    }
    break;
    case VK_END:
    if(bShift)
    {
    if(!IsSelected())
    {
    m_selStart = m_currentAddress;
    }
    if(GetKeyState(VK_CONTROL) & 0x80000000)
    {
    m_currentAddress = m_length-1;
    OnVScroll(SB_THUMBTRACK, ((m_length+(m_bpr/2)) / m_bpr) - m_lpp, NULL);
    Move(0,0);
    }
    else
    {
    m_currentAddress /= m_bpr;
    m_currentAddress *= m_bpr;
    m_currentAddress += m_bpr - 1;
    if(m_currentAddress > m_length)
    m_currentAddress = m_length-1;
    Move(0,0);
    }
    m_selEnd   = m_currentAddress;
    RedrawWindow();
    break;
    }
    else
    SetSel(-1, -1);
    if(GetKeyState(VK_CONTROL) & 0x80000000)
    {
    m_currentAddress = m_length-1;
    if(m_bHalfPage)
    OnVScroll(SB_THUMBTRACK, 0, NULL);
    else
    OnVScroll(SB_THUMBTRACK, ((m_length+(m_bpr/2)) / m_bpr) - m_lpp, NULL);
    Move(0,0);
    }
    else
    {
    m_currentAddress /= m_bpr;
    m_currentAddress *= m_bpr;
    m_currentAddress += m_bpr - 1;
    if(m_currentAddress > m_length)
    m_currentAddress = m_length-1;
    Move(0,0);
    }
    break;
    case VK_INSERT:
    SelInsert(m_currentAddress, max(1, m_selEnd-m_selStart));
    RedrawWindow();
    break;
    case VK_DELETE:
    if(IsSelected())
    {
    OnEditClear();
    }
    else
    {
    SelDelete(m_currentAddress, m_currentAddress+1);
    RedrawWindow();
    }
    break;
    case '\t':
    switch(m_currentMode)
    {
    case EDIT_NONE:
    m_currentMode = EDIT_HIGH;
    break;
    case EDIT_HIGH:
    case EDIT_LOW:
    m_currentMode = EDIT_ASCII;
    break;
    case EDIT_ASCII:
    m_currentMode = EDIT_HIGH;
    break;
    }
    Move(0,0);
    break; }
    m_bNoAddressChange = bac;
    }
      

  7.   


    CNXHexEdit m_Edit;DDX_Control(pDX, IDC_HEXEDITCTRL1, m_Edit);//初始化HEXEDIT
    m_Edit.SetOptions(TRUE, TRUE, TRUE, TRUE);
    m_Edit.SetBPR(16);
    m_Edit.RedrawWindow();//设置数据
    m_Edit.SetData(BYTE*, int);
    m_Edit.RedrawWindow();
      

  8.   

    .cpp余下的内容
    void CNXHexEdit::Move(int x, int y)
    {
    switch(m_currentMode)
    {
    case EDIT_NONE:
    return;
    case EDIT_HIGH:
    if(x != 0)
    m_currentMode = EDIT_LOW;
    if(x == -1)
    m_currentAddress --;
    m_currentAddress += y* m_bpr;
    break;
    case EDIT_LOW:
    if(x != 0)
    m_currentMode = EDIT_HIGH;
    if(x == 1)
    m_currentAddress++;
    m_currentAddress += y* m_bpr;
    break;
    case EDIT_ASCII:
    {
    m_currentAddress += x;
    m_currentAddress += y*m_bpr;
    }
    break;
    }
    if(m_currentAddress < 0)
    m_currentAddress = 0; if(m_currentAddress >= m_length)
    {
    m_currentAddress -= x;
    m_currentAddress -= y*m_bpr;
    }
    m_bNoAddressChange = TRUE;
    if(m_currentAddress < m_topindex)
    {
    OnVScroll(SB_LINEUP, 0, NULL);
    }
    if(m_currentAddress >= m_topindex + m_lpp*m_bpr)
    {
    OnVScroll(SB_LINEDOWN, 0, NULL);
    }
    m_bNoAddressChange = FALSE;
    //ScrollIntoView(m_currentAddress);
    RepositionCaret(m_currentAddress);
    }void CNXHexEdit::SetSel(int s, int e)
    {
    DestroyCaret();
    m_selStart = s;
    m_selEnd = e;
    RedrawWindow();
    if(m_editPos.x == 0 && m_bShowAddress)
    CreateAddressCaret();
    else
    CreateEditCaret();
    SetCaretPos(m_editPos);
    ShowCaret();
    }void CNXHexEdit::RepositionCaret(int  p)
    {
    int x, y; y = (p - m_topindex) / m_bpr;
    x = (p - m_topindex) % m_bpr; switch(m_currentMode)
    {
    case EDIT_NONE:
    CreateAddressCaret();
    x = 0;
    break;
    case EDIT_HIGH:
    CreateEditCaret();
    x *= m_nullWidth*3;
    x += m_offHex;
    break;
    case EDIT_LOW:
    CreateEditCaret();
    x *= m_nullWidth*3;
    x += m_nullWidth;
    x += m_offHex;
    break;
    case EDIT_ASCII:
    CreateEditCaret();
    x *= m_nullWidth;
    x += m_offAscii;
    break;
    }
    m_editPos.x = x;
    m_editPos.y = y*m_lineHeight;
    CRect rc;
    GetClientRect(&rc);
    if(rc.PtInRect(m_editPos))
    {
    SetCaretPos(m_editPos);
    ShowCaret();
    }
    }void CNXHexEdit::ScrollIntoView(int p)
    {
    if(p < m_topindex || p > m_topindex + m_lpp*m_bpr)
    {
    m_topindex = (p/m_bpr) * m_bpr;
    m_topindex -= (m_lpp / 3) * m_bpr;
    if(m_topindex < 0)
    m_topindex = 0; UpdateScrollbars();
    RedrawWindow();
    }
    }void CNXHexEdit::OnContextMenu(CWnd*, CPoint point)
    { // CG: This block was added by the Pop-up Menu component
    {
    if (point.x == -1 && point.y == -1)
    {
    //keystroke invocation
    CRect rect;
    GetClientRect(rect);
    ClientToScreen(rect); point = rect.TopLeft();
    point.Offset(5, 5);
    } CMenu menu;
    VERIFY(menu.LoadMenu(CG_IDR_POPUP_HEX_EDIT)); CMenu* pPopup = menu.GetSubMenu(0);
    ASSERT(pPopup != NULL); pPopup->EnableMenuItem(ID_EDIT_UNDO, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
    if(!IsSelected())
    {
    pPopup->EnableMenuItem(ID_EDIT_CLEAR, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
    pPopup->EnableMenuItem(ID_EDIT_CUT, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
    pPopup->EnableMenuItem(ID_EDIT_COPY, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
    }
    {
    COleDataObject obj;
    if (obj.AttachClipboard()) 
    {
    if(!obj.IsDataAvailable(CF_TEXT) && !obj.IsDataAvailable(RegisterClipboardFormat("BinaryData")))
    pPopup->EnableMenuItem(ID_EDIT_PASTE, MF_GRAYED|MF_DISABLED|MF_BYCOMMAND);
    }
    } pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
    this);
    }
    }void CNXHexEdit::OnEditClear() 
    {
    m_currentAddress = m_selStart;
    SelDelete(m_selStart, m_selEnd);
    RepositionCaret(m_currentAddress);
    RedrawWindow();
    }void CNXHexEdit::OnEditCopy() 
    {
    COleDataSource* pSource = new COleDataSource();
    EmptyClipboard();
    if(m_currentMode != EDIT_ASCII)
    {
    int dwLen = (m_selEnd-m_selStart);
    HGLOBAL hMemb = ::GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT, m_selEnd-m_selStart);
    HGLOBAL hMema = ::GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT, (dwLen) * 3); if (!hMema) 
    return; // copy binary
    LPBYTE p = (BYTE*)::GlobalLock(hMemb);
    memcpy(p, m_pData+m_selStart, dwLen);
    ::GlobalUnlock(hMemb);

    // copy ascii
    p = (BYTE*)::GlobalLock(hMema);
    for(int  i = 0; i < dwLen;)
    {
    TOHEX(m_pData[m_selStart+i], p);
    *p++ = ' ';
    i++;
    } ::GlobalUnlock(hMema); pSource->CacheGlobalData(RegisterClipboardFormat("BinaryData"), hMemb);
    pSource->CacheGlobalData(CF_TEXT, hMema);
    }
    else
    {
    HGLOBAL hMemb = ::GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT, m_selEnd-m_selStart);
    HGLOBAL hMema = ::GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT, m_selEnd-m_selStart);
    if (!hMemb || !hMema) 
    return; // copy binary
    LPBYTE p = (BYTE*)::GlobalLock(hMemb);
    int dwLen = m_selEnd-m_selStart; memcpy(p, m_pData+m_selStart, dwLen);
    ::GlobalUnlock(hMemb);

    // copy ascii
    p = (BYTE*)::GlobalLock(hMema);
    memcpy(p, m_pData+m_selStart, dwLen);
    for(int i = 0; i < dwLen; p++, i++)
    if(!isprint(*p))
    *p = '.';
    ::GlobalUnlock(hMema); pSource->CacheGlobalData(RegisterClipboardFormat("BinaryData"), hMemb);
    pSource->CacheGlobalData(CF_TEXT, hMema);
    }
    pSource->SetClipboard();
    }void CNXHexEdit::OnEditCut() 
    {
    OnEditCopy();
    SelDelete(m_selStart, m_selEnd);
    RedrawWindow();
    }void CNXHexEdit::OnEditPaste() 
    {
    COleDataObject obj;
    if (obj.AttachClipboard()) 
    {
    HGLOBAL hmem = NULL;
    if (obj.IsDataAvailable(RegisterClipboardFormat("BinaryData"))) 
    {
    hmem = obj.GetGlobalData(RegisterClipboardFormat("BinaryData"));
    }
    else if (obj.IsDataAvailable(CF_TEXT)) 
    {
    hmem = obj.GetGlobalData(CF_TEXT);
    }
    if(hmem)
    {
    LPBYTE p = (BYTE*)::GlobalLock(hmem);
    DWORD dwLen = ::GlobalSize(hmem);
    int insert;
    int oa = m_currentAddress;

    NormalizeSel();
    if(m_selStart == 0xffffffff)
    {
    if(m_currentMode == EDIT_LOW)
    m_currentAddress++;
    insert = m_currentAddress;
    SelInsert(m_currentAddress, dwLen);
    }
    else
    {
    insert = m_selStart;
    SelDelete(m_selStart, m_selEnd);
    SelInsert(insert, dwLen);
    SetSel(-1, -1);
    } memcpy(m_pData+insert, p, dwLen); m_currentAddress = oa;
    RedrawWindow();
    ::GlobalUnlock(hmem);
    }
    }
    }void CNXHexEdit::OnEditSelectAll() 
    {
    m_selStart = 0;
    m_selEnd = m_length;
    DestroyCaret();
    RedrawWindow();
    }void CNXHexEdit::OnEditUndo() 
    {
    // TODO: Add your command handler code here

    }void CNXHexEdit::NormalizeSel()
    {
    if(m_selStart > m_selEnd)
    m_selStart ^= m_selEnd ^= m_selStart ^= m_selEnd;
    }void CNXHexEdit::SelDelete(int s, int e)
    {
    LPBYTE p = (LPBYTE) malloc(m_length - (e-s)+1);
    memcpy(p, m_pData, s);
    if(s < m_length-(e-s)) 
    memcpy(p+s, m_pData+e, (m_length -e));

    free(m_pData);
    SetSel(-1, -1);
    m_pData = p;
    m_length = m_length-(e-s);
    if(m_currentAddress > m_length)
    {
    m_currentAddress = m_length;
    RepositionCaret(m_currentAddress);
    }
    m_bUpdate = TRUE;
    }void CNXHexEdit::SelInsert(int s, int l)
    {
    LPBYTE p = (LPBYTE) calloc(m_length + l, 1);
    memcpy(p, m_pData, s);
    memcpy(p+s+l, m_pData+s, (m_length-s));
    free(m_pData);
    SetSel(-1, -1);
    m_pData = p;
    m_length = m_length+l;
    m_bUpdate = TRUE;
    }CSize CNXHexEdit::GetSel()
    {
    return CSize(m_selStart, m_selEnd);
    }void CNXHexEdit::SetData(LPBYTE p, int len)
    {
    free(m_pData);

    m_pData = (LPBYTE) malloc(len);
    memcpy(m_pData, p, len); //SetSel(-1, -1);
    m_length = len;
    m_currentAddress = 0;
    m_editPos.x = m_editPos.y = 0;
    m_currentMode = EDIT_HIGH;
    m_topindex = 0;
    m_bUpdate = TRUE;
    }int CNXHexEdit::GetData(LPBYTE p, int len)
    {
    memcpy(p, m_pData, min(len, m_length));
    return m_length;
    }
      

  9.   

    fatal error C1083: Cannot open include file: 'resource.h': No such file or directory
    Error executing cl.exe.  提示这个错误。 
      

  10.   


    大哥怎么用?
    还没发完,你不说找到了,要结帖了吗?
    你#include "HexEditCtrl.h"这个头文件是啥啊?
      

  11.   

    #include "HexEditCtrl.h"
    是指上面的.H文件名称,你存成啥名就改成啥名。你用的是MFC吧,resource.h就是你的资源定义头文件,有些找不到定义,是因为,这个控件里,有个右键编辑菜单,你要是不要,把相应的代码删除就可以了下面是菜单资源的定义,如果需要右键菜单,你就对照加到你的资源里:
    CG_IDR_POPUP_HEX_EDIT MENU DISCARDABLE 
    BEGIN
        POPUP "_POPUP_"
        BEGIN
            MENUITEM "&Undo",                       ID_EDIT_UNDO
            MENUITEM SEPARATOR
            MENUITEM "Cu&t",                        ID_EDIT_CUT
            MENUITEM "&Copy",                       ID_EDIT_COPY
            MENUITEM "&Paste",                      ID_EDIT_PASTE
            MENUITEM "&Delete",                     ID_EDIT_CLEAR
            MENUITEM SEPARATOR
            MENUITEM "Select &All",                 ID_EDIT_SELECT_ALL
        END
    END