--- 1998 07/31 発刊 ---
--- 1999 06/16 改修 ---
Thanks to 坂本 貴洋 さん
--- 2000 01/08 改修 ---
Thanks to KENZOU さん

創 刊 号

今回のテーマ

シェルと仲良くする(part1)

    1. シェルAPI

次号予告

進め!中級プログラマー 創刊号
今回のテーマ シェルと仲良くする(part1)

VCLのような良く出来たライブラリを用いると、そこそこのWindowsアプリケーション、ユーティリティがものの数時間で非常に簡単に作成できてしまいます。
かしながら、それら標準のライブラリを用いても簡単には実現しない機能もやはり多数存在します。
回の特集の主題でもあるシェルとの対話もそれらの1つです。

各ファイルに割当てられているアイコンを取得するにはどうすればいいのか。
ある拡張子のファイルに対して、エクスプローラ上の右クリックで非標準のコンテキストメニューを表示させるにはどうすればいいのか。

のようなシェルとの対話を必要とする場面で使える知識やテクニックを今号(part1)及び次号(part2)に分けて解説していきます。

1. シェルAPI Windowsにおいてシェルと対話する最も簡単な方法はシェルAPIを利用するものです。
ここでいうシェルAPIとは、SHで始まる関数群及びその他のシェルに作用する関数群を合わせたもの(表1参照)のことで、Delphiでは「shellapi.pas」及び「shlobj.pas」にて宣言されています。(C系言語では「shellapi.h」「shlobj.h」)
これらの関数を利用すれば、シェル内で管理されているアイコンなどのシステムリソースにアクセスしたり、別のアプリケーションを実行したりすることが出来るようになります。
こではまず、これらのシェルAPIのうち知っていると便利なものについて、概要及び使用法を簡単に解説していきます。
また、ドラッグ&ドロップに絡む部分など、別の号で特集する予定のものに関しましては外しましたのでご容赦下さい。
お、「シェルって何?」という方は、まず下のミニ解説からご覧になって下さい。
ミニ解説: そもそもシェルって何?

ェルは直訳すると「殻」という意味になります。個人的にはこの表現はわかりにくいと思っています。
たしかに一言で表現するのは難しいですが、「殻」と同じくあえて抽象的に表現するならば「レストランのホール」といった表現の方がしっくりくるように思います。客(ユーザ)とレストラン(OS)との間をとりもつもの、という意味です。
象的ではなく直感的に表現すると、シェルとは「ユーザー側から見たOS側のインターフェイス」のことです。つまり、ユーザ側から見たOSの外観といった感じです。
厳密なことを言い出すとややこしいのでしょうが、おおよそ(少なくともここでは)そういう理解で問題ありません。
の例で続けますと、客(ユーザ)側から見えるのはレストラン(OS)のホール(シェル)であって、厨房(OS内部)ではない、ということです。
体的な話をしますと、Windowsのシェルは「エクスプローラ」です。ファイルマネージャのあれがエクスプローラだと思っていたとすればそれは間違いです。あれはエクスプローラの一部です。実は、デスクトップもエクスプローラなのです。
ここまで言うと、先の表現でいわんとした事がだんだん分かってきていただけたのではないかと思います。
(ユーザ)はレストランのホール(シェル)で欲しいもの(アプリケーションの起動やファイル階層の閲覧)を注文します。するとレストラン(OS)は何やら厨房(OS内部)でいろいろな材料を使って注文の品を調理します。しかし、ここの過程は客(ユーザ)側からは見えません。その後、レストラン(OS)は出来上がった注文の品をホール(シェル)に出して客(ユーザ)に食べさせて、一連の作業が終了します。
また、ホール(シェル)の中にあるものはナイフ、フォーク、灰皿(デスクトップ上のアイコンやスタートボタン)にいたるまで全てホール(シェル)で管理されています。
のように、シェルとは、「ユーザから見たOSの外観(インターフェイス)」一般を担っているものを指す、と理解しておいて下さい。

表1 シェルAPI一覧
SHChangeNotify手続き SHAddToRecentDocs手続き
SHGetInstanceExplorer関数 SHBrowseForFolder関数
SHLoadInProc関数 SHGetDesktopFolder関数
SHGetPathFromIDList関数 SHGetSpecialFolderLocation関数
SHGetMalloc関数 SHGetDataFromIDList関数
DragFinish手続き DragAcceptFiles手続き
SHFreeNameMappings手続き DragQueryFile関数
DragQueryPoint関数 ShellExecute関数
ShellExecuteEx関数 FindExecutable関数
CommandLineToArgvW関数 ShellAbout関数
ExtractAssociatedIcon関数 ExtractIcon関数
ExtractIconEx関数 SHAppBarMessage関数
SHFileOperation関数 Shell_NotifyIcon関数
SHGetFileInfo関数 DuplicateIcon関数
DoEnvironmentSubst関数  
1.1 SHChangeNotify手続き

[概要] プリケーションが行ったイベントをシステムに通知します。例えば、ファイル削除等のイベントをシェルに反映(フォルダから該当ファイルの表示が消える)させることが出来ます。
このように、アプリケーションがシェルに影響する動作をし、それをすぐにシェルに反映させたい場合はこの関数を呼出す必要があります。
Delphiでの宣言及び各パラメータの解説を以下に示します。
procedure SHChangeNotify(wEventId: Longint; uFlags: UINT; dwItem1, dwItem2: Pointer); stdcall;

{ パラメータ }
wEventId:シェルに通知するイベントの種類を表す以下のフラグの組合せ
  ・SHCNE_ASSOCCHANGED.....ファイルタイプの関連付けに変更
・SHCNE_ATTRIBUTES.....ファイル属性に変更
・SHCNE_CREATE.....ファイル作成
・SHCNE_DELETE.....ファイル削除
・SHCNE_DRIVEADD.....ネットワークドライブ追加
・SHCNE_DRIVEADDGUI.....GUI経由でのネットワークドライブ追加
・SHCNE_DRIVEREMOVED.....ネットワークドライブ削除
・SHCNE_INTERRUPT.....システム割込み
・SHCNE_MEDIAINSERTED.....CD-ROMのようなリムーバブルメディアの追加
・SHCNE_MEDIAREMOVED.....CD-ROMのようなリムーバブルメディアの削除
・SHCNE_MKDIR .....ディレクトリの作成
・SHCNE_NETSHARE.....ネットワーク上のリソースを共有
・SHCNE_NETUNSHARE.....リソースの共有を中止
・SHCNE_RENAMEFOLDER.....フォルダのリネーム
・SHCNE_RENAMEITEM.....フォルダ中のアイテムをリネーム
・SHCNE_RMDIR.....ディレクトリの削除
・SHCNE_SERVERDISCONNECT.....ネットワークサーバーとの切断
・SHCNE_UPDATEDIR.....ディレクトリ中のコンテンツを更新
・SHCNE_UPDATEIMAGE.....システムグローバルイメージリストを更新
・SHCNE_UPDATEITEM.....プリンタやファイルのプロパティを更新
uFlags:dwItem1、dwItem2の意味を示すフラグ(以下のいずれか1つ)
  ・SHCNF_DWORD.....dwItem1、dwItem2はDWORD値
