サイトのトップページへ リンクのページへ ロゴマーク
掲載 2005年02月11日 更新 2010年11月27日 Delphiサンプルプログラム集
460_特殊フォルダのフルパスを取得
動作確認等 Windows XP(SP3) + Delphi 2010(UP5) Pro
Windows 7 U64 + Delphi 2010(UP5) Pro
 460_SpecialFolderPath.zip [1,445 KB] 2010年11月27日版(EXE同梱)
[前のページ][次のページ]


■ 01_特殊フォルダのフルパスを取得 TOpenDialogで表示
■ 02_特殊フォルダのフルパスを取得 TShellListViewで表示
■ 03_特殊フォルダのフルパスを取得 TShellListViewで表示 2

  • 2007年10月29日
  • フルパスの取得をシェルネームスペースを使用するコードに変更
  • 2008年11月24日
  • 項目識別子のメモリアロケートの解放を忘れていたので追加
  • Windows Vistaに対応するためにCSIDL値のリストの方式を変更
  • 2009年12月10日
  • Delphi2010対応コードに修正
  • クリックではなくダブルクリックでダイアログ表示に変更
  • [ENTER]キーでも表示するようにした
  • シェルコンポーネントのTShellListViewで表示するサンプルを追加
  • 2010年03月30日
  • サンプル[03]を追加
  • 2010年08月20日
  • リスト4を追加
  • 2010年11月27日
  • GetDispNameFromPItemID関数の修正(Unicode対応になっていなかった)




01_特殊フォルダのフルパスを取得 TOpenDialog で表示


シェル関数類SHGetSpecialFolderLocation関数を使用したサンプルです.CSIDL(特殊フォルダを識別する値)を指定して,[送る][マイドキュメント]等の特殊フォルダのフルパス名を取得します.
動作はOSやIE(Shell32.dll)によっても多少違ってきます.


図1 設計時画面
  • 以下を配置
    CSIDLを一覧表示するTListBox
    [ファイル選択]ダイアログのTOpenDialog
    フルパスを表示するTEdit
図2 実行時画面
  • ListBox1にCSIDL値をリスト表示
  • 項目ダブルクリックまたは[ENTER]でファイル選択ダイアログ表示
  • 表示後,TEditにフルパス表示
図3 デスクトップを表示

リスト1 
特殊フォルダのフルパスを取得
unit SpecialFolderPath_OpenDialogUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    OpenDialog1: TOpenDialog;
    ListBox1: TListBox;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure ListBox1DblClick(Sender: TObject);
    procedure ListBox1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private 宣言 }
    function GetFolderPathEx(const nFolder:Integer):String ;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses ShlObj, ActiveX;

//-----------------------------------------------------------------------------
//  項目識別子からフォルダまたはファイルの表示名を求める
//
//  第1引数  対象の項目識別子を取得する際に使用したシェルフォルダオブジェクト
//  第2引数  対象の項目識別子
//  第3引数  取得する表示名の種類で以下のいずれか
//           SHGDN_NORMAL      表示用(デフォルトでエクスプローラでの表示名)
//           SHGDN_INFOLDER    フォルダ内の表示名
//          SHGDN_FORPARSING  親フォルダのParseDisplayNameに渡す表示名
//-----------------------------------------------------------------------------
function GetDispNameFromPItemID(ShFolder: IShellFolder; ItemID: PItemIDList;
     Flag: DWORD): String;
var
  StrRet : TStrRet;
begin
  Result := '';
  if ShFolder = nil then
    exit;
  if ItemID = nil then
    exit;

  FillChar(StrRet, SizeOf(StrRet), 0);
  if NOERROR = ShFolder.GetDisplayNameOf(ItemID, Flag, StrRet) then
  begin
    case StrRet.uType of
      STRRET_CSTR:
        begin
          SetString(Result, StrRet.cStr, Length(StrRet.cStr));
        end;
      STRRET_OFFSET:
        begin
          //ポインタのオフセット
          Inc(pByte(ItemID), StrRet.uOffset);
          Result := PChar(ItemID);
        end;
      STRRET_WSTR:
        begin
          Result := StrRet.pOleStr;
        end;
    end;
  end;
