QAサイトのスタック・オーバーフローでC++Builderの開発者が、System.SysUtilsユニットのFindFirst/FindNext関数で拡張子 ~1~や、その他の特殊な拡張子を持つすべてのファイルが見つからないという内容を質問していました。
このブログでは、この問題を解決するためのC++Builderのサンプルブログラムを紹介します。
ここでは、C++Builder 10.4を使用して、以下の手順に従ってアプリケーションを作成していきます。
1. C++Builder Windows VCLアプリケーション(空白のアプリケーション)を新規作成
2. プロジェクトに名前をつけて保存 (例えば、FindFirstVCLCpp)
3. フォーム上にTPanelを1つ配置し、AligeプロパティをalTopに変更
4. Panel1上にTButtonを1つ配置
5. Panel1上にTEditを1つ配置し、Textプロパティを”Find Files”に変更
6. フォーム上にTMemoを1つ配置し、AligeプロパティをalClientに変更
System.SysUtils.hppでのFindFirst関数の宣言は次のとおりです。
1 |
extern DELPHI_PACKAGE int __fastcall FindFirst(const System::UnicodeString Path, int Attr, TSearchRec &F); |
ここで重要な点は、検索するファイルのファイル属性(FindFirst関数の第二引数の Attr)を全部含めておくことです。 選択可能なファイル属性は、同様にSystem.SysUtils.hppで宣言されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
static const System::Int8 faInvalid = System::Int8(-1); // Identifies an invalid file. static const System::Int8 faReadOnly = System::Int8(0x1); // Identifies read-only files or directories. static const System::Int8 faHidden = System::Int8(0x2); // Identifies hidden files or directories. static const System::Int8 faSysFile = System::Int8(0x4); // Identifies system files or directories. static const System::Int8 faVolumeID _DEPRECATED_ATTRIBUTE0 = System::Int8(0x8); // Deprecated static const System::Int8 faDirectory = System::Int8(0x10); // Identifies a directory. static const System::Int8 faArchive = System::Int8(0x20); // Identifies Windows archived files. static const System::Byte faNormal = System::Byte(0x80); // Identifies normal files. static const System::Word faTemporary = System::Word(0x100); // Identifies temporary files or directories. static const System::Word faSymLink = System::Word(0x400); // Specifies only symbolic link file types. static const System::Word faCompressed = System::Word(0x800); // Identifies a compressed file or directory. static const System::Word faEncrypted = System::Word(0x4000); // Identifies an encrypted file or directory. static const int faVirtual = int(0x10000); // Reserved for system use. static const System::Word faAnyFile = System::Word(0x1ff); // Specifies any file type. |
なお、System.SysUtils.hppは、デフォルトで以下のパスに配置されています。
1 |
C:\Program Files (x86)\Embarcadero\Studio\21.0\include\windows\rtl\windows\rtl\System.SysUtils.hpp |
7. Button1をダブルクリックし、OnClickイベントハンドラを作成
8. OnClickイベントに以下のコードを実装
以下のコードでは、ディレクトリ内の ., .., .~* などの文字を含むすべてのファイルを表示します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
void __fastcall TForm1::Button1Click(TObject *Sender) { TSearchRec sr; Memo1->Lines->Clear(); int iAttributes = 0; iAttributes |= faReadOnly; iAttributes |= faHidden; iAttributes |= faSysFile; iAttributes |= faVolumeID; iAttributes |= faDirectory; iAttributes |= faArchive; iAttributes |= faAnyFile; if (FindFirst(Edit1->Text, iAttributes, sr) == 0) { do { if ((sr.Attr & iAttributes) == sr.Attr) { Memo1->Lines->Add( sr.Name + " = " + IntToStr(sr.Size) ); } } while (FindNext(sr) == 0); FindClose(sr); } } |
9. プロジェクトをビルドし、アプリケーションを実行
10. Edit1のテキスト欄に検索したいディレクトリパスを入力
ここでは、C++Builderプロジェクトの__historyフォルダ内のファイルを検索します。例えば、C:\Users\<ログイン名>\Documents\Embarcadero\Studio\Projects\<プロジェクト名> \ __history\*.*
11. Button1をクリックすると、Memo1には下図のように特殊な拡張子を含むファイルが表示されます。
スタック・オーバーフローについて
スタック・オーバーフローでは、C++Builder SO Tagをクリックすると、他にもC++Builderに関する質問と回答を見つけることができます。
日本語版のスタック・オーバーフローで質問や回答を行うには、こちらを参照ください。
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition