OpenDialogのようにファイル単位指定のものではなくて、フォルダツリーのみ表示されているフォルダ選択ダイアログみたいなのってありますかね?
TDirectoryOutlineって言うのがSamplesタブにあればそれで出来ると思います。
でもない場合やそれ以外の方法というと自分で作るしかないと思います。
Halbow です。
SelectDirectory() 関数で、Windows 標準のフォルダ選択ダイアログが
使えます。ヘルプで調べてください。二つあるほうの二番目です。(D5では)
こんなでしょうか?
違ったらすみません。
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;
あ、すみません、間違えました。
×TForm1 = class(TObject)
○TForm1 = class(TForm)
って、ここはどうでもいいですね。^^;
mMallocはReleaseしなくてよいのでしょうか。
確認しようとしたら、私のソースでも解放していなかったのですが^^;
SHGetMallocとIMallocを検索してみると、解放する必要がありそうな気がします。
解放する必要があると書いてありました。
SHGetMalloc(mMalloc)で割り当てられたメモリは
finally
mMalloc.Free(pIdList);
end;
mMalloc._Release;
end;
Result := bRet;
end;
でReleaseだと思うのですが、その確認方法が・・・。
確認方法なのですが、CPUウィンドウで確認できると
思うんですけど、プログラムカウンタとスタックポインタを見ていれば確認できますよね?確認したい関数に入る前と出た後でその値が一致しているかどうか・・という具合ですよね?
いつも「メモリリークとかってどうやって確認するんだろう?」と悩んでいます。
スタック上にメモリを確保するわけではないので、プログラムカウンタとスタックポインタではわからないと思います。
_AddRef, _Releaseの戻り値を見ても、いつも1なので、関係ないのかも。
# _AddRefでインクリメントされると思ったのですが
SHGetMallocで取得したポインタが、連続で取得しても変わらないようです。
SHGetMallocは、もしかしたら決まったインターフェースへのポインタを返すのかもしれませんね。そうであれば、解放しなくてよさそうです。
Delphiのメモリマネージャでのメモリリークなら、MemCheckというユニットがよいかと思います。
ツイート | ![]() |