タイトル : unlha32のコールバックを受け取った時の構造体がおかしい? 投稿日 : 2011/02/05(Sat) 20:41 投稿者 : A.K
こんにちは。 前回 http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?no=10429&reno=no&oya=10429&mode=msgview&page=0 に引き続きの質問で申し訳ないのですが、どうにもよく分からないので質問させて下さい。 前回の質問のソースコードで、UnlhaSetOwnerWindowEx64を使用したコールバックの設定を行いました。 そこで、書庫を解凍する際のコールバックを受け取るために、下記のようなコードを書きました。 (unlhaが返すWM_ARCEXTRACTの値は、あらかじめRegisterWindowMessageで取得済みです) Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message) MyBase.WndProc(m) If m.HWnd = _HWnd Then If m.Msg = wm_arcextractMsg AndAlso m.WParam.ToInt64 = 1 Then 'mode=1:解凍処理 Dim extractingInfo As New EXTRACTINGINFO64 Dim typeHandle As System.RuntimeTypeHandle = System.Type.GetTypeHandle(extractingInfo) Dim extractingInfoType As Type = Type.GetTypeFromHandle(typeHandle) '構造体の取得 extractingInfo = DirectCast(Marshal.PtrToStructure(m.LParam, extractingInfoType), EXTRACTINGINFO64) Debug.Print("SourceFileName : " & extractingInfo.szSourceFileName) Debug.Print("DestFileName : " & extractingInfo.szDestFileName) Debug.Print("FileSize : " & extractingInfo.llFileSize.ToString) Debug.Print("WriteSize : " & extractingInfo.llWriteSize.ToString) End If End If End Sub すると、ファイルサイズがあり得ない程大きくなっていたり、ファイル名の文字が欠けていたりと、extractingInfo構造体から得られる値がおかしくなっていました。 ファイル名の文字は、例えば本来は「あいうえお.jpg」であるべきところ、「うえお.jpg」と戻ってきていたため、「もしかしたら、読み出し位置が32ビット分ずれているのでは?」と思い、EXTRACTINGINFO64の宣言を以下のように書き換えてみたところ、ファイル名・サイズ等の情報が正常に得られるようになりました。 <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=1)> _ Public Structure EXTRACTINGINFO64 ' Public dwStructSize As Integer ←ここをコメントアウトした Public exinfo As EXTRACTINGINFO Public llFileSize As Long Public llCompressedSize As Long Public llWriteSize As Long Public dwAttributes As Integer Public dwCRC As Integer Public uOSType As Integer Public wRatio As Short Public ftCreateTime As Long Public ftAccessTime As Long Public ftWriteTime As Long <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=8)> _ Public szMode As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=513)> _ Public szSourceFileName As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=3)> _ Public dummy1 As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=513)> _ Public szDestFileName As String <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=3)> _ Public dummy As String End Structure これはコールバックを受け取るフォーム側での宣言です。 UnlhaSetOwnerWindowEx64を呼び出す側のクラスでは、コメントアウトを行わないで構造体宣言を行っています つまり、現在 ○unlha32を使って解凍処理を行うクラス EXTRACTINGINFO64の構造を変えずに宣言 UnlhaSetOwnerWindowEx64を使用 ○unlha32のコールバックを受け取るFormクラス EXTRACTINGINFO64の構造を変えて宣言(32バイト切り詰め) という状態にして、ようやく正常に動いている状態です。(これを正常と言えるならですが…) 現状問題ないとはいえ、EXTRACTINGINFO64の宣言が二つあって統一されていないのは気持ち悪いですし、どこか私の方法が間違えているなら直しておきたいです。 当方WinXP、VB2005です。 よろしくお願いします。 どなたか、分かる方がいらっしゃいましたら、よろしくお願いします。 〜UNLHA32 WINMES.TXTより〜 ----------------------------------------------------------------------- %3. ARCHIVERPROC の定義 ----------------------------------------------------------------------- ----------------------------------------------------------------------- BOOL CALLBACK ARCHIVERPROC( HWND _hwnd, UINT _uMsg, UINT _nState, LPVOID _lpEis ); ----------------------------------------------------------------------- 引数 _hwnd UnlhaSetOwnerWindowEx で指定したウィンドウハンド ルが渡されます。 _uMsg 現在のところは wm_arcextract となります。 _nState wm_arcextract の wParam,つまり nMode が格納され ます。 _lpEis 構造体へのポインタです。格納ファイルに関する情報 が得られます。実際には,次のどれかとなります。 LPEXTRACTINGINFOEX _lpEis UnlhaSetOwnerWindowEx() か sizeof(EXTRACTINGINFOEX) を指定して UnlhaSetOwnerWindowEx64() を使用した場合。 LPEXTRACTINGINFOEX32 _lpEis sizeof(EXTRACTINGINFOEX32) を指定して UnlhaSetOwner- WindowEx64() を使用した場合。 LPEXTRACTINGINFOEX64 _lpEis sizeof(EXTRACTINGINFOEX64) を指定して UnlhaSetOwner- WindowEx64() を使用した場合。 戻り値 TRUE UNLHA32.DLL に処理の継続を指示します。 FALSE UNLHA32.DLL に処理を中止させます。 ただし, _nState が 4 の場合 (作業書庫の書き戻し時) は中 止させることができません。 |