ファイルを16進数で表示

VC++ で Command Line で指定されたファイル名を取得して、記録されている内容を List Box に16進数で表示します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プロジェクトの設定

  1. 新規プロジェクト(DlgXtype)を作成します。
    ページ先頭の画像を参考にして DialogBoxを作成します。
    [OK] [キャンセル] ボタンを削除して、Dialog Box 全体に [ListBox] を貼り付けて下さい。
    ListBox のIDが IDC_LIST1(規定値)になっていることを確認して下さい。
    表示する文字幅を揃えるために DialogBox のフォントを設定します。
    DialogBox のプロパティから [一般] [フォントボタン] をクリックして [MSゴシック] を選択して下さい。
    Pフォントが設定されていると文字の幅がそろいません。
  2. DlgXtype.cpp と my.lib と my.h をフォルダーに格納してプロジェクトに加えて下さい。
    my.lib に登録されている DATAFILE Object Class を使っています。
    読者諸氏が作成するときは Object Class Library から次のファイルを取得してプロジェクトに組み込んで下さい。
    ファイル名 説明
    datafile.h DATAFILE Object Class のヘッダファイル
    datafile.cpp DATAFILE Object Class のプログラムファイル
  3. ビルドに続いて実行を行います。
    Command Line にファイル名が指定されていないときは GetOpenFileName() でファイルを選択します。
    ListBox にファイルの内容が16進数で表示されたら完成です。

プログラムの説明

  1. g_buf[2000][16] の16は一行分のバイト数で32Kバイトの領域を確保しています。
    ファイルが大きいときは先頭から32Kバイトだけが読み込まれます。
    DATAFILE DataFile; で DATAFILE Object を定義します。
    work は文字列を編集するためのワークエリアです。
        #include    <windows.h>
        #include    "my.h"
        #include    "resource.h"
    
        DATAFILE    DataFile;
        char        work[48];
        char        g_buf[2000][16];
        
  2. WinMain() の先頭でファイルがドラッグ&ドロップされているかを調べます。
    ファイルがドラッグ&ドロップされていないときはファイル選択画面から選びます。
    指定されたファイルを g_buf に入力して DialogBox を表示します。
        int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE, LPSTR lpCmdLine, int)
        {
            if (lpCmdLine!=NULL && *lpCmdLine!='\0')
                   DataFile.ReadData(lpCmdLine, g_buf[0], 32000);
            else   DataFile.OpenReadData(".",g_buf[0], 32000);
            if (DataFile.dwBytes==0)    return FALSE;
            DialogBox(hInst,MAKEINTRESOURCE(IDD_DIALOG1),NULL,(DLGPROC)DlgProc);
            return TRUE;
        }
        
  3. WM_INITDIALOG: には DialogBox の初期化のときに制御が渡されます。
    InitDlgProc() で g_buf から一行ずつ16進数に変換して ListBox に登録します。
        switch(msg)
        {   case WM_INITDIALOG:
                InitDlgProc(hDlg);
                break;
        
  4. 入力したバイト数を16で割った表示行数(ListBox の件数)を cnt に格納します。
    work は一行分の編集領域で、先頭部分にファイル内のオフセットを16進数で格納します。
    オフセットに続いて1バイトずつ16進数に変換して work に編集するのですが、連続して格納すると 表示が見にくいので4バイトごとに空白を一個、8バイトごとに空白を二個あけています。
    ListBox に登録するデータ形式は文字列で、文字列の終わりには '\0' を設定します。
    一行分の編集が完了した work を SendMessage() で ListBox に登録します。
    最後の SendMessage() はカーソルを ListBox の先頭行に位置づけるコードです。
    ListBox に対する SendMessage の説明は List Box で名簿の削除と追加 を参照して下さい。
        int InitDlgProc(HWND hDlg)
        {   int     cnt,i,j,pos;
    
            cnt= DataFile.dwBytes/16+1;
            for(i=0; i<cnt; i++)
            {   wsprintf(work,"%4X  ",i);
                for(j=0; j<16 && i*16+j<(int)DataFile.dwBytes; j++)
                {   pos= j*2+j/8+j/4+6;
                    wsprintf(work+pos,"%02X  ",(BYTE)g_buf[i][j]);
                }
                work[pos+2]= '\0';
                SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_INSERTSTRING,(WPARAM)i,(LPARAM)work);
            }
            SendMessage(GetDlgItem(hDlg,IDC_LIST1),LB_SETCURSEL,0L,0L);
            return cnt;
        }
        
  5. 【注意】このプログラムは最近のシステムに対応していません。
    名前に特殊文字や空白が使えるようになり、両側が「””」で囲まれて渡されるようになりました。
    「””」で囲まれているときは、これを取り除いてファイルをオープンして下さい。

超初心者の方のために全ソースコードを掲載します。 (^_^;)
全ソースコード

超初心者のプログラム入門(Win32API C++)