end;

//=============================================================================
//  ListBoxの項目値をダブルクリックしたらそのCSIDLのフォルダを初期ディレクトリ
//  にして[ファイル選択]ダイアログを表示
//=============================================================================
procedure TForm1.ListBox1DblClick(Sender: TObject);
var
  indx  : Integer;
  CSIDL : Integer;
  ADir  : String;
begin
  //ListBox1のIndexを取得してそのTObjectで定義した値を取出す
  indx  := ListBox1.ItemIndex;
  CSIDL := Integer(ListBox1.Items.Objects[indx]);

  ADir := GetFolderPathEx(CSIDL);
  Edit1.Text := ADir;

  if ADir <> '' then
  begin
    OpenDialog1.InitialDir := ADir;
    Update;
    OpenDialog1.Execute;
  end else
  begin
    ShowMessage('取得できませんでした. ');
  end;
end;

//=============================================================================
//  [ENTER]キーでも表示
//=============================================================================
procedure TForm1.ListBox1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then
  begin
    ListBox1DblClick(nil);
  end;
end;

//=============================================================================
//  CSIDLから特殊フォルダのフルパス名を取得する関数
//  第1引数は,SH...が表示するかも知れないメッセージボックスのオーナウィンドウ
//  のハンドル
//=============================================================================
function TForm1.GetFolderPathEx(const nFolder: Integer): String;
var
  FDesktopShFolder : IShellFolder;
  ItemID  : PItemIDList;
  AMalloc : IMalloc;
begin
  //項目識別子解放のためのメモリアロケーションのポインタ取得
  ShGetMalloc(AMalloc);

  //デスクトップのシェルオブジェクト取得
  SHGetDesktopFolder(FDesktopSHFolder);
  try
    //CSIDL値を項目識別子に変換
    SHGetSpecialFolderLocation(Handle, nFolder, ItemID);

    //その項目識別子に相当するパス名の文字列を取得
    //ファイル名はデスクトップオブジェクトを基準としたもの
    //シェルネームスペースの項目識別子はすべてデスクトップが大元のルート
    Result := GetDispNameFromPItemID(FDesktopSHFolder, ItemID, SHGDN_FORPARSING);
  finally
    //項目識別子メモリアロケーション解放
    AMalloc.Free(ItemID);
  end;
end;

