■ 現在のこのページの役立ち度:
表示されない場合こちらのリンクからもご覧になれます。
■ このページの役立ち度を評価する:
役立ち度を評価してください。
(1(左):あまり役立たない - 5(右):大変役立った):
■ ページの共有:
[ サイト内検索 ]
カスタム検索
#41630-0SHFileOperationのキャンセルを知るには匿名416302001-04-12(木) 16:17
     #41640-0RE#41630:SHFileOperationのキャンセルを知るには魔界の仮面弁士2001-04-12(木) 17:18
     #41644-0RE#41640:SHFileOperationのキャンセルを知るには魔界の仮面弁士2001-04-12(木) 17:58
     #41667-0RE#41640:SHFileOperationのキャンセルを知るには連雀2001-04-13(金) 00:38
     #41670-0RE#41667:SHFileOperationのキャンセルを知るには魔界の仮面弁士2001-04-13(金) 02:38
     #41678-0RE#41670:SHFileOperationのキャンセルを知るには魔界の仮面弁士2001-04-13(金) 11:45
#41630-0
SHFileOperationのキャンセルを知るには
SHFileOperationでファイルの削除をしようとしています。
この関数でファイルを削除しようとする際、確認ダイアログが出て「削除しま
すか」と聞いてきます。ここで、ユーザーが「OK」を押したのか「キャンセル」
を押したのか知りたいのですが、方法がわかりません。

VBマガジン1998然月号のダニエルアップルマン氏の記事には、「処理がキャン
セルされた場合、fAnyOperationsAbortedフィールドにTrueが設定されるが、
実際には動作しない」とあります。試してみましたが、実際に動作しませんで
した(WinME,Shell32.dll:5.50.4134.100)。

方法はないのでしょうか。
なにか知っている方がいれば、教えてください。
#41640-0
RE#41630:SHFileOperationのキャンセルを知るには
> VBマガジン1998然月号のダニエルアップルマン氏の記事には、「処理がキャン
> セルされた場合、fAnyOperationsAbortedフィールドにTrueが設定されるが、
その記事が、今手元にないので、よく覚えていませんが、
あれって、バイトアライメントの問題ではありませんでしたっけ?

SHFILEOPSTRUCTはシングルバイトアライメントなので、
fFlagsの直後にあるfAnyOperationsAbortedが詰められてしまい、
VBではそのまま取得すると、メモリ位置がずれて取得されるって話だったような。

# fFlags がLong宣言されているサンプルと、
# Integer宣言されているサンプルとがあるのも、
# アライメントの関係だったような…。

> 実際には動作しない」とあります。試してみましたが、実際に動作しませんで
> した(WinME,Shell32.dll:5.50.4134.100)。
ME環境がないので検証はできませんが、
構造体をバイト配列に置き換えて呼び出し、キャンセルを行うと、
キャンセルするかどうかで、その中身が変化したりはしませんでしたか?

> なにか知っている方がいれば、教えてください。
以前、fAnyOperationsAborted の使い方を回答したときには、
2バイトずらした位置をRtlMoveMemoryする事で取得できた、
という結論になったような。。。(うろ覚え)

# 実際のコードを見せてもらえれば、何かわかるかも。
#41644-0
RE#41640:SHFileOperationのキャンセルを知るには
>> VBマガジン1998然月号のダニエルアップルマン氏の記事には、「処理がキャン
>> セルされた場合、fAnyOperationsAbortedフィールドにTrueが設定されるが、
>> 実際には動作しない」とあります。試してみましたが、実際に動作しませんで
>> した(WinME,Shell32.dll:5.50.4134.100)。
> ME環境がないので検証はできませんが、

とりあえず、Win98/SP1, Shell32.DLL:4.72.3612.1700で
試してみたところ、問題なくキャンセルを検知できましたよ。

# えらく適当なコードになってますけど。(汗)

Private Type SHFILEOPSTRUCT_
    hWnd As Long
    wFunc As Long
    pFrom As String
    pTo As String
    fFlags As Integer
    fAnyOperationsAborted1 As Integer
    fAnyOperationsAborted2 As Integer
    otherMember(2) As Long
End Type
Private Declare Function SHFileOperationA Lib "shell32.dll" (ByRef lpFileOp As SHFILEOPSTRUCT_) As Long

Private Sub Test()
    Dim SFO As SHFILEOPSTRUCT_
    Dim lngRet   As Long
    
    With SFO
        .wFunc = &H3&
        .fFlags = &H40&
        .pFrom = ここは適当に
    End With
    lngRet = SHFileOperationA(SFO)
    MsgBox "戻り値:" & lngRet & vbCrLf _
         & "Abort1:" & SFO.fAnyOperationsAborted1 & vbCrLf _
         & "Abort2:" & SFO.fAnyOperationsAborted2 & vbCrLf _
         & "DLLErr:" & Err.LastDllError
End Sub
#41667-0
RE#41640:SHFileOperationのキャンセルを知るには
ゴミレスです。

> # fFlags がLong宣言されているサンプルと、
> # Integer宣言されているサンプルとがあるのも、
> # アライメントの関係だったような…。

cのヘッダファイルのせいかもしれません。
SHFILEOPSTRUCT構造体のfFlagsは FILEOP_FLAGS fFlags; と定義されていますが
このFILEOP_FLAGSのtypedefが混乱しています。
Shlobj.hでは   typedef UINT FILEOP_FLAGS; 
Shellapi.hでは typedef WORD FILEOP_FLAGS; こちらが正しいはず
#41670-0
RE#41667:SHFileOperationのキャンセルを知るには
(この投稿は、等間隔フォントで見て下さい)

>> # fFlags がLong宣言されているサンプルと、
>> # Integer宣言されているサンプルとがあるのも、
>> # アライメントの関係だったような…。
> cのヘッダファイルのせいかもしれません。

確かに、ヘッダファイルのせいなのですけれど、


> SHFILEOPSTRUCT構造体のfFlagsは FILEOP_FLAGS fFlags; と定義されていますが
> このFILEOP_FLAGSのtypedefが混乱しています。
> Shlobj.hでは   typedef UINT FILEOP_FLAGS; 
> Shellapi.hでは typedef WORD FILEOP_FLAGS; こちらが正しいはず

Integer/Longの違いは、この事だけが原因では無いと思います。

そもそも、fAnyOperationAborted が使えない一番の原因は、SHELLAPI.Hに含まれている、
   #include <pshpack1.h>
という、シングルバイトパッキング指定です。

この宣言がなされているため、先述の構造体は、
                                   fAnyOperationAborted
 (メモリイメージ)           fFlags──┐    │ hNameMappings┌─lpszProgressTitle
    ┃ hWnd ┃wFunc ┃pFrom ┃ pTo  ┃↓┃  ↓  ┃  ↓  ┃  ↓  ┃
    ┗┷┷┷┻┷┷┷┻┷┷┷┻┷┷┷┻┷┻┷┷┷┻┷┷┷┻┷┷┷┛

というバイト配置になるわけです。

しかし、VBの場合は、32bit単位のパッキングを採用しています。
# VBがシングルバイトパッキングを使うのは、バイナリファイルの入出力時のみ。

ゆえに、typedef WORD FILEOP_FLAGS; すなわち fFlags As Integer としても、

             VBによる2Byteのパディング──┐ fAnyOperationAborted
 (VBによるレイアウト)       fFlags──┐  │    │ hNameMappings┌─lpszProgressTitle
    ┃ hWnd ┃wFunc ┃pFrom ┃ pTo  ┃↓┃↓┃  ↓  ┃  ↓  ┃  ↓  ┃
    ┗┷┷┷┻┷┷┷┻┷┷┷┻┷┷┷┻┷┻┷┻┷┷┷┻┷┷┷┻┷┷┷┛

となり、fAnyOperationAborted 以降のデータがずれてしまう事になります。

