MFC读取文件并将其显示为十六进制(hexdump)

MFC读取文件并将其显示为十六进制(hexdump),mfc,hexdump,Mfc,Hexdump,我需要读取二进制文件并以一定的偏移量显示字节,这样我就可以更改这些字节,然后保存更新的文件。我真的不明白我怎样才能做到这一点。我使用的是MFC/VS2008 所以,我正在使用WinApi打开文件,并将其内容放入字节缓冲区。但我不确定如何将数据以一定的偏移量打印到(例如)编辑框和主问题-如何编辑这些数据(如在十六进制编辑器中)并保存更新的文件 CFileDialog FileDlg(TRUE, "*", "*", OFN_FILEMUSTEXIST); if(FileDlg.DoModa

我需要读取二进制文件并以一定的偏移量显示字节,这样我就可以更改这些字节,然后保存更新的文件。我真的不明白我怎样才能做到这一点。我使用的是MFC/VS2008

所以,我正在使用WinApi打开文件,并将其内容放入字节缓冲区。但我不确定如何将数据以一定的偏移量打印到(例如)编辑框和主问题-如何编辑这些数据(如在十六进制编辑器中)并保存更新的文件

 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;

    }

下面是一个具有所有者绘制列表框的解决方案(大小=固定大小,排序=false)

类clistEx:公共CListBox
{
公众:
向量缓冲区;
正确的保存项;
CEdit编辑;
整数指数;
无效设置()
{
if(Edit.m_-hWnd&&IsWindow(Edit.m_-hWnd))
返回;
编辑.创建(WS|u CHILD | WS|u BORDER | ES|u CENTER,CRect(0,0,0),this,1);
Edit.SetFont(GetFont());
编辑.SetLimitText(2);
SetItemHeight(0,21);
}
无效读取()
{
HANDLE hfile=CreateFile(L“in.txt”,通用\u READ,NULL,NULL,OPEN\u EXISTING,FILE\u ATTRIBUTE\u NORMAL,NULL);
如果(hfile!=无效的句柄值)//****已更改****
{
DWORD size=GetFileSize(hfile,NULL);
调整缓冲区大小(大小);
读取文件(hfile,&缓冲区[0],大小,0,空);
闭合手柄(hfile);
对于(int i=0;i rcItem;
正确的r=di->rcItem;
r、 右=右左+右宽度()/16;
HBRUSH笔刷=(HBRUSH)选择对象(di->hDC,GetStockObject(白色笔刷));
FillRect(di->hDC,&di->rcItem,画笔);
对于(int i=0;i<16;i++)
{
无符号int cursor=di->itemID*16+i;
如果(游标>=Buffer.size())
打破
csts;
s、 格式(L“%02X”,缓冲区[光标];
DrawText(di->hDC,s,s.GetLength(),r,DT_EDITCONTROL | DT|u CENTER | DT|u VCENTER | DT|u SINGLELINE);
}
}
仅无效按钮向下(UINT f,CPP点)
{
CListBox::OnLButtonDown(f,p);
设置();
int w=SaveItemRect.Width()/16;
正确的r=SaveItemRect;
r、 右=右+左+西;
对于(int i=0;i<16;i++)
{
如果(r.p.删除(p))
{
unsigned int index=GetCurSel()*16+i;
如果(索引>=Buffer.size())
返回;
指数=指数;
GetParent()->SetRedraw(0);
csts;
s、 格式(L“%02X”,缓冲区[索引]);
编辑.SetWindowText;
编辑.SetWindowPos(0,右左,右上,右宽(),右高(),SWP_NOZORDER | SWP_NOREDRAW | SWP_SHOWWINDOW);
Edit.SetFocus();
GetParent()->SetRedraw(1);
打破
}
r、 偏距(w,0);
}
}
//******已更改******
void MeasureItem(LPMEASUREITEMSTRUCT m){m->itemHeight=21;}
int CompareItem(LPCOMPAREITEMSTRUCT){返回0;}
//******已更改******
声明消息映射()
};
开始消息映射(ClisEx、ClisBox)
关于WM_LBUTTONDOWN()
结束消息映射()
另外,

  • 您可以为
    CEdit
  • 重写
    CMyEdit::OnKillFocus()
    以关闭编辑框
  • 重写
    CMyEdit::OnChar
    以仅接受十六进制字符
  • 读取编辑字符串,然后转换为
    无符号字符
    ,并将其分配给
    缓冲区[索引]
  • 覆盖
    clisEx::OnVScroll
    以关闭编辑框
//更改:

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

list.Create(WS_VSCROLL | WS|u BORDER | WS|u CHILD | WS|u VISIBLE | LBS|USETABSTOPS | LBS|OWNERDRAWFIXED,CRect(10,10,450,350),this,1001);

list.read();

请稍等,我将修正我的问题,使其更加精确。至少显示用于打开文件的代码。若要将字节转换为十六进制表示形式,请使用
sprintf(displaybuf,“%02X”,byte)
其中byte是
char
unsigned char
谢谢,但是如何用这些数据填充editbox并使其像在Hexdump中一样可编辑呢?谢谢,我尝试了第一个带有滚动的多行编辑框的代码片段,现在我看到了文件的十六进制表示形式。现在我将尝试将所有内容放在一起,并使其在我需要的方式。@Barmak Shemirani,当然,我想看看。我更改了答案,旧答案仍然在这里:(滚动到底部查看第一次修订)奇怪的是,我添加了一个列表框,将类声明添加到.h文件,将消息映射添加到.cpp文件(还有用于读写过程的按钮)但当我试图读取文件时,我在void AFXAPI AfxUnlockGlobals(int nLockType)上遇到了调试器错误。这可能是什么?我不确定那是什么错误。我在代码中有几个错误,我应该使用
无效句柄值
检查文件的创建情况(请参阅更新的答案)。还可以尝试使用create手动创建列表框
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()