//=============================================================================
//  Form生成時
//  ListBox1の各ItemにAddObjectでListBox1に表示する文字列と各CSIDL値をセット
//  Vistaにしか対応していないCSIDL_値があるので定数名ではなく実値を格納
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  with ListBox1.Items do
  begin
    AddObject('CSIDL_DESKTOP',                 TObject($0000));
    AddObject('CSIDL_INTERNET',                TObject($0001));
    AddObject('CSIDL_PROGRAMS',                TObject($0002));
    AddObject('CSIDL_CONTROLS',                TObject($0003));
    AddObject('CSIDL_PRINTERS',                TObject($0004));
    AddObject('CSIDL_PERSONAL',                TObject($0005));
    AddObject('CSIDL_FAVORITES',               TObject($0006));
    AddObject('CSIDL_STARTUP',                 TObject($0007));
    AddObject('CSIDL_RECENT',                  TObject($0008));
    AddObject('CSIDL_SENDTO',                  TObject($0009));
    AddObject('CSIDL_BITBUCKET',               TObject($000A));
    AddObject('CSIDL_STARTMENU',               TObject($000B));
    AddObject('CSIDL_MYDOCUMENTS',             TObject($000C));
    AddObject('CSIDL_MYMUSIC',                 TObject($000D));
    AddObject('CSIDL_MYVIDEO',                 TObject($000E));
    AddObject('CSIDL_DESKTOPDIRECTORY',        TObject($0010));
    AddObject('CSIDL_DRIVES',                  TObject($0011));
    AddObject('CSIDL_NETWORK',                 TObject($0012));
    AddObject('CSIDL_NETHOOD',                 TObject($0013));
    AddObject('CSIDL_FONTS',                   TObject($0014));
    AddObject('CSIDL_TEMPLATES',               TObject($0015));
    AddObject('CSIDL_COMMON_STARTMENU',        TObject($0016));
    AddObject('CSIDL_COMMON_PROGRAMS',         TObject($0017));
    AddObject('CSIDL_COMMON_STARTUP',          TObject($0018));
    AddObject('CSIDL_COMMON_DESKTOPDIRECTORY', TObject($0019));
    AddObject('CSIDL_APPDATA',                 TObject($001A));
    AddObject('CSIDL_PRINTHOOD',               TObject($001B));
    AddObject('CSIDL_LOCAL_APPDATA',           TObject($001C));
    AddObject('CSIDL_ALTSTARTUP',              TObject($001D));
    AddObject('CSIDL_COMMON_ALTSTARTUP',       TObject($001E));
    AddObject('CSIDL_COMMON_FAVORITES',        TObject($001F));
    AddObject('CSIDL_INTERNET_CACHE',          TObject($0020));
    AddObject('CSIDL_COOKIES',                 TObject($0021));
    AddObject('CSIDL_HISTORY',                 TObject($0022));
    AddObject('CSIDL_COMMON_APPDATA',          TObject($0023));
    AddObject('CSIDL_WINDOWS',                 TObject($0024));
    AddObject('CSIDL_SYSTEM',                  TObject($0025));
    AddObject('CSIDL_PROGRAM_FILES',           TObject($0026));
    AddObject('CSIDL_MYPICTURES',              TObject($0027));
    AddObject('CSIDL_PROFILE',                 TObject($0028));
    AddObject('CSIDL_SYSTEMX86',               TObject($0029));
    AddObject('CSIDL_PROGRAM_FILESX86',        TObject($002A));
    AddObject('CSIDL_PROGRAM_FILES_COMMON',    TObject($002B));
    AddObject('CSIDL_PROGRAM_FILES_COMMONX86', TObject($002C));
    AddObject('CSIDL_COMMON_TEMPLATES',        TObject($002D));
    AddObject('CSIDL_COMMON_DOCUMENTS',        TObject($002E));
    AddObject('CSIDL_COMMON_ADMINTOOLS',       TObject($002F));
    AddObject('CSIDL_ADMINTOOLS',              TObject($0030));
    AddObject('CSIDL_CONNECTIONS',             TObject($0031));
    AddObject('CSIDL_COMMON_MUSIC',            TObject($0035));
    AddObject('CSIDL_COMMON_PICTURES',         TObject($0036));
    AddObject('CSIDL_COMMON_VIDEO',            TObject($0037));
    AddObject('CSIDL_RESOURCES',               TObject($0038));
    AddObject('CSIDL_RESOURCES_LOCALIZED',     TObject($0039));
    AddObject('CSIDL_COMMON_OEM_LINKS',        TObject($003A));
    AddObject('CSIDL_CDBURN_AREA',             TObject($003B));
    AddObject('CSIDL_COMPUTERSNEARME',         TObject($003D));
    AddObject('CSIDL_PROFILES',                TObject($003E));
  end;

  Self.Width     := 350;
  Edit1.Width    := Self.Width - 14;
  ListBox1.Width := Self.Width - 14;
end;

end.

[ 頁先頭 ]



02_特殊フォルダのフルパスを取得 TShellListView で表示