・SHCNF_FLUSH.....システムのイベントバッファをフラッシュ
 (ただし、システムがイベントを処理するまで制御は戻ってこない)
・SHCNF_FLUSHNOWAIT.....システムのイベントバッファをフラッシュ
 (ただし、システムがイベントを処理する前に制御が戻ってくる)
・SHCNF_IDLIST.....dwItem1、dwItem2はアイテムIDリストのアドレス
・SHCNF_PATH.....dwItem1、dwItem2はパス(ヌル終端文字列)
・SHCNF_PRINTER.....dwItem1、dwItem2はプリンター名(ヌル終端文字列)
dwItem1, dwItem2:イベント依存のパラメータ(wEventID、uFlagsによって決まる)

[使用例] IExtractIcon.GetIconLocation 中でGIL_DONTCACHEフラグを立てている場合などは、アイコンキャッシュが無効のため、アイコンの変更が反映されない場合があります。
このような場合に SHChangeNotify手続きを用いて以下のように対処することができます。
var DirPath: string;//アイコンが変更されたアイテムのあるディレクトリへのパス
... ... ... ...
SHChangeNotify( SHCNE_UPDATEDIR, SHCNF_PATH, PChar(DirPath), Nil);

た、ファイルの関連付けを設定してそれが反映されない場合にも、以下のように SHChangeNotify手続きを用いて対処することができます。
SHChangeNotify( SHCNE_ASSOCCHANGED, SHCNF_FLUSH, Nil, Nil);

1.2 SHAddToRecentDocs手続き

[概要] スクバーのスタートメニューから辿れる「最近使ったファイル」フォルダに文書を追加、あるいは全てをクリアします。(pvにNilを立てた場合全てがクリアされます)
Delphiでの宣言及び各パラメータの解説を以下に示します。
procedure SHAddToRecentDocs(uFlags: UINT; pv: Pointer); stdcall;

{ パラメータ }
uFlags:pvパラメータの意味を示すフラグ(以下のいずれか1つ)
  ・SHARD_PATH.....パス(ヌル終端文字列)
・SHARD_PIDL.....アイテムIDリストへのアドレス
pv:文書のフルパスやファイル名を含むバッファへのポインタもしくはアイテムIDリストのアドレス(ただし、ここにヌルを指定すると最近使ったファイルをクリアする)

[使用例] タン1(Button1)をクリックすると「最近使ったファイル」に'test.txt'(作業ディレクトリ中に存在するものと仮定)を加え、ボタン2(Button2)がクリックされると「最近使ったファイル」を全てクリアする例です。
パスを与える場合はフルパスでなければならない点に注意して下さい。
procedure TForm1.Button1Click( Sender: TObject);
var
  locls: string;
begin
  locls := GetCurrentDir + '\test.txt';
  SHAddToRecentDocs( SHARD_PATH, PChar(locls));//'test.txt'を加える例
end;

procedure TForm1.Button2Click( Sender: TObject);
begin
  SHAddToRecentDocs( SHARD_PATH, Nil);//全てクリアする例
end;

1.3 SHBrowseForFolder関数

[概要] ェルフォルダを選択させるダイアログボックスを表示し、OKボタンが押された時にユーザが選択していたシェルフォルダを表すアイテムIDリスト構造体へのポインタを返します。
Delphiでの宣言及び各パラメータの解説を以下に示します。
function SHBrowseForFolder(var lpbi: TBrowseInfo): PItemIDList; stdcall;

{ パラメータ }
lpbi:ダイアログボックス表示に関する情報を含むTBrowseInfo構造体

{ 返値 }

選択されたファイルの(名前空間のルートに対する)位置を指定するアイテムIDリストへのポインタを返します。
この際、下の使用例に見られるように、TBrowseInfo.pszDisplayNameで指定されたバッファにはユーザーの選択したフォルダ名が入っていますが、フルパスも含めたフォルダ名が必要な場合は、後述のSHGetPathFromIDList関数を用いて返値のアイテムIDリストからフルパスを得る必要があります。
なお、ユーザーがキャンセルボタンを押した場合、返値はヌルになります。
また、返値のアイテムIDリストは、呼出し側がシェルのタスクアロケータを用いて開放する必要があります。

[使用例] タン(Button1)を押すとフォルダ選択ダイアログボックスが表示され、ユーザが選択したフォルダのフォルダ名がボタンのキャプションに、フォルダのフルパスが Edit1に表示される例です。
procedure TForm1.Button1Click(Sender: TObject);
var
  BrowseInfo: TBrowseInfo;
  FolderName, FolderPath: array[0..MAX_PATH] of Char;
  pidl: PItemIDList;
  lpMalloc: IMalloc;
begin
  if FAILED( SHGetMalloc( lpMalloc)) then exit;//シェルタスクアロケータ取得

  with BrowseInfo do//TBrowseInfo構造体の初期化
  begin
    hwndOwner := Handle;
    pidlRoot := Nil;
    pszDisplayName := FolderName;
    lpszTitle := 'フォルダを選んでね';
    ulFlags := BIF_RETURNONLYFSDIRS;
    lpfn := Nil;
  end;

  pidl := SHBrowseForFolder( BrowseInfo);
  if pidl = Nil then exit;
  Button1.Caption := FolderName;//ここではフォルダ名のみ
  SHGetPathFromIDList( pidl, FolderPath );//ここでフルパスを入手
  Edit1.Text := FolderPath;

  lpMalloc.Free(pidl);//呼出し側がシェルタスクアロケータを用いて開放
end;

ミニ解説: TBrowseInfo構造体

イアログボックス表示に関する情報を含み、ユーザーが選択したフォルダに関する情報を受取る構造体です。

TBrowseInfoA = packed record
  hwndOwner: HWND;
  pidlRoot: PItemIDList;
  pszDisplayName: PAnsiChar;
  lpszTitle: PAnsiChar;
  ulFlags: UINT;
  lpfn: TFNBFFCallBack;
  lParam: LPARAM;
  iImage: Integer;
end;

TBrowseInfo = TBrowseInfoA;

[メンバー]
hwndOwner.....ダイアログボックスのオーナーウィンドウハンドル
pidlRoot.....中身を表示するフォルダの位置を指定するアイテムIDリスト
(指定したフォルダとそのサブフォルダのみがダイアログボックスに表示される。ヌルを指定した場合、デスクトップフォルダが指定されたことになる。)
pszDisplayName.....ユーザーが選択したフォルダ名が返されるバッファへのポインタ
lpszTitle.....ダイアログボックスのビューコントロールの上に表示されている文字列へのポインタ
ulFlags.....ダイアログボックスにリストされるフォルダのタイプを指定するゼロもしくは以下に示すフラグの組合せ
・BIF_BROWSEFORCOMPUTER---コンピュータのみを返す
・BIF_BROWSEFORPRINTER---プリンターのみを返す
・BIF_DONTGOBELOWDOMAIN---ツリービューにおいてドメインレベル以下のネットワークを含まない
・BIF_RETURNFSANCESTORS---ファイルシステムフォルダのみを返す
・BIF_RETURNONLYFSDIRS---ファイルシステムディレクトリのみを返す
・BIF_STATUSTEXT---ダイアログボックスにステータスエリアを含む
(コールバック関数はダイアログボックスにメッセージを送りステータステキストを設定する事が出来る)
lpfn.....イベントが起った際にダイアログボックスが呼出すTFNBFFCallBack型の関数
lParam.....コールバック関数に渡されるパラメータ
iImage.....選択されたフォルダに関するイメージを指すシステムイメージリスト内のインデックス

1.4 SHGetPathFromIDList関数

[概要] イテムIDリストをファイルシステム上のフルパス(例:C\WINDOWS\SYSTEM)に変換します。
Delphiでの宣言及び各パラメータの解説を以下に示します。
function SHGetPathFromIDList(pidl: PItemIDList; pszPath: PChar): BOOL; stdcall;

{ パラメータ }
pidl:名前空間のルートに対する位置を指定するアイテムIDリストへのポインタ
pszPath:ファイルシステムパスを返されるバッファへのポインタ

{ 返値 }

関数が成功すればTRUE、失敗すればFALSEを返します。

[使用例] SHBrowseForFolder関数の使用例をもって代用します。

1.5 SHGetSpecialFolderLocation関数

[概要] み箱、コントロールパネル、マイコンピュータ、プリンターなどの特殊フォルダを示すアイテムIDリストへのポインタを返します。
Delphiでの宣言及び各パラメータの解説を以下に示します。
function SHGetSpecialFolderLocation(hwndOwner: HWND; nFolder: Integer; var ppidl: PItemIDList): HResult; stdcall;

{ パラメータ }
hwndOwner(in):ダイアログボックス等を表示する場合のオーナーウィンドウハンドル
nFolder(in):特別なフォルダを指定するフラグ(以下のいずれか1つ)
  ・CSIDL_BITBUCKET.....ごみ箱
・CSIDL_CONTROLS.....コントロールパネル
・CSIDL_DESKTOP.....デスクトップ
・CSIDL_DESKTOPDIRECTORY.....デスクトップ(デスクトップフォルダではない)上にファイルオブジェクトを物理的に保存するのに使用されるファイルシステムディレクトリ
・CSIDL_DRIVES.....マイコンピュータ
・CSIDL_FONTS.....フォント
・CSIDL_NETHOOD.....ネットワーク上のオブジェクトを含むファイルシステムディレクトリ
・CSIDL_NETWORK.....ネットワーク階層構造の上で最上位に位置するフォルダ
・CSIDL_PERSONAL.....文書の共通リポジトリ(お気に入り?)
・CSIDL_PRINTERS.....プリンター
・CSIDL_PROGRAMS.....プログラムグループ
・CSIDL_RECENT.....最近使ったファイル
・CSIDL_SENDTO.....送る
・CSIDL_STARTMENU.....スタートメニュー
・CSIDL_STARTUP.....スタートアップ
・CSIDL_TEMPLATES.....文書テンプレートの共通リポジトリ
ppidl(out):デスクトップに対するフォルダの位置を指定したアイテムIDリストへのポインタ

{ 返値 }

関数が成功すれば、NOERRORを返します。失敗した場合はOLEで定義されたエラーコードを返します。

[使用例] タン(Button1)をクリックすると、前述のSHGetPathFromIDList関数を使用してデスクトップフォルダのパスが Edit1に表示される例です。
だし、ネットワークプリンタなどの仮想フォルダにはパスが有りませんのでこの使い方をしても何も返ってきません。
procedure TForm1.Button1Click( Sender: TObject);
var
  pidl: PItemIDList;
  Path: array[0..MAX_PATH] of char;
begin
  SHGetSpecialFolderLocation( Handle, CSIDL_DESKTOP, pidl);
  SHGetPathFromIDList( pidl, Path);
  Edit1.Text := Path;
end;

1.6 SHGetMalloc関数

[概要] ェルのIMallocインターフェイスを返します。後でシェルにより開放されるメモリを割当てるために拡張シェルにより使用されるインターフェイスです。
シェルから返されたアイテムIDリストを開放するのにも使用します。
Delphiでの宣言及び各パラメータの解説を以下に示します。
function SHGetMalloc(var ppMalloc: IMalloc): HResult; stdcall;

{ パラメータ }
ppMalloc(out):返されるシェルのIMallocインターフェイス

{ 返値 }

関数が成功すればNOERRORを返します。失敗すればE_FAILを返します。

[使用例] SHBrowseForFolder関数の使用例をもって代用します。

1.7 ShellExecuteEx関数

[概要] ァイル(実行ファイル、文書ファイル)に対する操作を行います。同操作後、該当ファイルに対して、さらに何かしらの操作を行う場合などには ShellExecuteではなくこちらを使用した方が良い場合が多いです。
数が成功すると、TShellExecuteInfo.hInstAppに起動させたアプリケーションのインスタンスハンドル(33以上)を設定します。関数が失敗した場合は、TShellExecuteInfo.hInstAppにSE_ERR_*(32以下)のいずれか1つが格納されます。
Delphiでの宣言及び各パラメータの解説を以下に示します。
function ShellExecuteEx( lpExecInfo: PShellExecuteInfo):BOOL; stdcall;

{ パラメータ }
lpExecInfo:ファイルに関する情報を格納するTShellExecuteInfo構造体へのポインタ

{ 返値 }

関数が成功した場合は非ゼロ値を返します。
失敗した場合はゼロを返します。この場合、GetLastErrorでエラーに関する詳しい情報が得られます。(GetLastErrorで返される値は以下のいずれか1つ)
 ・ERROR_FILE_NOT_FOUND.....ファイルが見付からない
 ・ERROR_PATH_NOT_FOUND.....パスが見つからない
 ・ERROR_DDE_FAIL.....DDEトランザクションが失敗
 ・ERROR_NO_ASSOCIATION.....ファイルの関連付けが成されていない
 ・ERROR_ACCESS_DENIED.....アクセス拒否
 ・ERROR_DLL_NOT_FOUND.....DLLが見つからない
 ・ERROR_CANCELLED.....ユーザーがキャンセルした
 ・ERROR_NOT_ENOUGH_MEMORY.....メモリ不足
 ・ERROR_SHARING_VIOLATION.....共有違反

[使用例] タン(Button1)をクリックするとメモ帳が起動され、ユーザーがそのメモ帳を終了するまで待機する例です。
だし本来は、このような動作をさせる場合、終了待ちされるアプリケーションを ShellExecuteではなく CreateProcessで起動させるのが一般的なようです。
procedure TForm1.Button1Click( Sender: TObject);
var
  SXInfo: TShellExecuteInfo;
