繼承 TConversion 覆寫 ConvertReadStream,將二進位資料流轉為十六進位文字 (含位址、ASCII 碼、字元顯示),再向 TRichEdit 註冊副檔名關聯。
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)
{
if (nBufSize <= 82) return 0; // 緩衝區太小
String strTemp;
unsigned char szDstBuffer[16];
int n = pStream->Read(szDstBuffer, 16);
if (n == 0) return 0;
// 位址 (8 位十六進位)
strTemp = strTemp.sprintf("%.8xh: ", pStream->Position);
// 十六進位位元組 (四個一組)
for (int i = 0; i < n; i++) {
strTemp += IntToHex(szDstBuffer[i], 2) + " ";
if ((i+1) % 4 == 0) strTemp += " ";
}
// 補齊空白至固定寬度
strTemp += String(' ', 65 - strTemp.Length()) + "; ";
// ASCII 字元顯示 (不可列印顯示 '.')
for (int i = 0; i < n; i++) {
if (szDstBuffer[i] < 32 || szDstBuffer[i] > 126) szDstBuffer[i] = '.';
strTemp += (char)szDstBuffer[i];
}
strTemp += "\n";
strcpy(pSrcBuffer, strTemp.c_str());
int nResult = strTemp.Length();
// 顯示載入進度 (自訂函數)
Form1->Process(pStream->Position);
Application->ProcessMessages();
return nResult;
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
RichEdit1->RegisterConversionFormat(NULL, "bin", __classid(THexConversion));
RichEdit1->RegisterConversionFormat(NULL, "obj", __classid(THexConversion));
RichEdit1->RegisterConversionFormat(NULL, "exe", __classid(THexConversion));
}
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 = "載入完成!";
}
RegisterConversionFormat 讓 RichEdit 遇到指定副檔名時實例化對應 TConversion 衍生類別處理資料流。ConvertReadStream 每次讀取 16 位元組轉為一行十六進位文字,回傳寫入緩衝區的字元數。Application->ProcessMessages() 保持介面回應並更新進度。