選択したフォルダ内を,Delphiの[Demos]フォルダにあるシェルコンポーネントで表示する例です.リスト1ではプリンタ等のフォルダ内は表示しませんが,こちらでは表示します.項目を選択して表示すると,TShellListViewを配置した別のフォームを表示します.表示するフォームのユニットには追加コードはありません.
シェルコンポーネント類のインストール方法は,iPentecさんの[Shell コンポーネントの追加]の記事を参考にしてください.
リスト1同様,動作はOSやIE(Shell32.dll)によっても多少違ってきます.


図4 設計時画面
  • 以下を配置
    CSIDLを一覧表示するTListBox
    フルパスを表示するTEdit
図5 実行時画面
  • ListBox1にCSIDL値をリスト表示
  • 項目ダブルクリックまたは[ENTER]で該当フォルダ内を表示
  • 表示後,TEditにフルパス表示
図6 プリンタのフォルダ内を表示

リスト2 
特殊フォルダのフルパスを取得
unit SpecialFolderPath_ShellListViewUnit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure ListBox1DblClick(Sender: TObject);
    procedure ListBox1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private 宣言 }
    procedure GetFolderPathEx(const nFolder:Integer; var ADir,DispName: String);
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses ShlObj, ActiveX, Unit2;

//-----------------------------------------------------------------------------
//  項目識別子からフォルダまたはファイルの表示名を求める
//
//  第1引数  対象の項目識別子を取得する際に使用したシェルフォルダオブジェクト
//  第2引数  対象の項目識別子
//  第3引数  取得する表示名の種類で以下のいずれか
//           SHGDN_NORMAL      表示用(デフォルトでエクスプローラでの表示名)
//           SHGDN_INFOLDER    フォルダ内の表示名
//          SHGDN_FORPARSING  親フォルダのParseDisplayNameに渡す表示名
//-----------------------------------------------------------------------------
function GetDispNameFromPItemID(ShFolder: IShellFolder; ItemID: PItemIDList;
     Flag: DWORD): String;
var
  StrRet : TStrRet;
begin
  Result := '';
  if ShFolder = nil then
    exit;
  if ItemID = nil then
    exit;

  FillChar(StrRet, SizeOf(StrRet), 0);
  if NOERROR = ShFolder.GetDisplayNameOf(ItemID, Flag, StrRet) then
  begin
    case StrRet.uType of
      STRRET_CSTR:
        begin
          SetString(Result, StrRet.cStr, Length(StrRet.cStr));
        end;
      STRRET_OFFSET:
        begin
          //ポインタのオフセット
          Inc(pByte(ItemID), StrRet.uOffset);
          Result := PChar(ItemID);
        end;
      STRRET_WSTR:
        begin
          Result := StrRet.pOleStr;
        end;
    end;
  end;
end;

//=============================================================================
//  ListBoxの項目値をダブルクリックしたらそのCSIDLのフォルダを初期ディレクトリ
//  にしてForm2のShellListView1にそのフォルダをリスト表示
//  ShellListView1は以下の設定
//  Align := Client;
//  ViewStyle := vsReport
//=============================================================================
procedure TForm1.ListBox1DblClick(Sender: TObject);
var
  indx     : Integer;
  CSIDL    : Integer;
  ADir     : String;
  DispName : String;
begin
  //ListBox1のIndexを取得してそのTObjectで定義した値を取出す
  indx  := ListBox1.ItemIndex;
  CSIDL := Integer(ListBox1.Items.Objects[indx]);

  //戻り値はADirとDispName
  GetFolderPathEx(CSIDL, ADir, DispName);

  Edit1.Text := ADir;

  if ADir <> '' then
  begin
    Form2.ShellListView1.Root := ADir;
    //フォームのCaptionにCSIDL値とエクスプローラの表示名と同じ文字列を表示
    Form2.Caption := ListBox1.Items[Indx] + '  '+ DispName;
    Form2.ShowModal;
  end else
  begin
    ShowMessage('取得できませんでした. ');
  end;
end;