begin
  with SXInfo do//TShellExecuteInfo構造体の初期化
  begin
    cbSize := SizeOf( SXInfo);
    fMask := SEE_MASK_NOCLOSEPROCESS;//これがないと終了待ち出来ない
    Wnd := Application.Handle;
    lpVerb := 'open';
    lpFile := PChar( 'notepad.exe');
    lpParameters := Nil;
    lpDirectory := Nil;
    nShow := SW_SHOW;
  end;

  ShellExecuteEx( @SXInfo);
  Button1.Enabled := False;//メモ帳がいくつも起動されるとまずいので...

  //起動したアプリケーションの終了待ち
  while WaitForSingleObject( SXInfo.hProcess, 0) = WAIT_TIMEOUT do
    Application.ProcessMessages;

  ShowMessage( '終わったよ!');
  Button1.Enabled := True;
end;

ミニ解説: TShellExecuteInfo構造体

ShellExecuteEx関数で使われる情報を格納している構造体です。

TShellExecuteInfoA = record
  cbSize: DWORD;
  fMask: ULONG;
  Wnd: HWND;
  lpVerb: PAnsiChar;
  lpFile: PAnsiChar;
  lpParameters: PAnsiChar;
  lpDirectory: PAnsiChar;
  nShow: Integer;
  hInstApp: HINST;

  lpIDList: Pointer;
  lpClass: PAnsiChar;
  hkeyClass: HKEY;
  dwHotKey: DWORD;
  hIcon: THandle;
  hProcess: THandle;
end;

TShellExecuteInfo = TShellExecuteInfoA;

[メンバー]
cbSize.....構造体のサイズ
fMask.....他のメンバの内容に関するフラグ(以下に示すフラグの組合せ)
・SEE_MASK_CLASSKEY---hkeyClassを使用
・SEE_MASK_CLASSNAME---lpClassを使用
・SEE_MASK_CONNECTNETDRV---lpFileはネットワーク上のUNCパス
・SEE_MASK_DOENVSUBST---lpDirectoryあるいはlpFileで与えられる文字列にて指定されている環境変数を展開
・SEE_MASK_FLAG_DDEWAIT---ShellExecuteEx関数がDDE対話を開始させる場合、関数から返る前にDDE対話の終了を待つ
・SEE_MASK_FLAG_NO_UI---エラーが起きた場合エラーメッセージボックスを非表示
・SEE_MASK_HOTKEY---dwHotKeyが与えられている場合はホットキーを使用
・SEE_MASK_ICON---hIconのアイコンを使用
・SEE_MASK_IDLIST---lpIDListのアイテムIDリストを使用
・SEE_MASK_INVOKEIDLIST---lpIDListのアイテムIDリストを用いてアプリケーションを呼出す
(ヌルの場合は関数がアイテムIDリストを作成してアプリケーションを呼出す)
・SEE_MASK_NOCLOSEPROCESS---ShellExecuteEx関数が終了後、プロセスを実行したままにしておく
(hProcessがプロセスのハンドルを受取る)
Wnd.....エラーメッセージダイアログ等のメッセージボックスの親ウィンドウハンドル
lpVerb.....アプリケーションが実行する動作名へのポインタ(何も指定されない場合は「開く」になる)
lpFile.....開いたり印刷したりするファイル名へのポインタ
lpParameters.....アプリケーションに渡すスペース区切りのパラメータ(ヌル終端文字列)へのポインタ
(lpFileが文書ファイルを指す場合、lpParametersはヌル)
lpDirectory.....作業ディレクトリ名へのポインタ
nShow.....以下に示すShowコマンド(lpFileが文書ファイルの場合はゼロ)
・SW_SHOWDEFAULT.....アプリケーションを起動させたプログラムによってCreateProcess関数に渡されたTStartupInfo構造体に指定された、 SW_フラグを基にして表示状態を設定します。アプリケーションはこのフラグとともにShowWindowを呼び出して、 自身のメイン ウィンドウの初期表示状態を設定しなければなりません。
・SW_HIDE.....ウィンドウを非表示にし、 ほかのウィンドウをアクティブ化します。
・SW_MINIMIZE.....指定されたウィンドウをアイコン化し、 Z順序で次のトップ レベル ウィンドウをアクティブ化します。
・SW_RESTORE.....ウィンドウをアクティブ化して表示します。ウィンドウがアイコン化されていたり最大化されているときには、 Windowsが元のサイズと位置に復元します。アプリケーションは、 アイコン化されているウィンドウを復元ときにこのフラグを指定します。
・SW_SHOW.....ウィンドウをアクティブ化し、 現在のサイズと位置で表示します。
・SW_SHOWMAXIMIZED.....ウィンドウをアクティブ化し、 最大表示ウィンドウとして表示します。
・SW_SHOWMINIMIZED.....ウィンドウをアクティブ化し、 アイコン表示します。
・SW_SHOWMINNOACTIVE.....ウィンドウをアイコン表示します。アクティブ ウィンドウはアクティブな状態のままです。
・SW_SHOWNA.....ウィンドウを現在の状態で表示します。アクティブ ウィンドウはアクティブな状態のままです。
・SW_SHOWNOACTIVATE.....直前のサイズと位置でウィンドウを表示します。アクティブ ウィンドウはアクティブな状態のままです。
・SW_SHOWNORMAL.....ウィンドウをアクティブ化して表示します。ウィンドウがアイコン化されていたり最大化されているときには、 Windowsが元のサイズと位置に復元します。アプリケーションは、 最初にウィンドウを表示するときにこのフラグを指定します。
hInstApp.....アプリケーション(またはDDE)が起動成功した場合はそのインスタンスハンドル(またはDDEサーバーハンドル)、失敗した場合はエラー値(エラー値は以下に示すもののいずれか)
・SE_ERR_FNF---ファイルが見付からない
・SE_ERR_PNF---パスが見つからない
・SE_ERR_ACCESSDENIED---アクセス拒否された
・SE_ERR_OOM---メモリ不足
・SE_ERR_DLLNOTFOUND---DLLが見つからない
・SE_ERR_SHARE---開いたファイルの共有は不可
・SE_ERR_ASSOCINCOMPLETE---ファイルの関連付け情報が不完全
・SE_ERR_DDETIMEOUT---DDEがタイムアウト
・SE_ERR_DDEFAIL---DDEが失敗
・SE_ERR_DDEBUSY---DDEがビジー状態
・SE_ERR_NOASSOC---ファイルの関連付け情報が得られない
lpIDList.....実行するファイルを識別するアイテムIDリストを含んだTItemIDList構造体
lpClass.....ファイルクラス名もしくはGUID
hkeyClass.....ファイルクラスに対するレジストリキーのハンドル
dwHotKey.....アプリケーションのホットキー(下位バイトは仮想キーコード、上位バイトは以下のフラグの組合せ)
・HOTKEYF_ALT.....ALTキー
・HOTKEYF_CONTROL.....CTRLキー
・HOTKEYF_EXT.....Extendedキー
・HOTKEYF_SHIFT.....SHIFTキー
hIcon.....ファイルクラスに対するアイコンハンドル
hProcess.....新たに起動したアプリケーションのハンドル

1.8 FindExecutable関数

