山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他UNLHA32.DLLを使用した基本的な圧縮・解凍のサンプルプログラム(32bit)
概要
ある業務ソフトのアップデート処理のための専用のソフトを開発するために、LZHファイルの解凍をサポートする必要がありました。
本プログラムは、LZHファイルの圧縮・解凍を行います。
圧縮するファイル及び圧縮結果のLZHファイル、解凍するLZHファイル、解凍先はソースコードの文字列で記述しています。
現在、LHAはサポートを中止しているので、過去の遺産を処理する以外の新規採用は推奨しない。
UNLHA32.DLLは以下のホームページよりダウンロードできる。
Micco's HomePage http://micco.mars.jp/mysoft/unlha32.htm
本プログラムは、LZHファイルの圧縮・解凍を行います。
圧縮するファイル及び圧縮結果のLZHファイル、解凍するLZHファイル、解凍先はソースコードの文字列で記述しています。
現在、LHAはサポートを中止しているので、過去の遺産を処理する以外の新規採用は推奨しない。
UNLHA32.DLLは以下のホームページよりダウンロードできる。
Micco's HomePage http://micco.mars.jp/mysoft/unlha32.htm
テスト環境
コンパイラ
Visual C++ 2008/2013 Express 32bit マルチバイト/UNICODE実行環境
Windows 7 Enterprise Service Pack 1 64bit(Sandy Bridge-E)プログラムソースの概要
本プログラムは、UNLHA32.DLLを動的に呼び出しますので、DLLのロードや関数へのポインタの取得などが必要となります。
定形処理なので、クラス化しました。
カレントフォルダーにある1.txt 2.txt ファイルを圧縮しtest.lzhに保存します。
test.lzhファイルを解凍し、D:\testフォルダーに解凍します。
圧縮や解凍はUnLha関数を呼び出すことにより実行します。
UnLha(const HWND _hwnd, LPCSTR _szCmdLine, LPSTR _szOutput, const DWORD _dwSize);
戻り値は0の場合正常終了です。
オプションの詳細は、lha.exeを検索してください。
DLLロード及び関数へのポインタの取得を行います。
すでにLZHファイルが存在する場合は、ファイルを追加します。
複数のファイルをダブルコーテーションで囲まれ空白で区切られた1つの文字列に変換するために必要なメモリサイズを引数szで指定します。
ファイルが大量に存在する場合、かなりのメモリ容量が必要なので、動的に確保するようにしました。szを省略した場合4096バイトとなります。
UNICODEでコンパイルした場合、WideCharToMultiByte APIによりSJISに変換して、UnLha関数を呼び出します。 outstr配列はUnLha関数の実行時のメッセージが保存されます。
dtcDirフォルダが存在しない場合は、ダイアログボックスが表示され、フォルダを作成するかどうか尋ねてきます。
UNICODEでコンパイルした場合、WideCharToMultiByte APIによりSJISに変換して、UnLha関数を呼び出します。 outstr配列はUnLha関数の実行時のメッセージが保存されます。
ライブラリの解放を行います。
packメンバー関数により圧縮、extractメンバー関数により解凍を行います。
定形処理なので、クラス化しました。
カレントフォルダーにある1.txt 2.txt ファイルを圧縮しtest.lzhに保存します。
test.lzhファイルを解凍し、D:\testフォルダーに解凍します。
UNLHA32.DLLの使い方
DLLを動的に呼び出す場合、LoadLibrary APIによりDLLを呼び出し、GetProcAddress APIにより関数へのポインタを取得します。圧縮や解凍はUnLha関数を呼び出すことにより実行します。
UnLha(const HWND _hwnd, LPCSTR _szCmdLine, LPSTR _szOutput, const DWORD _dwSize);
戻り値は0の場合正常終了です。
hWnd
親ウィンドウのハンドルです。親ハンドルがない場合は0を指定します。szCmdLine
lha.exeと同形式のコマンドラインオプションを指定します。UNICODE文字列の場合はシフトJISに変換してから渡します。オプションの詳細は、lha.exeを検索してください。
圧縮する場合
以下の様に記述します。ソースファイルは空白で複数指定できます。空白を含むファイル名の場合はダブルコーテーションでくくります。uが圧縮を示し、-a1はファイルの属性を保存することを指定しています。
u -a1 LZHファイル名 ソースファイル
解凍する場合
以下の様に記述します。空白を含むファイル名の場合はダブルコーテーションでくくります。eが解凍示し、-a1はファイルの属性を再現(日付等)することを指定しています。
e -a1 LZHファイル名 展開先フォルダー
szOutput
UNLHA32.DLLの実行結果の文字列が保存されます。dwSize
szOutputの大きさを設定します。クラス UnLhaLib
DLLのロード・解放及び関数へのポインタの取得及びUNICODE/マルチバイトによる圧縮・解凍をサポートします。コンストラクター UnLhaLib
UnLhaLibのオブジェクトの初期化時に自動的に呼び出されます。DLLロード及び関数へのポインタの取得を行います。
Init
UNLHA32.DLL及び関数が使用可能どうかを返します。圧縮 pack
srcDirフォルダとsrcFilesで指定された複数のファイルを圧縮し、lzhFileで指定したファイルに保存します。すでにLZHファイルが存在する場合は、ファイルを追加します。
複数のファイルをダブルコーテーションで囲まれ空白で区切られた1つの文字列に変換するために必要なメモリサイズを引数szで指定します。
ファイルが大量に存在する場合、かなりのメモリ容量が必要なので、動的に確保するようにしました。szを省略した場合4096バイトとなります。
UNICODEでコンパイルした場合、WideCharToMultiByte APIによりSJISに変換して、UnLha関数を呼び出します。 outstr配列はUnLha関数の実行時のメッセージが保存されます。
解凍 extract
srcFileで指定されたLZHファイルをdtcDirフォルダに解凍します。dtcDirフォルダが存在しない場合は、ダイアログボックスが表示され、フォルダを作成するかどうか尋ねてきます。
UNICODEでコンパイルした場合、WideCharToMultiByte APIによりSJISに変換して、UnLha関数を呼び出します。 outstr配列はUnLha関数の実行時のメッセージが保存されます。
デストラクタ ~UnLhaLib
UnLhaLibオブジェクトが解放される前に自動的に呼び出されます。ライブラリの解放を行います。
_tWinMain
UnLhaLibオブジェクトを作成し、Initメンバ関数によりUNLHA32.DLLが使用可能かどうかを確認します。packメンバー関数により圧縮、extractメンバー関数により解凍を行います。
ソースコード
// UNLHA32.DLLを使用した基本的な圧縮・解凍のサンプルプログラム
// Visual C++ 2008/2013 Unicode/マルチバイト 32bit専用
// UNLHA32.DLL ダウンロード先 http://micco.mars.jp/mysoft/unlha32.htm
// インストルール先 Windows 32bit C:\Program Files\ArchiverDll\UNLHA32
// インストルール先 Windows 64bit C:\Program Files (x86)\ArchiverDll\UNLHA32
#ifdef _WIN64
#error 64bitでコンパイルするとUNLHA32.DLLが使用できません
#endif
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
class UnLhaLib{
typedef int (WINAPI *UNLHAFUNC)(const HWND _hwnd, LPCSTR _szCmdLine, LPSTR _szOutput, const DWORD _dwSize);
HINSTANCE hMod;
UNLHAFUNC UnlhaFunc;
public:
UnLhaLib(){
UnlhaFunc=0;
hMod = LoadLibrary(_TEXT("unlha32.dll"));
if(hMod==0)
UnlhaFunc=0;
else
UnlhaFunc = (UNLHAFUNC)GetProcAddress(hMod,"Unlha");
}
// UNLHA.DLLが使用可能かチェックする
bool Init(void){
return UnlhaFunc==0 ? false : true;
}
~UnLhaLib(){
if(hMod)
FreeLibrary(hMod);
}
// 圧縮
int pack(HWND hWnd,TCHAR* lzhFile,TCHAR* srcDir,TCHAR** srcFiles,int sz=0){
char outstr[32768];
int ret;
outstr[0]='\0';
if(sz==0)
sz=4096;
TCHAR* cmd=new TCHAR[sz];
if(cmd==0)
return -1;
_stprintf_s(cmd,sz,_TEXT("u -a1 \"%s\" \"%s\""),lzhFile,srcDir);
TCHAR** p=srcFiles;
TCHAR file[MAX_PATH+2];
while(*p){
_stprintf_s(file,sizeof(file)/sizeof(TCHAR),_TEXT(" \"%s\""),*p);
_tcscat_s(cmd,sz,file);
++p;
}
#ifdef UNICODE
char* cmd_sjis=new char[sz];
if(cmd_sjis==0){
delete []cmd;
return -1;
}
WideCharToMultiByte(932,0,cmd,-1,cmd_sjis,sizeof(cmd_sjis),NULL,NULL);
ret= (*UnlhaFunc)(hWnd, cmd_sjis, outstr ,32767);
delete []cmd_sjis;
#else
ret= (*UnlhaFunc)(hWnd, cmd, outstr ,32767);
#endif
delete []cmd;
return ret;
}
// 解凍
int extract(HWND hWnd,TCHAR* dtcDir,TCHAR* srcFile){
char outstr[32768];
outstr[0] = '\0';
TCHAR cmd[MAX_PATH*2+8];
_stprintf_s(cmd,sizeof(cmd)/sizeof(TCHAR),_TEXT("e -a1 \"%s\" \"%s\""),srcFile,dtcDir);
#ifdef UNICODE
char cmd_sjis[sizeof(cmd)];
WideCharToMultiByte(932,0,cmd,-1,cmd_sjis,sizeof(cmd_sjis),NULL,NULL);
return (*UnlhaFunc)(hWnd, cmd_sjis, outstr ,32767);
#else
return (*UnlhaFunc)(hWnd, cmd, outstr ,32767);
#endif
}
};
// 圧縮するファイルを指定
TCHAR* packSrcFiles[]={ _TEXT("1.txt"),_TEXT("2.txt"),0 };
// 圧縮結果を保存するLZHファイルを指定
TCHAR* packLzhFile=_TEXT("test.lzh");
// 圧縮するファイルのディレクトリを指定
TCHAR* packSrcDir=_TEXT("");
// 解凍するLZHファイルを指定
TCHAR* extractSrcFile=_TEXT("test.lzh");
// 解凍先ディレクトリを指定
TCHAR* extractDtcDir=_TEXT("d:\\test\\");
int WINAPI _tWinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,TCHAR* lpsCmdLine, int nCmdShow){
UnLhaLib lha;
if(lha.Init()==false){
MessageBox(0,_TEXT("UNLHA32.DLLが使用できません。"),_TEXT("エラー"),MB_OK);
return 1;
}
if(lha.pack(0,packLzhFile,packSrcDir,packSrcFiles,0)!=0){
MessageBox(0,_TEXT("UNLHA32.DLL::Unlha関数 圧縮中にエラーが発生しました。"),_TEXT("エラー"),MB_OK);
return 2;
}
if(lha.extract(0,extractDtcDir,extractSrcFile)!=0){
MessageBox(0,_TEXT("UNLHA32.DLL::Unlha関数 解凍中にエラーが発生しました。"),_TEXT("エラー"),MB_OK);
return 3;
}
return 0;
}
Copyright (C) 2012 山本ワールド All Rights Reserved.