//=============================================================================
//  [ENTER]キーでも表示
//=============================================================================
procedure TForm1.ListBox1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then
  begin
    ListBox1DblClick(nil);
  end;
end;

//=============================================================================
//  CSIDLから特殊フォルダのフルパス名と表示名を取得する関数
//  第1引数は,SH...が表示するかも知れないメッセージボックスのオーナウィンドウ
//  のハンドル
//=============================================================================
procedure TForm1.GetFolderPathEx(const nFolder: Integer;
  var ADir,DispName: String);
var
  FDesktopShFolder : IShellFolder;
  ItemID  : PItemIDList;
  AMalloc : IMalloc;
begin
  //項目識別子解放のためのメモリアロケーションのポインタ取得
  ShGetMalloc(AMalloc);

  //デスクトップのシェルオブジェクト取得
  SHGetDesktopFolder(FDesktopSHFolder);
  try
    //CSIDL値を項目識別子に変換
    SHGetSpecialFolderLocation(Handle, nFolder, ItemID);

    //その項目識別子に相当するパス名の文字列と表示名を取得
    //ファイル名はデスクトップオブジェクトを基準としたもの
    //シェルネームスペースの項目識別子はすべてデスクトップが大元のルート
    ADir     := GetDispNameFromPItemID(FDesktopSHFolder, ItemID, SHGDN_FORPARSING);
    DispName := GetDispNameFromPItemID(FDesktopSHFolder, ItemID, SHGDN_NORMAL);
  finally
    //項目識別子メモリアロケーション解放
    AMalloc.Free(ItemID);
  end;
end;

