MFC读取文件并将其显示为HEX(hexdump)

时间:2015-06-03 15:27:14

标签: mfc hexdump

我需要读取二进制文件并在某个偏移量处显示字节,以便我可以更改该字节,然后保存更新的文件。我真的不明白我怎样才能做到这一点。我正在使用MFC / VS 2008

所以,我正在使用WinApi打开文件并将其内容发送到BYTE缓冲区。但我不确定如何在某个偏移处打印数据(例如)编辑框和主要问题 - 如何编辑此数据(如在HEX编辑器中)并保存更新的文件。

 CFileDialog FileDlg(TRUE, "*", "*", OFN_FILEMUSTEXIST);
    if(FileDlg.DoModal() == IDOK)
    {
        CString pathName = FileDlg.GetPathName();
        //MessageBox(pathName, NULL, MB_OK);
        // Implement opening and reading file in here. 
        //Change the window's title to the opened file's title.
        //CString fileName = FileDlg.GetFileTitle();
        //SetWindowText(fileName);
        HANDLE hFile = CreateFile(pathName.GetString(), GENERIC_READ | GENERIC_WRITE, NULL,
            NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
        if(!hFile)
            return;
        DWORD dwSize = GetFileSize(hFile, NULL);
        BYTE *Content = (BYTE *)malloc(dwSize);
        DWORD dwRead;
        if(!ReadFile(hFile, Content, dwSize, &dwRead, NULL))
            return;

    }

1 个答案:

答案 0 :(得分:1)

这是一个拥有者绘制ListBox(size = fixed-sized,sort = false)

的解决方案
class CListHex : public CListBox
{
public:
    std::vector<BYTE> Buffer;
    CRect SaveItemRect;
    CEdit Edit;
    int Index;

    void setup()
    {
        if (Edit.m_hWnd && IsWindow(Edit.m_hWnd))
            return;
        Edit.Create(WS_CHILD | WS_BORDER | ES_CENTER, CRect(0, 0, 0, 0), this, 1);
        Edit.SetFont(GetFont());
        Edit.SetLimitText(2);
        SetItemHeight(0, 21);
    }

    void read()
    {
        HANDLE hfile = CreateFile(L"in.txt", GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hfile != INVALID_HANDLE_VALUE) //****CHANGED****
        {
            DWORD size = GetFileSize(hfile, NULL);
            Buffer.resize(size);
            ReadFile(hfile, &Buffer[0], size, 0, NULL);
            CloseHandle(hfile);
            for (int i = 0; i <= (int)Buffer.size() / 16; i++)
                AddString(0); 
        }
        else
        {
            MessageBox(L"error");
        }
    }

    void write()
    {
        HANDLE hFile = CreateFile(L"out.txt", GENERIC_WRITE, NULL, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hfile != INVALID_HANDLE_VALUE) //****CHANGED****
        {
            WriteFile(hFile, &Buffer[0], Buffer.size(), 0, 0);
            CloseHandle(hFile);
        }
        else
        {
            MessageBox(L"error");
        }
    }

    void DrawItem(LPDRAWITEMSTRUCT di)
    {
        SaveItemRect = di->rcItem;
        CRect r = di->rcItem;
        r.right = r.left + r.Width() / 16;

        HBRUSH brush = (HBRUSH)SelectObject(di->hDC, GetStockObject(WHITE_BRUSH));
        FillRect(di->hDC, &di->rcItem, brush);

        for (int i = 0; i < 16; i++)
        {
            unsigned int cursor = di->itemID * 16 + i;
            if (cursor >= Buffer.size())
                break;
            CString s;
            s.Format(L"%02X", Buffer[cursor]);
            DrawText(di->hDC, s, s.GetLength(), r, DT_EDITCONTROL|DT_CENTER|DT_VCENTER|DT_SINGLELINE);
        }
    }

    void OnLButtonDown(UINT f, CPoint p)
    {
        CListBox::OnLButtonDown(f, p);
        setup();

        int w = SaveItemRect.Width() / 16;
        CRect r = SaveItemRect;
        r.right = r.left + w;
        for (int i = 0; i < 16; i++)
        {
            if (r.PtInRect(p))
            {
                unsigned int index = GetCurSel() * 16 + i;
                if (index >= Buffer.size())
                    return;
                Index = index;
                GetParent()->SetRedraw(0);
                CString s;
                s.Format(L"%02X", Buffer[Index]);
                Edit.SetWindowText(s);
                Edit.SetWindowPos(0, r.left, r.top, r.Width(), r.Height(), SWP_NOZORDER | SWP_NOREDRAW | SWP_SHOWWINDOW);
                Edit.SetFocus();
                GetParent()->SetRedraw(1);
                break;
            }
            r.OffsetRect(w, 0);
        }
    }

    //******CHANGED******       
    void MeasureItem(LPMEASUREITEMSTRUCT m) { m->itemHeight=21; }
    int  CompareItem(LPCOMPAREITEMSTRUCT) { return 0; }
    //******CHANGED******       

    DECLARE_MESSAGE_MAP()
};

BEGIN_MESSAGE_MAP(CListHex, CListBox)
    ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

此外,

  • 您可以为CEdit
  • 添加子类
  • 覆盖CMyEdit::OnKillFocus()以关闭编辑框
  • 覆盖CMyEdit::OnChar仅接受十六进制字符
  • 阅读编辑字符串,然后转换为unsigned char并将其分配给Buffer[Index]
  • 覆盖CListHex::OnVScroll以关闭编辑框

<强> // CHANGED:

要创建函数,请尝试手动执行,以确保它获得正确的标志:

list.Create(WS_VSCROLL | WS_BORDER | WS_CHILD | WS_VISIBLE | LBS_USETABSTOPS | LBS_OWNERDRAWFIXED , CRect(10, 10, 450, 350), this, 1001); list.read();