[概要]
定したファイルに関連付けられている実行ファイルの名前とハンドルを返します。まだどのDDEサーバーもDDE対話を初期化していない場合は、Resultに起動されたDDEサーバーへのパスが返されます。
Delphiでの宣言及び各パラメータの解説を以下に示します。
function FindExecutable(FileName, Directory: PChar; Result: PChar): HINST; stdcall;

{ パラメータ }
FileName(in):対象となるファイル名
Directory(in):デフォルトディレクトリ名
Result(out):FileNameに関連付けられている実行ファイル名

{ 返値 }

関数が成功した場合、33以上の値を返します。失敗した場合は32以下の値を返し、以下のいずれかの値を取ります。
 ・0.....システムはメモリ外かリソース外にある
 ・31.....関連付けが成されていない
 ・ERROR_FILE_NOT_FOUND.....ファイルが見付からない
 ・ERROR_PATH_NOT_FOUND.....パスが見つからない
 ・ERROR_BAD_FORMAT.....実行ファイルが不正

[使用例]
タン(Button1)をクリックするとオープンダイアログボックスが現れ、そこでユーザーがファイルを選択しOKボタンをクリックすると、ユーザーに選択されたファイルに関連付けられた実行ファイルのフルパスが Edit1に表示される例です。
procedure TForm1.Button1Click(Sender: TObject);
var
  ExeName: array[0..MAX_PATH] of char;
begin
  if not OpenDialog1.Execute then Exit;

  if FindExecutable( PChar(OpenDialog1.FileName), Nil, ExeName) > 32 then
    Edit1.Text := ExeName
  else
    Edit1.Text := 'None';
end;

1.9 ExtractAssociatedIcon関数

[概要]
ァイル中のインデックス付けされたアイコンのハンドルもしくは関連付けされたファイル中のアイコンのハンドルを返します。
数はまず、lpIconPathのファイル中のインデックス付けされたアイコンを探します。それで見つからなければ、関連付けされた実行ファイル中のアイコンを探します。
Delphiでの宣言及び各パラメータの解説を以下に示します。
function ExtractAssociatedIcon(hInst: HINST; lpIconPath: PChar; var lpiIcon: Word): HICON; stdcall;

{ パラメータ }
hInst(in):関数を呼出したアプリケーションのインスタンス
lpIconPath(in,out):アイコンのフルパス
lpiIcon(out):アイコンのインデックス

{ 返値 }

関数が成功すると、アイコンのハンドルを返します。失敗するとヌルを返します。

[使用例]
タン(Button1)をクリックするとオープンダイアログボックスが現れ、そこでユーザーがファイルを選択しOKボタンをクリックすると、ユーザーに選択されたファイルに関連付けられたアイコンがフォーム中心に描画される例です。
procedure TForm1.Button1Click(Sender: TObject);
var
  TheIcon: TIcon;
  lpiIcon: Word;
  FName: array[0..MAX_PATH] of char;
begin
  if not OpenDialog1.Execute then Exit;
  StrPCopy( FName, OpenDialog1.FileName);

  //アイコン生成
  TheIcon := TIcon.Create;
  TheIcon.Handle := ExtractAssociatedIcon( HInstance, FName, lpiIcon);

  //フォームに描画
  if TheIcon.Handle <> 0 then
    Form1.Canvas.Draw( (Width - TheIcon.Width) div 2
                , (Height - TheIcon.Height) div 2, TheIcon)
  else
    ShowMessage('エラー!');

  //アイコン破棄
  TheIcon.Free;
end;

1.10 ExtractIcon関数

[概要]
行ファイル、DLL、アイコンファイルから指定されたINDEXのアイコンハンドルを返します。
Delphiでの宣言及び各パラメータの解説を以下に示します。
function ExtractIcon(hInst: HINST; lpszExeFileName: PChar; nIconIndex: UINT): HICON; stdcall;

{ パラメータ }
hInst:関数を呼出したアプリケーションのインスタンス
lpszExeFileName:実行ファイル、DLL、アイコンファイルのファイル名
nIconIndex:アイコンのインデックス
(ゼロの場合ファイルの最初のアイコンが指定されたことになり、-1の場合関数はファイル中のアイコン数を返す)

{ 返値 }

関数が成功すればアイコンのハンドルを返します。指定されたファイルが実行ファイル、DLL、アイコンファイルでなかった場合は1を返します。アイコンが見つからなければヌルを返します。

[使用例]
タン(Button1)をクリックするとオープンダイアログボックスが現れ、そこでユーザーがファイルを選択しOKボタンをクリックすると、ユーザーに選択されたファイル中のアイコンを全て描画する例です。また、総アイコン数を Edit1に表示します。
procedure TForm1.Button1Click(Sender: TObject);
var
  TheIcon: TIcon;
  nIcon,i: integer;
  FName: array[0..MAX_PATH] of char;
begin
  if not OpenDialog1.Execute then Exit;
  StrPCopy( FName, OpenDialog1.FileName);

  //ファイルのチェック
  nIcon := integer( ExtractIcon( HInstance, FName, 0));
  if ( nIcon = 1 ) or ( nIcon = 0 ) then
  begin
    Edit1.text := 'アイコンはありません';
    Exit;
  end;

  //アイコン数を取得
  nIcon := integer( ExtractIcon( HInstance, FName, -1));
  Edit1.Text := IntToStr( nIcon) + ' icons exist in ' + FName;

  //アイコンの描画
  for i := 0 to nIcon - 1 do
  begin
    TheIcon := TIcon.Create;
    TheIcon.Handle := ExtractIcon( HInstance, FName, i );
    Form1.Canvas.Draw( i * 35, 30, TheIcon);
    TheIcon.Free;
  end;
end;

1.11 SHAppBarMessage関数

[概要]
AppBarメッセージをシステムに送ります。
ここで、AppBarとは、タスクバーや MS OFFICEのオフィスバー(?)のような、デスクトップの特定の場所に陣取るウィンドウ/バーのことを指します。
Delphiでの宣言及び各パラメータの解説を以下に示します。
function SHAppBarMessage(dwMessage: DWORD; var pData: TAppBarData): UINT; stdcall;

{ パラメータ }
dwMessage:送るAppBarメッセージの識別子(以下のいずれか1つ)
  ・ABM_ACTIVATE---AppBarがアクティブになった事をシステムに通知
・ABM_GETAUTOHIDEBAR---スクリーンの特定の端に関連付けられているオートハイドAppBarのハンドルを返す
・ABM_GETSTATE---タスクバーがオートハイドか常に最前面のどちらの常態にあるかを返す
・ABM_GETTASKBARPOS---タスクバーの使用領域を返す
・ABM_NEW---新しいAppBarを登録し、システムが通知に使用するメッセージIDを指定する
・ABM_QUERYPOS---AppBarのためのサイズとスクリーン位置を要求する
・ABM_REMOVE---AppBarの登録を削除する
・ABM_SETAUTOHIDEBAR---スクリーンの端にオートハイドAppBarを登録または削除する
・ABM_SETPOS---AppBarのサイズとスクリーン座標を設定する
・ABM_WINDOWPOSCHANGED---AppBarの位置が変更されたことをシステムに通知する
pData:TAppBarData構造体(各フィールドはdwMessageに依存する)