//=============================================================================
//  Form生成時
//  ListBox1の各ItemにAddObjectでListBox1に表示する文字列と各CSIDL値をセット
//  Vistaにしか対応していないCSIDL_値があるので定数名ではなく実値を格納
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  with ListBox1.Items do
  begin
    AddObject('CSIDL_DESKTOP',                 TObject($0000));
    AddObject('CSIDL_INTERNET',                TObject($0001));
    AddObject('CSIDL_PROGRAMS',                TObject($0002));
    AddObject('CSIDL_CONTROLS',                TObject($0003));
    AddObject('CSIDL_PRINTERS',                TObject($0004));
    AddObject('CSIDL_PERSONAL',                TObject($0005));
    AddObject('CSIDL_FAVORITES',               TObject($0006));
    AddObject('CSIDL_STARTUP',                 TObject($0007));
    AddObject('CSIDL_RECENT',                  TObject($0008));
    AddObject('CSIDL_SENDTO',                  TObject($0009));
    AddObject('CSIDL_BITBUCKET',               TObject($000A));
    AddObject('CSIDL_STARTMENU',               TObject($000B));
    AddObject('CSIDL_MYDOCUMENTS',             TObject($000C));
    AddObject('CSIDL_MYMUSIC',                 TObject($000D));
    AddObject('CSIDL_MYVIDEO',                 TObject($000E));
    AddObject('CSIDL_DESKTOPDIRECTORY',        TObject($0010));
    AddObject('CSIDL_DRIVES',                  TObject($0011));
    AddObject('CSIDL_NETWORK',                 TObject($0012));
    AddObject('CSIDL_NETHOOD',                 TObject($0013));
    AddObject('CSIDL_FONTS',                   TObject($0014));
    AddObject('CSIDL_TEMPLATES',               TObject($0015));
    AddObject('CSIDL_COMMON_STARTMENU',        TObject($0016));
    AddObject('CSIDL_COMMON_PROGRAMS',         TObject($0017));
    AddObject('CSIDL_COMMON_STARTUP',          TObject($0018));
    AddObject('CSIDL_COMMON_DESKTOPDIRECTORY', TObject($0019));
    AddObject('CSIDL_APPDATA',                 TObject($001A));
    AddObject('CSIDL_PRINTHOOD',               TObject($001B));
    AddObject('CSIDL_LOCAL_APPDATA',           TObject($001C));
    AddObject('CSIDL_ALTSTARTUP',              TObject($001D));
    AddObject('CSIDL_COMMON_ALTSTARTUP',       TObject($001E));
    AddObject('CSIDL_COMMON_FAVORITES',        TObject($001F));
    AddObject('CSIDL_INTERNET_CACHE',          TObject($0020));
    AddObject('CSIDL_COOKIES',                 TObject($0021));
    AddObject('CSIDL_HISTORY',                 TObject($0022));
    AddObject('CSIDL_COMMON_APPDATA',          TObject($0023));
    AddObject('CSIDL_WINDOWS',                 TObject($0024));
    AddObject('CSIDL_SYSTEM',                  TObject($0025));
    AddObject('CSIDL_PROGRAM_FILES',           TObject($0026));
    AddObject('CSIDL_MYPICTURES',              TObject($0027));
    AddObject('CSIDL_PROFILE',                 TObject($0028));
    AddObject('CSIDL_SYSTEMX86',               TObject($0029));
    AddObject('CSIDL_PROGRAM_FILESX86',        TObject($002A));
    AddObject('CSIDL_PROGRAM_FILES_COMMON',    TObject($002B));
    AddObject('CSIDL_PROGRAM_FILES_COMMONX86', TObject($002C));
    AddObject('CSIDL_COMMON_TEMPLATES',        TObject($002D));
    AddObject('CSIDL_COMMON_DOCUMENTS',        TObject($002E));
    AddObject('CSIDL_COMMON_ADMINTOOLS',       TObject($002F));
    AddObject('CSIDL_ADMINTOOLS',              TObject($0030));
    AddObject('CSIDL_CONNECTIONS',             TObject($0031));
    AddObject('CSIDL_COMMON_MUSIC',            TObject($0035));
    AddObject('CSIDL_COMMON_PICTURES',         TObject($0036));
    AddObject('CSIDL_COMMON_VIDEO',            TObject($0037));
    AddObject('CSIDL_RESOURCES',               TObject($0038));
    AddObject('CSIDL_RESOURCES_LOCALIZED',     TObject($0039));
    AddObject('CSIDL_COMMON_OEM_LINKS',        TObject($003A));
    AddObject('CSIDL_CDBURN_AREA',             TObject($003B));
    AddObject('CSIDL_COMPUTERSNEARME',         TObject($003D));
    AddObject('CSIDL_PROFILES',                TObject($003E));
  end;

  Self.Width     := 350;
  Edit1.Width    := Self.Width - 14;
  ListBox1.Width := Self.Width - 14;
end;

end.

[ 頁先頭 ]



03_特殊フォルダのフルパスを取得 TShellListView で表示 2


リスト2とほとんど同じですが,ネット上でよく見かける例です.シェルフォルダオブジェクト等のシェルネームスペースを使用しないコードです.このコードはシンプルですが,リスト2では取得できる特殊フォルダのフルパスが取得できないことがあります.それはGUIDで表されるフォルダです.動作を確認して,これでも十分な場合は利用する価値はあります.


図7 実行例

リスト3 
特殊フォルダのフルパスを取得
シェルフォルダオブジェクトの処理を省略したコード
unit SpecialFolderPath_ShellListView2Unit;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Edit1: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure ListBox1DblClick(Sender: TObject);
    procedure ListBox1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private 宣言 }
    function GetFolderPathEx(const nFolder:Integer): String;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses ShlObj, ActiveX, Unit2;

//=============================================================================
//  ListBoxの項目値をダブルクリックしたらそのCSIDLのフォルダを初期ディレクトリ
//  にしてForm2のShellListView1にそのフォルダをリスト表示
//  ShellListView1は以下の設定
//  Align := Client;
//  ViewStyle := vsReport
//=============================================================================
procedure TForm1.ListBox1DblClick(Sender: TObject);
var
  indx  : Integer;
  CSIDL : Integer;
  ADir  : String;
