[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2005/03/01(Tue) 15:41
投稿者名:はこ
Eメール:
URL :
タイトル:
SHFileOperation
いつもお世話になっております。

APIのSHFileOperation関数を使ってFDにファイルをコピーしようとしています。
FDドライブにディスクをセットしていない状態で、SHFileOperaion関数を実行
すると、「Aドライブにディスクを挿入してください」というダイアログが表示
されるのですが、そこでキャンセルボタンをクリックして処理を中止しても、
SHFileOperaion関数の戻り値も、引数SHFILEOPSTRUCTのfAnyOperaionsAbortedも
0になってしまい、正常終了時と同じ結果になってしまいます。

ファイルのコピーダイアログでキャンセルボタンがクリックされると、
fAnyOperationsAborted=1となり判別できるのですが、ディスクの挿入ダイアログでは
やはり判別不可能でしょうか?

ご存知の方いらっしゃいましたら、ご教授ください。
よろしくお願いします。

投稿時間:2005/03/01(Tue) 16:24
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re: SHFileOperation
fAnyOperationsAborted の戻り値の値が1になっているかと思いますが
確認してみて下さい。

投稿時間:2005/03/01(Tue) 16:58
投稿者名:はこ
Eメール:
URL :
タイトル:
Re^2: SHFileOperation
花ちゃんさん

ご回答どうもありがとうございます。

こちらでももうちょっと確認してみました。
すると、WindowsXP SP2の環境ではfAnyOperationsAborted=1と
なりますが、Windows2000 (Server,Pro) SP4の環境では
fAnyOperationsAborted=0となってしまうことがわかりました。

動作環境を記述せずに申し訳ありませんでした。

実際のコードはこちらになります。

Private Sub cmdCopy_Click()
    Dim sh          As SHFILEOPSTRUCT
    Dim bytBuf()    As Byte
    Dim lngRet      As Long
    Dim lngCancel   As Long
    
    'FD出力
    With sh
        .hwnd = Me.hwnd
        .wFunc = FO_COPY
        .pFrom = "C:\test.dat"
        .pTo = "A:\test.dat"
    End With
    lngRet = SHFileOperation(sh)
    
    ReDim bytBuf(LenB(sh)) As Byte
    MoveMemory bytBuf(0), sh, LenB(sh)
    MoveMemory lngCancel, bytBuf(18), Len(lngCancel)
    
    If lngRet = 0 And lngCancel = 0 Then
        MsgBox "コピー完了!"
    End If
End Sub

Windows2000環境で実行すると、最後のIf文の時点でlngRetも
lngCancelも0となり、「コピー完了!」メッセージが表示されて
しまいます。

やはり環境の問題なのでしょうか?

投稿時間:2005/03/01(Tue) 18:02
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^3: SHFileOperation
私は、2000を持っていないので未確認ですが下記のサイトでは
2000でもokのように書いてありますが。

 hhttp://vbvbvb.com/jp/gtips/0951/gSHFileOperationFoCopyAborted.html

又、検索すれば下記のような情報もあります。

hhttp://www.kwi.co.jp/tips1.htm

hhttp://thedailywtf.com/ShowPost.aspx?PostID=29989

投稿時間:2005/03/01(Tue) 22:30
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^3: SHFileOperation
fAnyOperationsAborted As Integer の後続の アライメント調整が必要なのでは?


手元にWin2000環境が無いので確認できませんが、
こんな感じで取得できないでしょうか。

Option Explicit

Private Const FO_COPY As Long = &H2&

Private Type SHFILEOPSTRUCT
    hWnd As Long
    wFunc As Long
    pFrom As String
    pTo As String
    fFlags As Integer
    fAnyOperationsAborted As Long
    hNameMappings As Long
    lpszProgressTitle As String
End Type

'Private Declare Function SHFileOperation Lib "shell32" Alias "SHFileOperationA" _
    (ByRef lpFileOp As SHFILEOPSTRUCT) As Long

Private Declare Function SHFileOperationForBin Lib "shell32" Alias "SHFileOperationA" _
    (ByRef lpFileOp As Byte) As Long

Private Declare Sub MoveMemory Lib "KERNEL32" Alias "RtlMoveMemory" _
    (ByRef Dest As Any, ByRef Source As Any, ByVal length As Long)

Private Sub Form_Load()
    Dim sh          As SHFILEOPSTRUCT
    Dim lngRet      As Long
    
    'FD出力
    With sh
        .hWnd = Me.hWnd
        .wFunc = FO_COPY
        .pFrom = "C:\test.dat"
        .pTo = "A:\test.dat"
    End With
    
    Dim forVB(31) As Byte, forAPI(29) As Byte
    MoveMemory forVB(0), sh, 32
    MoveMemory forAPI(0), forVB(0), 18
    MoveMemory forAPI(18), forVB(20), 12

    lngRet = SHFileOperationForBin(forAPI(0))

    Erase forVB
    MoveMemory forVB(0), forAPI(0), 18
    MoveMemory forVB(20), forAPI(18), 12
    MoveMemory sh, forVB(0), 32
    
    If lngRet = 0 And sh.fAnyOperationsAborted = 0 Then
        MsgBox "コピー完了!"
    End If
End Sub

投稿時間:2005/03/02(Wed) 09:37
投稿者名:はこ
Eメール:
URL :
タイトル:
Re: SHFileOperation
花ちゃんさん
魔界の仮面弁士さん

ご回答どうもありがとうございます。

>花ちゃんさん
実は、花ちゃんさんに教えていただいたのと同じvbvbvb.comのNo.988を
参考にコーディングしていました。
あのHPでは確かにWin2000にも○がついていたので、できないわけがない
と思い、迷宮に迷い込んでいます。

また、2つ目のURLの情報も見たことがありまして。
かなり近い状況なのですが、コピー中ダイアログでキャンセルしたときは
ちゃんとNGが返ってくるし、NT4.0でのバグということなのでちょっと
違うのかな?と思います。
せっかく教えていただいたのにすみません。

魔界の仮面弁士さんに教えていただいた方法と、花ちゃんさんに教えて
いただいた3つ目のURLでの方法が同じような感じでしたので、Win2000
上で動かしてみたのですが、やはりディスクの挿入ダイアログでキャンセル
した場合にはsh.fAnyOperationsAborted=0となってしまいました。
(コピー中ダイアログでキャンセルした場合は1が返ってきました。)

同じWin2000でも環境によって結果が違うことがあるのでしょうか?
もしWin2000の環境をお持ちの方で、確認していただける方が
いらっしゃいましたら、確認していただけないでしょうか?

よろしくお願い致します。

投稿時間:2005/03/02(Wed) 16:20
投稿者名:GOD
Eメール:
URL :
タイトル:
Re^2: SHFileOperation
> 同じWin2000でも環境によって結果が違うことがあるのでしょうか?
> もしWin2000の環境をお持ちの方で、確認していただける方が
> いらっしゃいましたら、確認していただけないでしょうか?
>
私の環境でもFD要求時にキャンセルしても正常値(戻り値:0)が返ってきてました。
ファイルのコピーが成功しているかだけが分かればよいのならSHFileOperationで正常値が戻ってきた後
にフ
ァイルが存在しているか確認すれば今回分(FDなし)に対しては対応できるかと思います。

環境:Win2000+SP4, IE5.5, VB6+SP5

投稿時間:2005/03/03(Thu) 10:39
投稿者名:はこ
Eメール:
URL :
タイトル:
【解決】SHFileOperation
>GODさん
ご確認どうもありがとうございます。
やっぱりWin2000では仕方のないことなのでしょうか。。。

GODさんからのヒントを元に結局このようにすることにしました。

Private Sub cmdCopy_Click()
    Dim sh          As SHFILEOPSTRUCT
    Dim bytBuf()    As Byte
    Dim lngRet      As Long
    Dim lngCancel   As Long
    Dim intRet      As Integer
    
    On Error Resume Next

RETRY:

    'FDがセットされているか確認
    Err.Clear
    Dir "A:\", vbDirectory
    If Err.Number <> 0 Then
        intRet = MsgBox("フロッピーディスクをセットして再試行ボタンを押下してください。", _
                        vbExclamation Or vbRetryCancel, _
                        Me.Caption)
        If intRet = vbRetry Then
            GoTo RETRY
        Else
            Exit Sub
        End If
    End If
    
    'FD出力
    With sh
        .hwnd = Me.hwnd
        .wFunc = FO_COPY
        .pFrom = "C:\test.dat"
        .pTo = "A:\test.dat"
    End With
    
    lngRet = SHFileOperation(sh)
        
    ReDim bytBuf(LenB(sh)) As Byte
    MoveMemory bytBuf(0), sh, LenB(sh)
    MoveMemory lngCancel, bytBuf(18), Len(lngCancel)
    
    If lngRet = 0 And sh.fAnyOperationsAborted = 0 Then
        MsgBox "コピー完了!"
    End If
End Sub

花ちゃんさん、魔界の仮面弁士さん、GODさん、どうもありがとうございました。