このため、もしフラグ以降の項目(例えばlpszProgressTitle等)を使うのであれば、
fFlagsの後ろに続くフィールドを、2バイト前方へ動かさなければなりません。
これの対処のため、fFlags以降の構造を、あえてヘッダファイルの宣言とは
違った形にしてあるサンプルを、いくつか見かけます。
(テーマ2掲示板の#154も、SHFILEOPSTRUCT の宣言を変更していますよね)

ところで、以下は蛇足ですが…

この「バイトのずれ」が発生する関係上、lpszProgressTitle を指定する場合は
String型を使ってはいけません。使った場合、ほぼ間違いなくメモリ例外が発生します。
もし、lpszProgressTitle を使う場合は、As Longで宣言しておき、
  Dim buf() As Byte
  buf = "文字列"
  udtSHFILEOPSTRUCT.lpszProgressTitle = VarPtr(buf(0))
のように指定してやる必要があります。
#41678-0
RE#41670:SHFileOperationのキャンセルを知るには
> (この投稿は、等間隔フォントで見て下さい)
この投稿もまた、等幅フォントで見てください。m(_ _)m
わかりにくい図になってしまっているのはご容赦を。


> (テーマ2掲示板の#154も、SHFILEOPSTRUCT の宣言を変更していますよね)
コイツを書き忘れてました。m(_ _)m

先の図と比較すると、構造体の宣言を変更したことにより、
   『fAnyOperationsAborted が、正しい位置を指している』
ということがわかるかと思います。

               fAnyOperationsAbortedHi────┐  ┌─VBによる2Byteのパディング
               fAnyOperationsAbortedLo──┐  │  │    ┌─hNameMappings 
 (テーマ2#154宣言)          fFlags──┐  │  │  │    │      ┌─lpszProgressTitle
    ┃ hWnd ┃wFunc ┃pFrom ┃ pTo  ┃↓┃↓┃↓┃↓┃  ↓  ┃  ↓  ┃
    ┗┷┷┷┻┷┷┷┻┷┷┷┻┷┷┷┻┷┻┷┻┷┻┷┻┷┷┷┻┷┷┷┛

hNameMappingsとlpszProgressTitleは、依然ずれたままですが、
必要であれば、fAnyOperationsAbortedと同様に、2バイト(ないしは1バイト)単位で
分割すれば、正しい配置になります。


ついでに、Q&A #41644の宣言も図式化してみました。
# 少々大きくしすぎた模様。(泣)

                fAnyOperationsAborted2────┐  ┌─VBによる2Byteのパディング
                fAnyOperationsAborted1──┐  │  │    ┌───┬───┬──otherMember(0〜2)
 (Q&A #41644宣言)           fFlags──┐  │  │  │    │      │      │
    ┃ hWnd ┃wFunc ┃pFrom ┃ pTo  ┃↓┃↓┃↓┃↓┃  ↓  ┃  ↓  ┃  ↓  ┃
    ┗┷┷┷┻┷┷┷┻┷┷┷┻┷┷┷┻┷┻┷┻┷┻┷┻┷┷┷┻┷┷┷┻┷┷┷┛
このページと関連する記事:
#29361-0RASDIALPARAM 構造体のサイズ(RAS API)2000-09-05(火) 16:52
#5582-0AVISTREAMINFOの構造1999-09-21(火) 14:55
#18404-0SHFileOperation のキャンセル2000-03-23(木) 16:27
#425-2Equalsについて2003-12-10(水) 11:54
#13081-0CreateFileでのファイルの開き方教えてください2000-01-13(木) 12:34
#1738-1eMbeddedVBで実行ファイルを作成する時のエラーについて2002-07-16(火) 07:25
#462-1Byteを構造体にコピーしたいんですが・・・1999-06-28(月) 11:07
#180-2FTPでのダウンロード2002-05-15(水) 08:39
#2574-0DLLのコール1999-10-22(金) 08:56
#31314-0RE#31284:テキストファイルの操作について(その2)2000-10-06(金) 15:18
お探しの情報は見つかりましたか?お困りの問題は解決しましたか?
サイト内検索, 似た記事検索で見つからなくてもあきらめずに掲示板で質問してみましょう。
VB初心者友の会があなたのお役に立てれば幸いです。また、本ページの投稿者の方々にこの場を借りて感謝致します。
本ページは過去ログを集めて自動構成しています。よろしければこのページに関するフィードバックをお願いします。
(※ 構成の誤り、広告等の不適切な記事、リンク切れ、読めないページの報告など)