begin
  //ListBox1のIndexを取得してそのTObjectで定義した値を取出す
  indx  := ListBox1.ItemIndex;
  CSIDL := Integer(ListBox1.Items.Objects[indx]);

  //戻り値はADir
  ADir := GetFolderPathEx(CSIDL);
  Edit1.Text := ADir;

  if ADir <> '' then
  begin
    Form2.ShellListView1.Root := ADir;
    //取得したフォルダをForm2で表示
    Form2.ShowModal;
  end else
  begin
    ShowMessage('取得できませんでした. ');
  end;
end;

//=============================================================================
//  [ENTER]キーでも表示
//=============================================================================
procedure TForm1.ListBox1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_RETURN then
  begin
    ListBox1DblClick(nil);
  end;
end;

//=============================================================================
//  CSIDLから特殊フォルダのフルパス名と表示名を取得する関数
//  第1引数は,SH...が表示するかも知れないメッセージボックスのオーナウィンドウ
//  のハンドル
//=============================================================================
function TForm1.GetFolderPathEx(const nFolder: Integer): String;
var
  Path    : array[0..MAX_PATH] of Char;
  ItemID  : PItemIDList;
  AMalloc : IMalloc;
begin
  //項目識別子解放のためのメモリアロケーションのポインタ取得
  ShGetMalloc(AMalloc);

  try
    //CSIDL値を項目識別子に変換
    SHGetSpecialFolderLocation(Application.Handle, nFolder, ItemID);

    //項目識別子をフルパスの文字列に変換
    SHGetPathFromIDList(ItemID, Path);
    Result := Path;
  finally
    //項目識別子メモリアロケーション解放
    //項目識別子はす解放を忘れてもメモリリークを検出できないので注意
    AMalloc.Free(ItemID);
  end;
end;

