VBアプリケーションでは、ユーザーが不要になったファイルを削除できる機能が必要になることがよくあります。しかし残念ながら、これに対処する最も簡単な方法であるKill関数の使用は、一方通行です。ユーザーが誤ってファイルを削除した場合、あるいはデバッグのために削除したファイルが必要になった場合、そのファイルを復元することはできません。
KillはAPI呼び出しを必要としないため、開発者にとって便利です。ファイルのパス名を文字列式として関数に渡すだけで(例:Kill(App.Path & “\1.txt”))、ファイルが削除されます。しかし、ユーザーにセーフティネットを提供し、ファイルの復元を確実にしたい場合は、別の方法があります。Kill関数を使用する代わりに、アプリから削除されたファイルをごみ箱に送信するように設定しましょう。その仕組みは以下のとおりです。
ごみ箱への移動
このテクニックの鍵となるのは、Shell32.dll によってエクスポートされるSHFileOperation関数です。SHFileOperation は Windows 95/98/Me/NT4.0/2000 でサポートされており、ファイルシステム内のオブジェクトのコピー、移動、名前変更、削除が可能です。また、ファイルをごみ箱に送ることで削除し、必要に応じてユーザーが復元できるようにすることも可能です。
API SHFileOperation
を呼び出すことで、既存のダイアログを利用してファイルを移動し、プロセスの状態に関するユーザーフィードバックを提供できます。Visual BasicプログラムでSHFileOperation関数を使用するには、次の宣言文を含める必要があります。Public Declare Function SHFileOperation Lib _ “shell32.dll” Alias “SHFileOperationA” (lpFileOp _ As SHFILEOPSTRUCT) As Long
SHFileOperation関数は、操作が成功した場合は 0 を返し、エラーが発生した場合は 0 以外の値を返します。
この関数は、 SHFILEOPSTRUCT構造体へのポインタを1つの引数として必要とします。この構造体には、SHFileOperation関数が要求されたファイル操作を実行するために必要な情報が含まれています。
Visual Basic の場合、 SHFILEOPSTRUCT構造体の形式は次のようになります:
Public 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 Long
End Type
表Aは、SHFILEOPSTRUCT構造体の各要素について説明しています。ファイルをごみ箱に送るには、FO_DELETEとFO_ALLOWUNDOの2つのオプションを設定する必要があります。
表A
要素 | 説明/可能な値 |
ハンド |
ファイル操作のステータスに関する情報を表示するダイアログボックスのウィンドウハンドル |
wFunc |
実行する操作の種類: FO_MOVE —pFromで指定されたファイルをpToで指定された場所に FO_RENAME —pFromで指定されたファイルの名前を変更します |
pFrom |
ソースファイル名を指定するためのバッファのアドレス。複数のファイル名はNULLで区切る必要があります。ファイル名のリストは、二重NULLで終端する必要があります。 |
pTo |
宛先ファイルまたはディレクトリの名前を格納するバッファのアドレス。fFlags メンバが FOF_MULTIDESTFILES を指定している場合、バッファには複数の宛先ファイル名を格納できます。複数のファイル名は NULL で区切る必要があります。名前のリストは NULL で終端されている必要があります。 |
fフラグ |
ファイル操作を制御するフラグ。複数のフラグを使用できます。FOF_ALLOWUNDO —元に戻す情報を保持します。FOF_FILESONLY —ワイルドカード ファイル名 (*.*) が指定されている場合にのみ、ファイルに対して操作を実行します 。FOF_MULTIDESTFILES —pToメンバは、すべてのソース ファイルが送信される 1 つのディレクトリではなく、複数の宛先ファイル (ソース ファイルごとに 1 つ) を指定します。FOF_NOCONFIRMATION —表示されるすべてのダイアログ ボックスに対して「すべてはい」で応答します。FOF_NOCONFIRMMKDIR —操作で新しいディレクトリの作成が必要な場合、新しいディレクトリの作成を確認しません。FOF_NOERRORRUI —エラーが発生した場合、ユーザー インターフェイスは表示されません。FOF_RENAMEONCOLLISION — 移動、コピー、または名前変更操作で、対象の名前を持つファイルが既に存在する場合、操作対象のファイルに新しい名前を指定します。FOF_SILENT — 進行状況ダイアログ ボックスを表示しません。 FOF_SIMPLEPROGRESS —進行状況ダイアログ ボックスを表示しますが、ファイル名は表示しません。 FOF_WANTMAPPINGHANDLE — FOF_RENAMEONCOLLISIONが指定されている場合、ファイル名が変更されるとhNameMappingsが入力されます。 |
任意の操作が中止されました |
ユーザーがファイル操作を完了する前に中止した場合にはTrueを受け取り、そうでない場合はFalseを返す値 |
hNameMappings |
SHNAMEMAPPING構造体の配列を含むファイル名マッピングオブジェクトへのハンドル。各構造体には、移動、コピー、または名前変更された各ファイルの古いパスと新しいパスが含まれます。fFlagsメンバーにFOF_WANTMAPPINGHANDLEフラグが含まれている場合のみ有効です。このハンドルはSHFreeNameMappings関数を使用して解放する必要があります。 |
IpszProgressTitle |
進捗ダイアログボックスのタイトルとして使用する文字列のアドレス。fFlagsにFOF_SIMPLEPROGRESSフラグが含まれている場合にのみ使用されます。 |
SHFILEOPSTRUCTの要素
コードデモ:
ファイルをごみ箱に送る簡単なVBプロジェクトを作成しましょう。このサンプル関数を設計どおりに動作させるには、図Aに示すように、ごみ箱オプションの選択を解除して、削除時にファイルをすぐに削除する必要があります。
図A |
![]() |
ごみ箱のプロパティ画面 |
- VB を起動して新しいプロジェクトを開始します。
- モジュールを作成し、次のコードを追加します。
Option Explicit Public 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 Long End Type Public Declare Function SHFileOperation Lib _ “shell32.dll” Alias “SHFileOperationA” (lpFileOp _ As SHFILEOPSTRUCT) As Long Public Const FO_DELETE = &H3 Public Const FOF_ALLOWUNDO = &H40
- フォームにコマンド ボタンを追加し、cmdSendToRecycleBin という名前を付けます。
画面は図 Bのようになるはずです。
図B |
![]() |
サンプルフォーム |
- cmdSendToRecycleBinクリック イベントに次のコードを追加します。
Dim SHop As SHFILEOPSTRUCT
Dim strFile As String strFile = App.Path & “\hello.txt” With SHop .wFunc = FO_DELETE .pFrom = strFile .fFlags = FOF_ALLOWUNDO End With SHFileOperation SHop
- strFile = App.Path & “\hello.txt”のファイル名と場所を、ごみ箱に送るファイルに合わせて変更してください。ファイルがVBプロジェクトと同じディレクトリにある場合は、App.Path はそのままにして、ファイル名のみを変更してください。
- プロジェクトを実行するには、[Ctrl][F5]を押します。
- 「ごみ箱へ送る」をクリックすると、画面は図Cのようになります。「はい」を選択すると、ファイルはごみ箱に移動されます。
図C |
![]() |
サンプル出力 |
VBとAPIでもっと楽しもう
このサンプルでは、SHFileOperation APIを使用して、指定されたファイルをごみ箱に送信し、ユーザーが必要に応じてファイルを復元できるようにしました。次回は、アプリケーション開発に役立つ他のAPI関数、例えばユーザーがコンピューターをログオフ、再起動、シャットダウンできるようにする関数について見ていきます。