首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

C++Builder 實現 TRichEdit 自動十六進制檢視器

     編輯:VC 教學

前言

當使用 TRichEdit 開啟二進位檔(如 .exe、.obj、.bin)時,預設會嘗試以文字方式解碼,導致顯示亂碼。本文示範如何繼承 TConversion 類別並覆寫 ConvertReadStream,註冊自訂轉換格式,讓 RichEdit 自動將指定副檔名的檔案以十六進制檢視器模式呈現——類似 UltraEdit 的經典十六進制檢視格式:位址、十六進位位元組、ASCII 字元對照。

核心類別:THexConversion

//---------------------------------------------------------------------------
// 從 TConversion 衍生自訂轉換類別
class THexConversion : public TConversion
{
public:
    virtual int __fastcall ConvertReadStream(TStream *pStream,
        char *pSrcBuffer, int nBufSize);
};
//---------------------------------------------------------------------------

// 覆寫讀取串流轉換邏輯
int __fastcall THexConversion::ConvertReadStream(TStream *pStream,
    char *pSrcBuffer, int nBufSize)
{
    String strTemp;
    unsigned char szDstBuffer[16];
    int n, nResult;

    // 緩衝區太小直接返回
    if (nBufSize <= 82) return 0;

    // 1. 顯示位址(8 位十六進位 + "h: ")
    strTemp = strTemp.sprintf("%.8xh: ", pStream->Position);

    // 2. 讀取 16 位元組
    n = pStream->Read(szDstBuffer, 16);
    if (n == 0) return 0;

    // 3. 十六進位位元組,每 4 組加一空格
    for (int i = 0; i < n; i++)
    {
        AppendStr(strTemp, IntToHex(szDstBuffer[i], 2) + ' ');
        if ((i + 1) % 4 == 0) AppendStr(strTemp, ' ');
    }

    // 4. 填充對齊至固定寬度
    String str;
    str.StringOfChar(' ', 65 - strTemp.Length());
    AppendStr(strTemp, str + "; ");

    // 5. ASCII 字元區:可列印字元顯示原字,否則顯示 '.'
    for (int i = 0; i < n; i++)
    {
        if ((szDstBuffer[i] < 32) || (szDstBuffer[i] > 126))
            szDstBuffer[i] = '.';
        AppendStr(strTemp, (char)szDstBuffer[i]);
    }

    AppendStr(strTemp, "\n");
    StrCopy(pSrcBuffer, strTemp.c_str());
    nResult = strTemp.Length();

    // 6. 回報進度(選用)
    Form1->Process(pStream->Position);
    Application->ProcessMessages();

    return nResult;
}

註冊轉換格式

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    // 將 bin、obj、exe 三種副檔名關聯至 THexConversion
    RichEdit1->RegisterConversionFormat(NULL, "bin", __classid(THexConversion));
    RichEdit1->RegisterConversionFormat(NULL, "obj", __classid(THexConversion));
    RichEdit1->RegisterConversionFormat(NULL, "exe", __classid(THexConversion));
}

進度回報輔助函式

// 表單類別需宣告:void __fastcall Process(int nPos);
void __fastcall TForm1::Process(int nPos)
{
    StatusBar1->SimpleText = "正在處理... " + String(nPos);
    StatusBar1->Update();
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    RichEdit1->Lines->LoadFromFile("C:\\123\\123.exe");
    StatusBar1->SimpleText = "載入完成!";
}

關鍵技術點解析

技術點說明
TConversion 機制RichEdit 內建的串流轉換架構,支援依副檔名動態掛載自訂解碼器。
ConvertReadStream核心虛擬函式,負責從 TStream 讀取原始位元組並轉換為 RichEdit 可顯示的文字緩衝區。
固定 16 位元組區塊模仿標準十六進位編輯器排版,每行 16 位元組,便於人眼對照位址與內容。
ASCII 過濾將控制字元(<32)與擴展 ASCII(>126)替換為 '.',避免亂碼干擾閱讀。
進度回報利用 Application->ProcessMessages() 保持 UI 響應,適合大型二進位檔案載入。

擴充應用建議

  • 加入 ConvertWriteStream 實現十六進位編輯後存檔功能。
  • 支援更多副檔名(.dll、.sys、.dat 等)只需多呼叫幾次 RegisterConversionFormat。
  • 結合 FindDialog 實現十六進位模式下的關鍵字/位元組搜尋。
  • 若需效能優化,可改用 TMemoryStream 一次讀入全部資料再分塊格式化。

透過繼承 TConversion,我們以極少的程式碼為 TRichEdit 賦予了專業級十六進位檢視能力,展示了 VCL 架構擴充性的強大與優雅。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved