** pasha |
Отправлено: 23.11.2005, 12:34 |
|
Не зарегистрирован
|
Как известно многие функции C++Builder построена на функциях API.
Подскажите API-аналог функции SelectDirectory().
На какой API-функции построена SelectDirectory ? |
|
** pasha |
Отправлено: 23.11.2005, 12:36 |
|
Не зарегистрирован
|
Может быть SHBrowseForFolder ??? |
|
Gedeon |
Отправлено: 23.11.2005, 14:14 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Она не на апи написана — это борландовкое диалоговое окно TSelectDirDlg
|
|
BreakPointMAN |
Отправлено: 23.11.2005, 23:39 |
|
Станционный диспетчер
Группа: Участник
Сообщений: 86
|
Gedeon, позвольте немного не согласиться с Вами.
Все зависит от того, каким образом вызывается функция SelectDirectory(). Если формат её вызова такой:
CODE |
WideString Root="";
AnsiString Caption="Caption";
AnsiString Dir;
SelectDirectory(Caption,Root,Dir);
ShowMessage("Selected directory is: "+Dir);
|
то компилятор генерирует код, по которому видно, что в данном случае Builder'овская SelectDirectory() инкапсулировала вызов WinAPI.
QUOTE |
.text:00402154 ; --------------- S U B R O U T I N E ---------------------------------------
.text:00402154
.text:00402154 ; Attributes: library function bp-based frame
.text:00402154
.text:00402154 __fastcall Filectrl::SelectDirectory(const System::AnsiString,const System::WideString,System::AnsiString &) proc near
.text:00402154 ; CODE XREF: sub_4019C0+69p
.text:00402154
.text:00402154 var_4C = dword ptr -4Ch
.text:00402154 var_48 = dword ptr -48h
.text:00402154 var_44 = dword ptr -44h
.text:00402154 var_40 = dword ptr -40h
.text:00402154 var_3C = dword ptr -3Ch
.text:00402154 var_38 = dword ptr -38h
.text:00402154 var_34 = dword ptr -34h
.text:00402154 var_2C = dword ptr -2Ch
.text:00402154 var_28 = dword ptr -28h
.text:00402154 var_24 = dword ptr -24h
.text:00402154 var_20 = dword ptr -20h
.text:00402154 var_1C = dword ptr -1Ch
.text:00402154 var_18 = dword ptr -18h
.text:00402154 uMode = dword ptr -14h
.text:00402154 var_10 = dword ptr -10h
.text:00402154 var_C = dword ptr -0Ch
.text:00402154 var_5 = byte ptr -5
.text:00402154 var_4 = dword ptr -4
.text:00402154
.text:00402154 push ebp
.text:00402155 mov ebp, esp
.text:00402157 add esp, 0FFFFFFB4h
.text:0040215A push ebx
.text:0040215B push esi
.text:0040215C xor ebx, ebx
.text:0040215E mov [ebp+var_20], ebx
.text:00402161 mov [ebp+var_24], ebx
.text:00402164 mov [ebp+var_4], ecx
.text:00402167 mov ebx, edx
.text:00402169 mov esi, eax
.text:0040216B xor eax, eax
.text:0040216D push ebp
.text:0040216E push offset loc_40232C
.text:00402173 push dword ptr fs:[eax]
.text:00402176 mov fs:[eax], esp
.text:00402179 mov [ebp+var_5], 0
.text:0040217D mov eax, [ebp+var_4]
.text:00402180 mov eax, [eax]
.text:00402182 call sub_40233C
.text:00402187 test al, al
.text:00402189 jnz short loc_402193
.text:0040218B mov eax, [ebp+var_4]
.text:0040218E call System::__linkproc__ LStrClr(System::AnsiString &)
.text:00402193
.text:00402193 loc_402193: ; CODE XREF: Filectrl::SelectDirectory(System::AnsiString,System::WideString,System::AnsiString &)+35j
.text:00402193 lea eax, [ebp+var_4C]
.text:00402196 xor ecx, ecx
.text:00402198 mov edx, 20h
.text:0040219D call System::__linkproc__ FillChar(void)
.text:004021A2 lea eax, [ebp+var_20]
.text:004021A5 push eax
.text:004021A6 call SHGetMalloc
.text:004021AB test eax, eax
.text:004021AD jnz loc_40230E
.text:004021B3 cmp [ebp+var_20], 0
.text:004021B7 jz loc_40230E
.text:004021BD push 104h
.text:004021C2 mov eax, [ebp+var_20]
.text:004021C5 push eax
.text:004021C6 mov eax, [eax]
.text:004021C8 call dword ptr [eax+0Ch]
.text:004021CB mov [ebp+var_10], eax
.text:004021CE xor eax, eax
.text:004021D0 push ebp
.text:004021D1 push offset loc_402307
.text:004021D6 push dword ptr fs:[eax]
.text:004021D9 mov fs:[eax], esp
.text:004021DC xor eax, eax
.text:004021DE mov [ebp+var_18], eax
.text:004021E1 mov eax, ebx
.text:004021E3 xor edx, edx
.text:004021E5 call System::__linkproc__ WStrCmp(void)
.text:004021EA jz short loc_40221F
.text:004021EC lea eax, [ebp+var_24]
.text:004021EF push eax
.text:004021F0 call SHGetDesktopFolder
.text:004021F5 lea eax, [ebp+var_2C]
.text:004021F8 push eax
.text:004021F9 lea eax, [ebp+var_18]
.text:004021FC push eax
.text:004021FD lea eax, [ebp+var_28]
.text:00402200 push eax
.text:00402201 mov eax, ebx
.text:00402203 call System::__linkproc__ WStrToPWChar(System::WideString)
.text:00402208 push eax
.text:00402209 push 0
.text:0040220B mov eax, off_46CA64
.text:00402210 mov eax, [eax]
.text:00402212 mov eax, [eax+30h]
.text:00402215 push eax
.text:00402216 mov eax, [ebp+var_24]
.text:00402219 push eax
.text:0040221A mov eax, [eax]
.text:0040221C call dword ptr [eax+0Ch]
.text:0040221F
.text:0040221F loc_40221F: ; CODE XREF: Filectrl::SelectDirectory(System::AnsiString,System::WideString,System::AnsiString &)+96j
.text:0040221F mov eax, off_46CA64
.text:00402224 mov eax, [eax]
.text:00402226 mov eax, [eax+30h]
.text:00402229 mov [ebp+var_4C], eax
.text:0040222C mov eax, [ebp+var_18]
.text:0040222F mov [ebp+var_48], eax
.text:00402232 mov eax, [ebp+var_10]
.text:00402235 mov [ebp+var_44], eax
.text:00402238 mov eax, esi
.text:0040223A call System::__linkproc__ LStrToPChar(void)
.text:0040223F mov [ebp+var_40], eax
.text:00402242 mov [ebp+var_3C], 1
.text:00402249 mov eax, [ebp+var_4]
.text:0040224C cmp dword ptr [eax], 0
.text:0040224F jz short loc_402265
.text:00402251 mov [ebp+var_38], offset FileCtrl::_16501
.text:00402258 mov eax, [ebp+var_4]
.text:0040225B mov eax, [eax]
.text:0040225D call System::__linkproc__ LStrToPChar(void)
.text:00402262 mov [ebp+var_34], eax
.text:00402265
.text:00402265 loc_402265: ; CODE XREF: Filectrl::SelectDirectory(System::AnsiString,System::WideString,System::AnsiString &)+FBj
.text:00402265 xor eax, eax
.text:00402267 call sub_43FEAC
.text:0040226C mov [ebp+var_C], eax
.text:0040226F push 1 ; uMode
.text:00402271 call SetErrorMode
.text:00402276 mov [ebp+uMode], eax
.text:00402279 xor eax, eax
.text:0040227B push ebp
.text:0040227C push offset loc_4022B2
.text:00402281 push dword ptr fs:[eax]
.text:00402284 mov fs:[eax], esp
.text:00402287 lea eax, [ebp+var_4C]
.text:0040228A push eax
.text:0040228B call SHBrowseForFolderA
.text:00402290 mov [ebp+var_1C], eax
.text:00402293 xor eax, eax
.text:00402295 pop edx
.text:00402296 pop ecx
.text:00402297 pop ecx
.text:00402298 mov fs:[eax], edx
.text:0040229B push offset loc_4022B9
.text:004022A0
.text:004022A0 loc_4022A0: ; CODE XREF: Filectrl::SelectDirectory(System::AnsiString,System::WideString,System::AnsiString &)+163j
.text:004022A0 mov eax, [ebp+uMode]
.text:004022A3 push eax ; uMode
.text:004022A4 call SetErrorMode
.text:004022A9 mov eax, [ebp+var_C]
.text:004022AC call sub_43FF60
.text:004022B1 retn
|
Отредактировано BreakPointMAN — 23/11/2005, 23:40
|
|
Gedeon |
Отправлено: 24.11.2005, 08:56 |
|
Ветеран
Группа: Модератор
Сообщений: 1742
|
Да, согласен, совсем забыл что она перегруженная и говорил именно про тот вариант, который
CODE |
SelectDirectory(AnsiString &Directory, TSelectDirOpts Options, int HelpCtx); |
точнее посмотрел в исходниках
CODE |
function SelectDirectory(var Directory: string;
Options: TSelectDirOpts; HelpCtx: Longint): Boolean;
var
D: TSelectDirDlg;
begin
D := TSelectDirDlg.Create(Application);
try
D.Directory := Directory;
D.AllowCreate := sdAllowCreate in Options;
D.Prompt := sdPrompt in Options;
{ scale to screen res }
if Screen.PixelsPerInch <> 96 then
begin
D.ScaleBy(Screen.PixelsPerInch, 96);
D.FileList.ParentFont := True;
D.Left := (Screen.Width div 2) — (D.Width div 2);
D.Top := (Screen.Height div 2) — (D.Height div 2);
D.FileList.Font.Color := clGrayText;
end;
if HelpCtx = 0 then
begin
D.HelpButton.Visible := False;
D.OKButton.Left := D.CancelButton.Left;
D.CancelButton.Left := D.HelpButton.Left;
end
else D.HelpContext := HelpCtx;
Result := D.ShowModal = mrOK;
if Result then
begin
Directory := D.Directory;
if sdPerformCreate in Options then
ForceDirectories(Directory);
end;
finally
D.Free;
end;
end;
|
а если вспомнить про второй
CODE |
SelectDirectory(const AnsiString Caption, const WideString Root, AnsiString &Directory);
|
то да совершенно верно SHBrowseForFolder
CODE |
function SelectDirectory(const Caption: string; const Root: WideString;
var Directory: string): Boolean;
var
WindowList: Pointer;
BrowseInfo: TBrowseInfo;
Buffer: PChar;
OldErrorMode: Cardinal;
RootItemIDList, ItemIDList: PItemIDList;
ShellMalloc: IMalloc;
IDesktopFolder: IShellFolder;
Eaten, Flags: LongWord;
begin
Result := False;
if not DirectoryExists(Directory) then
Directory := '';
FillChar(BrowseInfo, SizeOf(BrowseInfo), 0);
if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then
begin
Buffer := ShellMalloc.Alloc(MAX_PATH);
try
RootItemIDList := nil;
if Root <> '' then
begin
SHGetDesktopFolder(IDesktopFolder);
IDesktopFolder.ParseDisplayName(Application.Handle, nil,
POleStr(Root), Eaten, RootItemIDList, Flags);
end;
with BrowseInfo do
begin
hwndOwner := Application.Handle;
pidlRoot := RootItemIDList;
pszDisplayName := Buffer;
lpszTitle := PChar(Caption);
ulFlags := BIF_RETURNONLYFSDIRS;
if Directory <> '' then
begin
lpfn := SelectDirCB;
lParam := Integer(PChar(Directory));
end;
end;
WindowList := DisableTaskWindows(0);
OldErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
try
ItemIDList := ShBrowseForFolder(BrowseInfo);
finally
SetErrorMode(OldErrorMode);
EnableTaskWindows(WindowList);
end;
Result := ItemIDList <> nil;
if Result then
begin
ShGetPathFromIDList(ItemIDList, Buffer);
ShellMalloc.Free(ItemIDList);
Directory := Buffer;
end;
finally
ShellMalloc.Free(Buffer);
end;
end;
end;
|
|
|
|