フォルダ選択ダイアログってありますか?


あっぷっぷ〜  2003-10-26 10:13:58  No: 5439

OpenDialogのようにファイル単位指定のものではなくて、フォルダツリーのみ表示されているフォルダ選択ダイアログみたいなのってありますかね?


LupinⅢ  URL  2003-10-26 10:17:33  No: 5440

TDirectoryOutlineって言うのがSamplesタブにあればそれで出来ると思います。
でもない場合やそれ以外の方法というと自分で作るしかないと思います。


Halbow  2003-10-26 13:16:34  No: 5441

Halbow です。

SelectDirectory() 関数で、Windows 標準のフォルダ選択ダイアログが
使えます。ヘルプで調べてください。二つあるほうの二番目です。(D5では)


まろ  2003-10-28 20:27:38  No: 5442

こんなでしょうか?
違ったらすみません。

type
  TForm1 = class(TObject)
  private
    function OpenFolderDialog(var sPath:string):boolean;
  public
end;
  function BrowseCallbackProc(hWnd: HWND; uMsg: UINT; lParam: LPARAM; lpData: LPARAM): integer; stdcall; export;

function BrowseCallbackProc(hWnd:HWND; uMsg:UINT; lParam,lpData: lParam):integer;
var
  sPathNameAry: array[0..MAX_PATH] of char;
begin
  if (uMsg = BFFM_INITIALIZED) then begin
    SendMessage(hwnd, BFFM_SETSELECTION, 1, LongInt(lpData));
  end
  else if (uMsg = BFFM_SELCHANGED) then begin
    SHGetPathFromIDList(PItemIDList(lParam), sPathNameAry);
    SendMessage(hWnd, BFFM_SETSTATUSTEXT, 0, LongInt(@sPathNameAry));
  end;
  Result:=0;
end;

function TForm1.OpenFolderDialog(var sPath:string):boolean;
var
  mMalloc   : IMalloc;
  tBrowsInfo: TBrowseInfo;
  sDispPath : array[0..MAX_PATH] of char;
  pIdList   : PItemIdList;
  pBuffer   : Pchar;
  sDirPath  : Pchar;
  bRet      : boolean;
begin
  bRet := False;
  if Succeeded(SHGetMalloc(mMalloc)) then begin
    //選択したフォルダ
    sDirPath := Pchar(sPath);
    //BrowseInfo構造体を初期化
    with tBrowsInfo do begin
      hwndOwner      := GetActiveWindow;
      pidlRoot       := nil;
      pszDisplayName := sDispPath;
      lpszTitle      := 'フォルダを選択してください。';
      ulFlags        := BIF_RETURNONLYFSDIRS or BIF_STATUSTEXT;
      lpfn           := @BrowseCallbackProc;
      lParam         := LongInt(sDirPath);
      iImage         := 0;
    end;

    pIdList := SHBrowseForFolder(tBrowsInfo);
    if (pIdList <> nil) then begin
      pBuffer := mMalloc.Alloc(MAX_PATH);
      try
        SHGetPathFromIDList(pIdList, pBuffer);
        if DirectoryExists(string(pBuffer)) then begin
          sPath := string(pBuffer);
          bRet := True;
        end;
      finally
        mMalloc.Free(pBuffer);
      end;
      mMalloc.Free(pIdList);
    end;
  end;
  Result := bRet;
end;


まろ  2003-10-28 20:30:04  No: 5443

あ、すみません、間違えました。
×TForm1 = class(TObject)
○TForm1 = class(TForm)
って、ここはどうでもいいですね。^^;


にしの  2003-10-28 20:46:32  No: 5444

mMallocはReleaseしなくてよいのでしょうか。
確認しようとしたら、私のソースでも解放していなかったのですが^^;
SHGetMallocとIMallocを検索してみると、解放する必要がありそうな気がします。


まろ  2003-10-28 21:49:06  No: 5445

解放する必要があると書いてありました。
SHGetMalloc(mMalloc)で割り当てられたメモリは

    finally
      mMalloc.Free(pIdList);
    end;
    mMalloc._Release;
  end;
  Result := bRet;
end;

でReleaseだと思うのですが、その確認方法が・・・。
確認方法なのですが、CPUウィンドウで確認できると
思うんですけど、プログラムカウンタとスタックポインタを見ていれば確認できますよね?確認したい関数に入る前と出た後でその値が一致しているかどうか・・という具合ですよね?
いつも「メモリリークとかってどうやって確認するんだろう?」と悩んでいます。


にしの  2003-10-29 00:56:00  No: 5446

スタック上にメモリを確保するわけではないので、プログラムカウンタとスタックポインタではわからないと思います。
_AddRef, _Releaseの戻り値を見ても、いつも1なので、関係ないのかも。
# _AddRefでインクリメントされると思ったのですが
SHGetMallocで取得したポインタが、連続で取得しても変わらないようです。
SHGetMallocは、もしかしたら決まったインターフェースへのポインタを返すのかもしれませんね。そうであれば、解放しなくてよさそうです。

Delphiのメモリマネージャでのメモリリークなら、MemCheckというユニットがよいかと思います。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加