{ 返値 }

メッセージ依存の値を返します。

[使用例]
タン(Button1)をクリックするとタスクバーの位置情報が Edit1に表示される例です。
TAppBarData構造体の初期化すべきフィールドは AppBarに送るメッセージによって異なる点に注意して下さい。
procedure TForm1.Button1Click(Sender: TObject);
var
  AppbData: TAppBarData;
begin
  //TAppBarData構造体の初期化
  AppbData.cbSize := SizeOf(TAppBarData);

  SHAppBarMessage( ABM_GETTASKBARPOS, AppbData);

  //タスクバーの位置情報を表示
  Edit1.Text := ' ('
        + Format( 'Left : %d ', [AppbData.rc.Left])
        + Format( 'Right : %d ', [AppbData.rc.Right])
        + Format( 'Top : %d ', [AppbData.rc.Top])
        + Format( 'Bottom: %d ', [AppbData.rc.Bottom])
        + ')';
end;
れは、ボタン(Button1)をクリックするとForm2がタスクバーとして画面上部に登録される例です。
ただしここで注意しなければならないのは、シェルはAppBarを登録しても、その表示領域を確保するだけで、その他の動作は全てAppBarの側で実装しなければならない点です。したがって、タスクバーのようなものを作成するにはかなりの作業が必要となります。
var
  MyAppbData: TAppBarData;

procedure TForm2.FormCreate(Sender: TObject);
begin
  //MyAppbDataの登録
  MyAppbData.cbSize := SizeOf(MyAppbData);
  MyAppbData.hWnd := Handle;
  MyAppbData.uCallbackMessage := WM_USER + 100;
  SHAppBarMessage( ABM_NEW, MyAppbData);

  //MyAppbDataの位置をシェルに通知
  with MyAppbData do
  begin
    uEdge := ABE_TOP;
    rc.Left := 0;
    rc.Right := Screen.Width;
    rc.Top := 0;
    rc.Bottom := 40;
  end;
  SHAppBarMessage( ABM_SETPOS, MyAppbData);

  //Form2を実際に位置付けるのは実装者の仕事。
  //シェルはAppBar用のスペースを確保しているに過ぎない。
  //実際、このままのコードだと、この後Form2は自由に移動
  //できてしまう。
  //したがって、これはあくまでもAppBar登録・表示のため
  //の例。

  SetBounds( MyAppbData.rc.Left
        , MyAppbData.rc.Top
        , MyAppbData.rc.Right - MyAppbData.rc.Left
        , MyAppbData.rc.Bottom - MyAppbData.rc.Top);
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  //MyAppbDataの登録抹消
  SHAppBarMessage( ABM_REMOVE, MyAppbData);
end;

ミニ解説: TAppBarData構造体

SHAppBarMessage関数にて使用されるAppBarに関する構造体です。

TAppBarData = record
  cbSize: DWORD;
  hWnd: HWND;
  uCallbackMessage: UINT;
  uEdge: UINT;
  rc: TRect;
  lParam: LPARAM;
end;

[メンバー]
cbSize.....SizeOf(TAppBarData)
hWnd.....AppBarのハンドル
uCallbackMessage.....任意のメッセージID(hWndのAppBarにメッセージを通知する際(ABM_NEWメッセージを送る際)に使用)
uEdge.....スクリーンの端を指定するフラグ(ABM_GETAUTOHIDEBAR、ABM_QUERYPOS、ABM_SETAUTOHIDEBAR、ABM_SETPOSメッセージを送る際に使用し、以下のいずれか1つ)
 ・ABE_BOTTOM---下サイド
 ・ABE_LEFT--- 左サイド
 ・ABE_RIGHT---右サイド
 ・ABE_TOP---上サイド
rc.....AppBarやタスクバーのスクリーン座標での表示領域(ABM_GETTASKBARPOS、ABM_QUERYPOS、ABM_SETPOSメッセージを送る際に使用する)
lParam.....メッセージ依存のパラメータ(ABM_SETAUTOHIDEBARメッセージと共に使用される)

1.12 SHFileOperation関数

[概要]
ァイルシステム上のコピー、移動、リネーム、削除の各処理を行います。
ファイル操作中のダイアログボックス等が Windows標準のものなので、操作性の統一感が出ます。
Delphiでの宣言及び各パラメータの解説を以下に示します。
function SHFileOperation(const lpFileOp: TSHFileOpStruct): Integer; stdcall;

{ パラメータ }
lpFileOp:処理に必要な情報を格納するTSHFileOpStruct構造体

{ 返値 }

関数が成功すればゼロ、失敗すれば非ゼロを返します。

[使用例]
タン(Button1)をクリックするとオープンダイアログボックスが開き、そこで選択したファイル(複数可)をごみ箱に移動させる例です。
procedure TForm1.Button1Click(Sender: TObject);
var
  FileOp: TSHFileOpStruct;
  FNames: string;
  n: integer;
begin
  OpenDialog1.Options := OpenDialog1.Options + [ofAllowMultiSelect];
  if not OpenDialog1.Execute then Exit;

  //削除するファイルが複数の場合はヌル区切りの2重ヌル終端文字列にコピー
  with OpenDialog1.Files do
  begin
    FNames := '';
    for n := 0 to Count - 1 do
      FNames := FNames + Strings[n] + #0;
    FNames := FNames + #0;
  end;

  //FileOpの初期化
  //複数ファイルをごみ箱へ削除

  with FileOp do
  begin
    Wnd := Handle;
    wFunc := FO_DELETE;
    pFrom := PChar( FNames);
    pTo := Nil;
    fFlags := FOF_ALLOWUNDO;
  end;

  SHFileOperation( FileOp);
end;
タン(Button1)をクリックするとオープンダイアログボックスが開き、そこで選択したファイル(複数可)を"D:\backup"に移動させる例です。
procedure TForm1.Button1Click(Sender: TObject);
var
  FileOp: TSHFileOpStruct;
  FNames: string;
  n: integer;
