LHA で圧縮された TEXT を表示



LHA で圧縮された TEXT ファイルを解凍して表示します。
吉崎栄泰氏が開発された unlha32 をダウンロードすれば簡単です。

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

ライブラリの準備

  1. 吉崎栄泰氏が開発された unlha32 をダウンロードして下さい。
    unlha32 をキーにして、検索サイトで調べればすぐ見つかるはずです。
  2. ダウンロードしたファイルを解凍して下さい。
    プログラム作成に必要なのは次のファイルです。
    ファイル名 説明
    unlhavc.lib コンパイルのとき使用する LIB ファイルです
    unlha32.h コンパイルのとき使用する Lib Header ファイルです
    unlha32.dll 実行時に呼び出される DLL ファイルです
  3. 私がダウンロードしたファイルは、自己解凍型の ulh3189.exe で、これを規定値のまま実行すると下記のフォルダーにファイル一式が格納されました。
    c:\Program File\ArchiverDll\UNLHA32
  4. UNLHA32.TXT にファイルの説明がされています。
    UNLHA32.LIB はボーランド C++ 用なので間違えないようにして下さい。

アプリケーションの作成

  1. [ファイル] [新規作成] [プロジェクト] から新規プロジェクト(LzhTxt)を作成します。
    ダウンロードした unlhavc.lib, unlha32.h, unlha32.dll をプロジェクトのフォルダーに格納して下さい。
  2. test.lzh を用意します。
    この圧縮ファイルには次のファイルを格納します。
    buf[] の領域は 512 バイトしか確保していないので、それぞれのファイルサイズは 512 バイト以下にして下さい。
    file_a.txt
    file_b.txt
    file_c.txt
    1. file_a.txt の例です。
      filea.txt
      aaaaaaaaaaaaaaaaaaaaa
      bbbbbbbbbbbbbbbbb
      ccccccccccccc
      ddddddddddddddddddddddddddd
      eeeeeeeeeeeeeeeeeeeeeee
      fffffffff
      gggggggggggggggggggggggggggggggg
      
    2. file_b.txt の例です。
      fileb.txt
      HHHHHHHHHHHHH
      IIIIIIIIIIIIIIIIII
      JJJJJJJ
      KKKKKKKKKKKKKKKKKKKKKKKKKK
      LLLLLLLLLLLLL
      MMMMMMMMMMMMMMMMMM
      NNNNNNNNNNNNNNNNNNNNN
      
    3. file_c.txt の例です。
      filec.txt
      000000000000000000000000
      1111111111111111
      22222222222222222222222
      333333333
      444444444444
      555555555555555555
      
  3. [プロジェクト] [プロパティ] [リンカ] [入力] から unlhavc.lib をリンクします。
    #pragma を使ってリンクすることもできます。
  4. 次のメニューを追加します。
    IDM_FILE_A: FILE_Aの表示(&A)
    IDM_FILE_B: FILE_Bの表示(&B)
    IDM_FILE_C: FILE_Cの表示(&C)
  5. StdAfx.h に次のファイルを取り込んで下さい。
    time.h を後にすると、unlha32.h でエラーが表示されます。
        #include <time.h>
        #include "unlha32.h"
        
  6. テンプレートで作成された LzhTxt.cpp のソースコードを修正します。
          BYTE    buf[512];
          DWORD   dLen;
        
  7. LzhTxt.cpp の修正の続きです。
    WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {                       :
                            :
        switch( message ) 
        {   case WM_COMMAND:
                            :
                            :
                switch( wmId )
                {           :
                    case IDM_FILE_A:
                        UnlhaExtractMem(hWnd,"test.lzh c: file_a.txt",buf,512,NULL,NULL,&dLen);
                        buf[dLen] = '\0';
                        MessageBox(NULL, (const char *)buf, "LHA file_a.txt", MB_OK);
                        break;
                    case IDM_FILE_B:
                        UnlhaExtractMem(hWnd,"test.lzh c: file_b.txt",buf,512,NULL,NULL,&dLen);
                        buf[dLen] = '\0';
                        MessageBox(NULL, (const char *)buf, "LHA file_b.txt", MB_OK);
                        break;
                    case IDM_FILE_C:
                        UnlhaExtractMem(hWnd,"test.lzh c: file_c.txt",buf,512,NULL,NULL,&dLen);
                        buf[dLen] = '\0';
                        MessageBox(NULL, (const char *)buf, "LHA file_c.txt", MB_OK);
                        break;
    
  8. [デバッグ] [デバッグなしで開始] を選択して、ビルド(コンパイル)に続いて実行を行います。
    コンパイルの進行状況とエラーがあれば、エラーメッセージが表示されます。
    メニューから「FILE_Aの表示」を選び、ページ先頭の画面が表示されたら完成です。

プログラムの説明

  1. LZH を解凍してメモリに格納するだけなら簡単です。
    UnlhaExtractMem() 関数を呼び出すだけです。
    dLen には LZH を解凍してメモリ展開したサイズが格納されます。
          case IDM_FILE_A:
              UnlhaExtractMem(hWnd,"test.lzh c: file_a.txt",buf,512,NULL,NULL,&dLen);
              buf[dLen] = '\0';
              MessageBox(NULL, (const char *)buf, "LHA file_a.txt", MB_OK);
              break;
        
  2. unlha32.dll には LZH を操作する関数が多数登録されていて、API 関数の仕様は c:\Program Files\ArchiverDll\UNLHA32\API.TXT に記載されています。
    UnlhaExtractMem() 関数は次のように説明されています。
    -----------------------------------------------------------------------
    %o      int WINAPI UnlhaExtractMem(const HWND _hwnd, LPCSTR _szCmdLine,
                    LPBYTE _szBuffer, const DWORD _dwSize, time_t *_lpTime,
                    LPWORD _lpwAttr, LPDWORD _lpdwWriteSize)
    -----------------------------------------------------------------------
    順序数  49
    機能
            メモリバッファへ展開します。 残念ながら,_lpdwWriteSize で指定
            したサイズごとに複数回に分けて処理…といった使用法は行えません。
    
    引数
            _hwnd       UNLHA32.DLL を呼び出すアプリのウィンドウのハンドル。
                        UNLHA32.DLL は実行時にこのウィンドウに対して EnableWin-
                        dow() を実行しウィンドウの動作を抑制します。ウィンドウ
                        が存在しないコンソールアプリの場合や,指定する必要のな
                        い場合は NULL を渡します。
            _szCmdLine  UNLHA32.DLL に渡すコマンドの文字列。Unlha() と同じもの
                        が指定できますが,コマンドは無視されます。
            _lpBuffer   展開イメージを格納するバッファ。ここで指定するバッファ
                        については,_dwSize で示されるサイズが保証されている必
                        要があります。
            _dwSize     バッファのサイズ。UNLHA32.DLL が返す結果のサイズより指
                        定されたサイズが小さい場合は指定サイズまで出力されます。
            _lpTime     展開されたファイルの UTC でのタイムスタンプを得ます。
                        必要ない場合は NULL を指定します。
            _lpwAttr    展開されたファイルの属性を得ます。 必要ない場合は NULL
                        を指定します。
            _lpdwWriteSize
                        展開の結果書き込まれたサイズを得ます。  必要ない場合は
                        NULL を指定します。
    
    戻り値
            正常終了の時            0。
            エラーが発生した場合    0 以外の数。
    
    その他
            API の性格上,書庫やファイル名にワイルドカードを使うのは無意味と思
            われます。
        
  3. 代表的な関数には次のような物があります。
    1. LHA をオープンします。
      hArc = UnlhaOpenArchive(hWnd, szLZHFile, M_ERROR_MESSAGE_ON);
    2. LHA に格納されている先頭のファイル情報を取得します。
      if (UnlhaFindFirst(hArc, "*.*", &ii) != -1) {
    3. LHA に格納されている次のファイル情報を取得します。
      UnlhaFindNext()
    4. メモリに展開します。
      UnlhaExtractMem()
    5. LHA をクローズします。
      UnlhaCloseArchive(hArc);

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