//=============================================================================
//  Form生成時
//  ListBox1の各ItemにAddObjectでListBox1に表示する文字列と各CSIDL値をセット
//  Vistaにしか対応していないCSIDL_値があるので定数名ではなく実値を格納
//=============================================================================
procedure TForm1.FormCreate(Sender: TObject);
begin
  with ListBox1.Items do
  begin
    AddObject('CSIDL_DESKTOP',                 TObject($0000));
    AddObject('CSIDL_INTERNET',                TObject($0001));
    AddObject('CSIDL_PROGRAMS',                TObject($0002));
    AddObject('CSIDL_CONTROLS',                TObject($0003));
    AddObject('CSIDL_PRINTERS',                TObject($0004));
    AddObject('CSIDL_PERSONAL',                TObject($0005));
    AddObject('CSIDL_FAVORITES',               TObject($0006));
    AddObject('CSIDL_STARTUP',                 TObject($0007));
    AddObject('CSIDL_RECENT',                  TObject($0008));
    AddObject('CSIDL_SENDTO',                  TObject($0009));
    AddObject('CSIDL_BITBUCKET',               TObject($000A));
    AddObject('CSIDL_STARTMENU',               TObject($000B));
    AddObject('CSIDL_MYDOCUMENTS',             TObject($000C));
    AddObject('CSIDL_MYMUSIC',                 TObject($000D));
    AddObject('CSIDL_MYVIDEO',                 TObject($000E));
    AddObject('CSIDL_DESKTOPDIRECTORY',        TObject($0010));
    AddObject('CSIDL_DRIVES',                  TObject($0011));
    AddObject('CSIDL_NETWORK',                 TObject($0012));
    AddObject('CSIDL_NETHOOD',                 TObject($0013));
    AddObject('CSIDL_FONTS',                   TObject($0014));
    AddObject('CSIDL_TEMPLATES',               TObject($0015));
    AddObject('CSIDL_COMMON_STARTMENU',        TObject($0016));
    AddObject('CSIDL_COMMON_PROGRAMS',         TObject($0017));
    AddObject('CSIDL_COMMON_STARTUP',          TObject($0018));
    AddObject('CSIDL_COMMON_DESKTOPDIRECTORY', TObject($0019));
    AddObject('CSIDL_APPDATA',                 TObject($001A));
    AddObject('CSIDL_PRINTHOOD',               TObject($001B));
    AddObject('CSIDL_LOCAL_APPDATA',           TObject($001C));
    AddObject('CSIDL_ALTSTARTUP',              TObject($001D));
    AddObject('CSIDL_COMMON_ALTSTARTUP',       TObject($001E));
    AddObject('CSIDL_COMMON_FAVORITES',        TObject($001F));
    AddObject('CSIDL_INTERNET_CACHE',          TObject($0020));
    AddObject('CSIDL_COOKIES',                 TObject($0021));
    AddObject('CSIDL_HISTORY',                 TObject($0022));
    AddObject('CSIDL_COMMON_APPDATA',          TObject($0023));
    AddObject('CSIDL_WINDOWS',                 TObject($0024));
    AddObject('CSIDL_SYSTEM',                  TObject($0025));
    AddObject('CSIDL_PROGRAM_FILES',           TObject($0026));
    AddObject('CSIDL_MYPICTURES',              TObject($0027));
    AddObject('CSIDL_PROFILE',                 TObject($0028));
    AddObject('CSIDL_SYSTEMX86',               TObject($0029));
    AddObject('CSIDL_PROGRAM_FILESX86',        TObject($002A));
    AddObject('CSIDL_PROGRAM_FILES_COMMON',    TObject($002B));
    AddObject('CSIDL_PROGRAM_FILES_COMMONX86', TObject($002C));
    AddObject('CSIDL_COMMON_TEMPLATES',        TObject($002D));
    AddObject('CSIDL_COMMON_DOCUMENTS',        TObject($002E));
    AddObject('CSIDL_COMMON_ADMINTOOLS',       TObject($002F));
    AddObject('CSIDL_ADMINTOOLS',              TObject($0030));
    AddObject('CSIDL_CONNECTIONS',             TObject($0031));
    AddObject('CSIDL_COMMON_MUSIC',            TObject($0035));
    AddObject('CSIDL_COMMON_PICTURES',         TObject($0036));
    AddObject('CSIDL_COMMON_VIDEO',            TObject($0037));
    AddObject('CSIDL_RESOURCES',               TObject($0038));
    AddObject('CSIDL_RESOURCES_LOCALIZED',     TObject($0039));
    AddObject('CSIDL_COMMON_OEM_LINKS',        TObject($003A));
    AddObject('CSIDL_CDBURN_AREA',             TObject($003B));
    AddObject('CSIDL_COMPUTERSNEARME',         TObject($003D));
    AddObject('CSIDL_PROFILES',                TObject($003E));
  end;

  Self.Width     := 350;
  Edit1.Width    := Self.Width - 14;
  ListBox1.Width := Self.Width - 14;
end;

end.


次のリストもネット上でよく見かけます.SHGetSpecialFolderPath関数を使用します.この関数も取得できない特殊フォルダがあります.簡単なコードで済みますので,特定の特殊フォルダだけを対象にした動作だけであれば,十分利用する価値はあります.


リスト4 
特殊フォルダのフルパスをSHGetSpecialFolderPath関数で取得
//=============================================================================
//  特殊フォルダのパスを取得する簡単な方法
//  引数のStrCSIDLにCSIDL_DESKTOP等を指定する
//
//  usesにShlObjが必要
//=============================================================================
function TForm1.GetSpecialFolderPath(IntCSIDL: Integer): String;
var
  Buff : array[0..MAX_PATH] of Char;
begin
  FillChar(Buff, SizeOf(Buff), #0);
  SHGetSpecialFolderPath(0, Buff, IntCSIDL, False);
  Result := String(Buff);
end;




[ 頁先頭 ] [前のページ][次のページ]