begin
  OpenDialog1.Options := OpenDialog1.Options + [ofAllowMultiSelect];
  if not OpenDialog1.Execute then Exit;

  //コピーするファイルが複数の場合はヌル区切りの2重ヌル終端文字列にコピー
  with OpenDialog1.Files do
  begin
    FNames := '';
    for n := 0 to Count - 1 do
      FNames := FNames + Strings[n] + #0;
    FNames := FNames + #0;
  end;

  //FileOpの初期化
  //複数ファイルを"D:\backup"ディレクトリへ移動

  with FileOp do
  begin
    Wnd := Handle;
    wFunc := FO_MOVE;
    pFrom := PChar( FNames);
    pTo := PChar( 'D:\backup' + #0);
    fFlags := FOF_FILESONLY or FOF_NOCONFIRMMKDIR;
  end;

  SHFileOperation( FileOp);
end;

ミニ解説: TSHFileOpStruct構造体

SHFileOperation関数がファイル操作を行う際使用する情報を格納した構造体です。
pFromあるいはpToが不完全名である場合、現在のディレクトリはグローバルカレントドライブ、ディレクトリから設定されます。

TSHFileOpStructA = packed record
  Wnd: HWND;
  wFunc: UINT;
  pFrom: PAnsiChar;
  pTo: PAnsiChar;
  fFlags: FILEOP_FLAGS;
  fAnyOperationsAborted: BOOL;
  hNameMappings: Pointer;
  lpszProgressTitle: PAnsiChar;
end;

TSHFileOpStruct = TSHFileOpStructA;

[メンバー]
Wnd.....ファイル操作中の状態情報を表示するダイアログボックスのハンドル
wFunc.....ファイル操作の種類を表すフラグ(以下のいずれか1つ)
 ・FO_COPY---pFromからpToへファイルをコピーする
 ・FO_DELETE---pFromのファイルを削除する
 ・FO_MOVE---pFromからpToへファイルを移動する
 ・FO_RENAME---pFromのファイルをリネームする
pFrom.....ソースファイル名(複数の場合は、ヌル区切りで2重ヌル終端の文字列)
pTo.....デスティネーションファイル・ディレクトリ名(複数の場合はヌル区切り2重ヌル終端の文字列で、それぞれが pFrom の1つ1つのデスティネーションになる)
fFlags.....ファイル操作をコントロールする以下のフラグの組合せ
 ・FOF_ALLOWUNDO---可能ならアンドゥー情報を保持する
 ・FOF_CONFIRMMOUSE---未実装
 ・FOF_FILESONLY---ワイルドカード(*.*)が指定された場合、ファイルに対してのみ操作を行う
 ・FOF_MULTIDESTFILES---デスティネーションファイル・ディレクトリを複数指定する
 ・FOF_NOCONFIRMATION---表示されるダイアログボックスに「全てはい」を選択
 ・FOF_NOCONFIRMMKDIR---必要があれば新しいディレクトリを自動的に作成
 ・FOF_RENAMEONCOLLISION---既に同じファイル名が存在する場合「のコピー」というファイル名を与える
 ・FOF_SILENT---進捗ダイアログボックスを表示しない
 ・FOF_SIMPLEPROGRESS---進捗ダイアログボックスを表示(ファイル名は表示せず)
 ・FOF_WANTMAPPINGHANDLE---hNameMappingsを使用(ハンドルはSHFreeNameMappings関数で開放)
fAnyOperationsAborted.....処理が終了する前にユーザーが中断させた場合にTRUEが返される
hNameMappings.....fFlagsがFOF_WANTMAPPINGHANDLEを含む時使用され、TSHNameMapping構造体(後述)の配列を含むファイルネームマッピングオブジェクトのハンドル
lpszProgressTitle.....fFlagsがFOF_SIMPLEPROGRESSを含む時使用され、進捗ダイアログボックスのタイトル文字列へのポインタ

1.13 SHGetFileInfo関数

[概要]
ァイルシステム上のオブジェクト(ファイル、フォルダ等)に関する各種情報を返します。
Delphiでの宣言及び各パラメータの解説を以下に示します。
function SHGetFileInfo(pszPath: PAnsiChar; dwFileAttributes: DWORD; var psfi: TSHFileInfo; cbFileInfo, uFlags: UINT): DWORD; stdcall;

{ パラメータ }
pszPath(in):ファイルの相対・絶対パスを格納したバッファへのポインタ(uFlagsがSHGFI_PIDLを含む時はpszPathはシェルの名前空間内でファイルを識別するアイテムIDリストを指していなければならない)
dwFileAttributes(in):uFlagsがSHGFI_USEFILEATTRIBUTESを含む場合に使用されるファイル属性フラグ(以下のフラグの組合せ)
  ・FILE_ATTRIBUTE_ARCHIVE---アーカイブファイル
(アプリケーションはこのフラグをバックアップファイルや削除ファイルに対して付与します)
・FILE_ATTRIBUTE_COMPRESSED---圧縮ファイル(圧縮フォルダ)
・FILE_ATTRIBUTE_DIRECTORY---ディレクトリ
・FILE_ATTRIBUTE_HIDDEN---隠しファイル
・FILE_ATTRIBUTE_NORMAL---属性無し(このフラグは単独で使用される)
・FILE_ATTRIBUTE_OFFLINE---ファイルのデータをすぐには利用できない
(ファイル、データがオフラインストレージに物理的に移動されたことを示す)
・FILE_ATTRIBUTE_READONLY---読込み専用
・FILE_ATTRIBUTE_SYSTEM---システムファイル
(OSの一部かあるいはOSにより排他的に使用されるファイル)
・FILE_ATTRIBUTE_TEMPORARY---テンポラリファイル
(メディアにフラッシュされない限りデータのほとんどがメモリ上に存在する)
psfi(out):TSHFileInfo構造体
cbFileInfo(in):TSHFileInfo構造体のサイズ
uFlags(in):返されるファイル情報を指定するフラグ(以下のフラグの組合せ)
  ・SHGFI_ATTRIBUTES.....ファイル属性フラグを返す
(属性フラグはpsfiにより指定されるTSHFileInfo構造体のdwAttributesにコピーされる)
・SHGFI_DISPLAYNAME.....ファイルの表示名を返す
(表示名はpsfiにより指定されるTSHFileInfo構造体のszDisplayNameにコピーされる)
・SHGFI_EXETYPE.....pszPathが実行ファイルの場合実行ファイルのタイプを返す
(このフラグは単独で用いられ返値は以下の通り)
 0 ---> 非実行ファイルあるいはエラー
 LOWORD = NE or PE
 HIWORD = 3.0, 3.5, 4.0 ---> ウィンドウズアプリケーション
 LOWORD = MZ
 HIWORD = 0 ---> MS-DOS .EXE, .COM .BAT file
 LOWORD = PE
 HIWORD = 0 ---> Win32 コンソールアプリケーション
・SHGFI_ICON.....ファイルを表すアイコンのハンドル及びシステムイメージリスト内のアイコンインデックスを返す
(psfiにより指定されるTSHFileInfo構造体のhIcon、iIconにコピーされ、システムイメージリストのハンドルを返す)
・SHGFI_ICONLOCATION.....ファイルを表すアイコンを含むファイル名を返す
(ファイル名はpsfiにより指定されるTSHFileInfo構造体のszDisplayNameにコピーされる)
・SHGFI_LARGEICON.....大きなアイコンを返すSHGFI_ICON指定
・SHGFI_LINKOVERLAY.....ファイルアイコンにリンクを追加するSHGFI_ICON指定
・SHGFI_OPENICON.....「開いた」アイコンを返すSHGFI_ICON指定
・SHGFI_PIDL.....pszPathはパスではなくアイテムIDリストへのポインタを指す
・SHGFI_SELECTED.....アイコンにシステムハイライト色を混ぜるSHGFI_ICON指定
・SHGFI_SHELLICONSIZE.....シェルサイズのアイコンを返すSHGFI_ICON指定
・SHGFI_SMALLICON.....小さいアイコンを返すSHGFI_ICON指定
・SHGFI_SYSICONINDEX.....システムイメージリスト内のアイコンインデックスを返す
(インデックスはpsfiにより指定されるTSHFileInfo構造体のiIconにコピーされる)
・SHGFI_TYPENAME.....ファイルタイプを表す文字列を返す
(文字列はpsfiにより指定されるTSHFileInfo構造体のszTypeNameにコピーされる)
・SHGFI_USEFILEATTRIBUTES.....dwFileAttributesを使用する

{ 返値 }

返値はuFlagsに依存します。
uFlagsがSHGFI_EXETYPEの場合、返値は上述の実行ファイルタイプを表します。
また、uFlagsがSHGFI_ICONあるいはSHGFI_SYSICONINDEXを含む場合は、返値は大きなアイコンを含むシステムイメージリストのハンドルを表し、SHGFI_SMALLICONが指定されている場合は小さなアイコンを含むシステムイメージリストのハンドルを表します。
uFlagsがSHGFI_EXETYPE、SHGFI_ICON、SHGFI_SYSICONINDEX、SHGFI_SMALLICONを含まない場合は、関数が成功すると非ゼロ値が返され、失敗するとゼロが返されます。

[使用例]
タン(Button1)をクリックすると"C:\Program Files\BORLAND\DELPHI 3\BIN"ディレクトリ中の全てのファイル名とそのアイコンを ListView1に表示する例です。
procedure TForm1.AddIcon( FName: string);
var
  FileInfo:TSHFileInfo;
  LclIcon:TIcon;
  LclListItem:TListItem;
begin
  {どこかで ImageList1のサイズを大きいアイコン用にしておく
  ImageList1.Width := 32;
  ImageList1.Height := 32; }


  ShGetFileInfo( PChar(FName), 0, FileInfo, SizeOf(FileInfo),
            SHGFI_ICON or SHGFI_LARGEICON or SHGFI_DISPLAYNAME);

  //追加するアイコン作成
  LclIcon := TIcon.Create;
  LclIcon.Handle := FileInfo.hIcon;

  //ListView1にアイコン、表示名追加
  LclListItem := ListView1.Items.Add;
  LclListItem.Caption := FileInfo.szDisplayName;
  LclListItem.ImageIndex := ImageList1.AddIcon( LclIcon);

  //アイコンオブジェクト開放
  LclIcon.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  SR: TSearchRec;
  Dir: string;
begin
  Dir := 'C:\Program Files\BORLAND\DELPHI 3\BIN\';

  if FindFirst( Dir + '*.*', faAnyFile, SR) = 0 then
  begin
    AddIcon( Dir + SR.Name);

    while FindNext( SR) = 0 do
      AddIcon( Dir + SR.Name);

    FindClose( SR);
  end;
end;

ミニ解説: TSHFileInfo構造体

ァイルオブジェクトに関する情報を含む構造体です。

TSHFileInfoA = record
  hIcon: HICON;
  iIcon: Integer;
  dwAttributes: DWORD;
  szDisplayName: array [0..MAX_PATH-1] of AnsiChar;
  szTypeName: array [0..79] of AnsiChar;
end;

TSHFileInfo = TSHFileInfoA;

[メンバー]
hIcon.....ファイル用のアイコンのハンドル
iIcon.....システムイメージリスト内のアイコンインデックス
dwAttributes.....ファイルオブジェクトの属性フラグ(ゼロあるいはファイルの共通属性を示す以下のフラグの組合せ)
(キャパビリティ関連)
 ・SFGAO_CANCOPY.....コピー可能
 ・SFGAO_CANDELETE.....削除可能
 ・SFGAO_CANLINK.....ショートカット作成可能
 ・SFGAO_CANMOVE.....移動可能
 ・SFGAO_CANRENAME.....リネーム可能
 ・SFGAO_DROPTARGET.....ドロップされたターゲット
 ・SFGAO_HASPROPSHEET.....プロパティシート有り
 ・SFGAO_CAPABILITYMASK......キャパビリティ用マスク(Andをとってキャパビリティに関するフラグのみを取出す)
(ディスプレイ関連)
 ・SFGAO_GHOSTED.....ゴーストアイコン(半透明アイコン)で表示
 ・SFGAO_LINK.....ショートカット
 ・SFGAO_READONLY.....読込み専用
 ・SFGAO_SHARE .....共有ファイル
 ・SFGAO_DISPLAYATTRMASK.....ディスプレイ用マスク(Andをとってディスプレイに関するフラグのみを取出す)
(コンテンツ関連)
 ・SFGAO_FILESYSTEM.....ファイルシステムの一部(ファイル、ディレクトリ、ルートディレクトリ)
 ・SFGAO_FILESYSANCESTOR.....ファイルシステムフォルダを含む
 ・SFGAO_FOLDER.....フォルダ
 ・SFGAO_HASSUBFOLDER.....サブフォルダを持つ
 ・SFGAO_CONTENTSMASK.....コンテンツ用マスク(Andをとってコンテンツに関するフラグのみを取出す)
(その他)
 ・SFGAO_REMOVABLE.....リムーバブルメディア上に存在
 ・SFGAO_VALIDATE.....キャッシュ情報を正当化する
 ・SFGAO_COMPRESSED.....圧縮されている
szDisplayName.....対象ファイルのウィンドウズシェル内での表示名あるいは対象ファイルを表しているアイコンを含むファイルへのフルパス
szTypeName.....ファイルタイプを表す文字列

進め!中級プログラマー 創刊号
次号予告
号のテーマは今回に引き続き、「シェルと仲良くする( Part2 )」と題しまして「2. 拡張シェルオブジェクト」について解説します。
当は今回だけで、拡張シェルオブジェクトも含めた「シェルと仲良くする」を終了させるつもりだったのですが、予想していた以上に作成が難航してしまい、2回に分けて掲載することとなりました。
ネタがあればすぐ作成できる、という僕の読みは非常に甘かったようです。断片的なネタをまとまった文章に組み立てる難しさを思い知らされてしまいました。
者の皆さんにとっても(2部構成になったことは)かったるいことと思いますが、どうかご勘弁をお願いします。
ェルを取扱う、拡張する、は32ビット版 Windowsの一つの売りであり、また面白い話題でもありますので、何とか次号でそれなりの形にまとめたいと思います。

だし、次号発刊日は未定です。今回のでかなり疲れてしまったので少し休養します。(毎日が休養だろ!というお叱りの声が...)まあ、あまり期待しないで適当に待っていて下さい。

トップページに戻る

メール作成 ご意見・ご要望等は左のポストをクリックして杉浦(gv4j-sgur@asahi-net.or.jp)までお寄せ下さい
なお、当サイトは「Netscape Communicator 4.5 for MS Windows」でのみ表示・動作が調整されております
Internet Explorer の場合、正常に表示・動作しない可能性がありますのでご了承下さい。
Copyright © 1998 Jun-ya Sugiura and Hanayo Sugiura. All rights reserved. Updated - 8 January 2000