こんにちは。
タイトルの通り、APIのファイルフォルダコピー関数に関する質問です。現在VisualBasicでの操作なので、こちらへ掲載させていただきました。
まず環境ですが、
PC:VAIOノート2001年製
OS:Windows2000Pro
外付けフロッピー(A:)ドライブ:Logitec製USBバスパワードライブ
以上の条件で、下記のロジック
Function FileCopy(frm_ctrl As Form, source As String, destination As String) As Variant
Dim lpFileOp As SHFILEOPSTRUCT
Dim lngRetValue As Long
With lpFileOp
.hWnd = frm_ctrl.hWnd
.wFunc = FO_COPY
.pFrom = source
.pTo = destination
.fFlags = FOF_NOCONFIRMATION Or FOF_NOCONFIRMMKDIR Or FOF_MULTIDESTFILES Or _
FOF_SIMPLEPROGRESS
.fAnyOperationsAborted = True
.hNameMappings = 0&
.lpszProgressTitle = "コピー"
End With
lngRetValue = SHFileOperation(lpFileOp)
If lngRetValue <> 0 Then
MsgBox "ファイルコピーに失敗しました。"
End If
AplFileCopy = lngRetValue
End Function
を実行した場合、デザイン環境または実行したexeが強制終了させられ、エラーメッセージが表示されます。
ステップインで追跡した結果、"SHFileOperation(lpFileOp)"の箇所で発生していたのですが、原因が分かりません・・・ちなみにWindowsXPで実行した場合、デザイン環境時のみエラーが発生し、実行環境では正常にファイルコピーが完了しました。
以上から、SHFileOperation()がエラーを発生させる原因または、これを回避・解消する方法をご存知の方、おられましたら、教えてください。
よろしくお願いします。
No.2ベストアンサー
- 回答日時:
構造体の定義自体はあっていました。
ただ、この構造体自体が曲者で、
>fFlags As Integer '操作フラッグ(FOF_xxx)
とIntegerが1つだけいます。
普通はWinAPIで使用する構造体は、4バイト(32bit)毎に構造体のメンバが整列されているのですが、このIntegerのせいで、このメンバ以降のメモリ上の位置がずれてしまっています。
VB6では自動的に4バイトの位置にメンバの位置を合わせてしまうため、VBで定義した構造体と、APIが要求する構造体の定義に違いが出てきてしまい、エラーが発生してしまいます。
>ちなみに、4つ目の操作フラグの"FOF_SIMPLEPROGRESS"を削除してみたら不具合が起きませんでした。
構造体の一番最後のメンバであるlpszProgressTitleは、
FOF_SIMPLEPROGRESSを指定したときのみ参照されます。
つまり、FOF_SIMPLEPROGRESSが指定されたときに、
lpszProgressTitleをAPI内部で参照しに行ったが、
構造体のアライメントの関係でlpszProgressTitleの位置がずれてしまっていたため、ただしく"コピー"という文字列が取得できず、エラーとなってしまった。
ということです。
どうしてもタイトル文字列を変えたいということですと、
メンバのずれを意識して自分でアドレスの値を指定していくしかなさそうですね。
takat_tetsuさん、ご回答ありがとうございます。
原因を理解できました。結果としてはVB6でのプログレスバー付き(及びタイトル付き)の使用を避けようと思います。今後もAPI使用時は引数の4バイトは意識しておいた方が良さそうですね。プログレスバーはまた別オブジェクトでも作成してみます。
お忙しいところ、ありがとうございました。感謝します。
No.1
- 回答日時:
構造体の定義が怪しいかも。
どんな定義書いてます?
この回答への補足
以下、定義したい構造体です。
Type SHFILEOPSTRUCT
hWnd As Long 'ウインドウのハンドル
wFunc As Long '操作方法
pFrom As String '操作元のファイル名・ディレクトリ名
pTo As String '操作先のファイル名・ディレクトリ名
fFlags As Integer '操作フラッグ(FOF_xxx)
fAnyOperationsAborted As Long
hNameMappings As Long
lpszProgressTitle As String
End Type
ちなみに、4つ目の操作フラグの"FOF_SIMPLEPROGRESS"を削除してみたら不具合が起きませんでした。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
- Visual Basic(VBA) 【前回の続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/16 16:44
- Visual Basic(VBA) 【前回の続き続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/24 20:49
- Visual Basic(VBA) VBA 参照先で選んだファイルをコピーし、出力先に別名で保存したい 8 2022/05/13 20:37
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
- Visual Basic(VBA) 貼り付けた値が消えていく 以下はソースファイルの2番目のシートのB6から最終行を取得 ターゲットファ 2 2023/07/27 12:23
- その他(Microsoft Office) マクロVBAについて 1 2022/09/06 18:12
- Visual Basic(VBA) エクセルのマクロについて教えてください。 7 2023/07/04 09:18
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る EXEの実行内容の結果によって、戻り値を0か1かで返したい 1 2023/07/04 16:40
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Outlook.ApplicationをCreateOb...
-
マクロについて教えてください...
-
実行時エラー 438になった時の...
-
Exce2007でBorder クラスの Lin...
-
実行時エラー3001「引数が間違...
-
エクセルVBA、フリーフォームで...
-
エクセルエラー13型が一致しま...
-
VBAがブレークモードになっ...
-
プロシージャ名の取得
-
ASP.NET OleDbConnectionが定義...
-
Application.ActiveInspectorで...
-
エクセルVBA autofilterでエラー
-
VBSで変数の宣言はできないので...
-
VBA 新しいフォルダを作成する方法
-
テキストボックスに記述した数...
-
ExcelVBA Range クラスの Page...
-
Excel2003でworksheetクラスのC...
-
excel vbaでvlooupの変数がわか...
-
'Speak'メソッドは失敗しました
-
VBAのChrome操作のエラーについ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
実行時エラー 438になった時の...
-
エクセルエラー13型が一致しま...
-
【Excel VBA】マクロをボタンに...
-
なぜこんな初歩的なVBAのIf文で...
-
マクロについて教えてください...
-
実行時エラー3001「引数が間違...
-
VBAがブレークモードになっ...
-
ExcelVBA Range クラスの Page...
-
VBSで変数の宣言はできないので...
-
VBS実行時エラー オブジェクト...
-
OLEDB.NETで接続できない
-
プロシージャ名の取得
-
EXCEL VBAマクロ中断でデバッグ...
-
ADODB.Streamを使用してUTF-8を...
-
VBAでのエラー
-
実行時エラー48発生時のDLL特定...
-
Outlook.ApplicationをCreateOb...
-
VB6+SQL サーバー 2000 で 実行...
-
実行時エラー -'-2147417848
-
「コンパイルエラー:プロシー...
おすすめ情報