📄 browsedr.~pas
字号:
function TBrowseDirectoryDlg.Execute: boolean;
var
S: string;
AParent: TWinControl;
TempPIDL: PItemIDList;
begin
FDisplayName := '';
{ Assume the worst }
AParent := NIL;
if not (csDesigning in ComponentState) then
{ Determine who the parent is. }
if assigned(FParent) then
AParent := FParent
else begin
if assigned(Owner) then
if Owner is TWinControl then
AParent := TWinControl(Owner)
else
if assigned(Application) and assigned(Application.MainForm) then
AParent := Application.MainForm;
end;
{ Call the function }
Result := BrowseDirectory(FShellMalloc, S, TempPIDL, FImageIndex,
FDisplayName, AParent, FTitle, FRoot, FOptions,
(FStatusText <> '') or FShowSelectionInStatus, BrowseCallbackProc,
LongInt(Self));
FDlgWnd := 0; { Not valid any more. }
{ If selection made, update property }
if Result then
begin
FSelection := S;
SelectionPIDL := TempPIDL;
end else begin
FSelection := '';
SelectionPIDL := NIL;
end;
end;
function FormatSelection(const APath: string): string;
begin
Result := APath;
if Result <> '' then begin
if (Length(Result) < 4) and (Result[2] = ':') then begin
if Length(Result) = 2 then
Result := Result + '\'
end else
if (Result[Length(Result)] = '\') and (Result <> '\') then
SetLength(Result, Length(Result)-1);
end;
end;
procedure TBrowseDirectoryDlg.SendSelectionMessage;
var
TempSelectionPIDL: PItemIDList;
ShellFolder: IShellFolder;
OLEStr: array[0..MAX_PATH] of TOLEChar;
Eaten: ULONG;
Attr: ULONG;
shBuff: PChar;
begin
if (FSelection = '') and assigned(FSelectionPIDL) then
begin
shBuff := PChar(FShellMalloc.Alloc(MAX_PATH)); // Shell allocate buffer.
try
if SHGetPathFromIDList(FSelectionPIDL, shBuff) then
FSelection := shBuff
else
FSelection := '';
finally
FShellMalloc.Free(shBuff); // Clean-up.
end;
SendMessage(FDlgWnd, BFFM_SETSELECTION, 0, LPARAM(FSelectionPIDL));
end else begin
if Copy(FSelection, 1, 2) = '\\' then // UNC name!
begin
if SHGetDesktopFolder(ShellFolder) = NO_ERROR then
begin
try
if ShellFolder.ParseDisplayName(FDlgWnd, NIL,
StringToWideChar(FSelection, OLEStr, MAX_PATH), Eaten,
TempSelectionPIDL, Attr) = NO_ERROR then
begin
SelectionPIDL := TempSelectionPIDL;
SendMessage(FDlgWnd, BFFM_SETSELECTION, 0, LPARAM(FSelectionPIDL));
end;
finally
{$IFNDEF DFS_NO_COM_CLEANUP} ShellFolder.Release; {$ENDIF}
end;
end;
end else begin { normal path }
if SHGetDesktopFolder(ShellFolder) = NO_ERROR then
begin
try
if ShellFolder.ParseDisplayName(FDlgWnd, NIL,
StringToWideChar(FSelection, OLEStr, MAX_PATH), Eaten,
TempSelectionPIDL, Attr) = NO_ERROR then
SelectionPIDL := TempSelectionPIDL;
finally
{$IFNDEF DFS_NO_COM_CLEANUP} ShellFolder.Release; {$ENDIF}
end;
SendMessage(FDlgWnd, BFFM_SETSELECTION, 1,
LPARAM(FormatSelection(FSelection)));
end;
end;
end;
end;
procedure TBrowseDirectoryDlg.DoInitialized(Wnd: HWND);
var
Rect: TRect;
begin
FDlgWnd := Wnd;
if FCenter then begin
GetWindowRect(Wnd, Rect);
SetWindowPos(Wnd, 0,
(GetSystemMetrics(SM_CXSCREEN) - Rect.Right + Rect.Left) div 2,
(GetSystemMetrics(SM_CYSCREEN) - Rect.Bottom + Rect.Top) div 2,
0, 0, SWP_NOACTIVATE or SWP_NOSIZE or SWP_NOZORDER);
end;
// Documentation for BFFM_ENABLEOK is incorrect. Value sent in LPARAM, not WPARAM.
SendMessage(FDlgWnd, BFFM_ENABLEOK, 0, LPARAM(FEnableOKButton));
if FStatusText <> '' then
SendMessage(Wnd, BFFM_SETSTATUSTEXT, 0, LPARAM(FittedStatusText));
if (FSelection <> '') or (FSelectionPIDL <> NIL) then
SendSelectionMessage;
if FCaption <> '' then
SendMessage(FDlgWnd, WM_SETTEXT, 0, LPARAM(FCaption));
if assigned(FOnCreate) then
FOnCreate(Self);
end;
procedure TBrowseDirectoryDlg.DoSelChanged(Wnd: HWND; Item: PItemIDList);
var
Name: string;
begin
if FShowSelectionInStatus or assigned(FSelChanged) then
begin
Name := '';
SetLength(Name, MAX_PATH);
SHGetPathFromIDList(Item, PChar(Name));
SetLength(Name, StrLen(PChar(Name)));
if FShowSelectionInStatus then
StatusText := Name;
if assigned(FSelChanged) then
FSelChanged(Self, Name, Item);
end;
end;
procedure TBrowseDirectoryDlg.DoValidateFailed(Path: string;
var Cancel: boolean);
begin
if assigned(FOnValidateFailed) then
FOnValidateFailed(Self, Path, Cancel);
end;
procedure TBrowseDirectoryDlg.SetFitStatusText(Val: boolean);
begin
if FFitStatusText = Val then exit;
FFitStatusText := Val;
// Reset the status text area if needed.
if FDlgWnd <> 0 then
SendMessage(FDlgWnd, BFFM_SETSTATUSTEXT, 0, LPARAM(FittedStatusText));
end;
procedure TBrowseDirectoryDlg.SetStatusText(const Val: string);
begin
if FStatusText = Val then exit;
FStatusText := Val;
if FDlgWnd <> 0 then
SendMessage(FDlgWnd, BFFM_SETSTATUSTEXT, 0, LPARAM(FittedStatusText));
end;
procedure TBrowseDirectoryDlg.SetSelection(const Val: string);
begin
if FSelection = Val then exit;
FSelection := Val;
// Add trailing backslash so it looks better in the IDE.
if (FSelection <> '') and (FSelection[Length(FSelection)] <> '\') and
DirExists(FSelection) then
FSelection := FSelection + '\';
if FDlgWnd <> 0 then
SendSelectionMessage;
end;
procedure TBrowseDirectoryDlg.SetSelectionPIDL(Value: PItemIDList);
begin
if (FSelectionPIDL <> Value) then
begin
if assigned(FSelectionPIDL) then
FShellMalloc.Free(FSelectionPIDL);
FSelectionPIDL := Value;
end;
end;
procedure TBrowseDirectoryDlg.SetEnableOKButton(Val: boolean);
begin
if FEnableOKButton = Val then exit;
FEnableOKButton := Val;
if FDlgWnd <> 0 then
// Documentation for BFFM_ENABLEOK is incorrect. Value sent in LPARAM, not WPARAM.
SendMessage(FDlgWnd, BFFM_ENABLEOK, 0, LPARAM(FEnableOKButton));
end;
function TBrowseDirectoryDlg.GetCaption: string;
var
Temp: array[0..255] of char;
begin
if FDlgWnd <> 0 then
begin
SendMessage(FDlgWnd, WM_GETTEXT, SizeOf(Temp), LPARAM(@Temp));
Result := string(Temp);
end else
Result := FCaption;
end;
procedure TBrowseDirectoryDlg.SetCaption(const Val: string);
begin
FCaption := Val;
if FDlgWnd <> 0 then
SendMessage(FDlgWnd, WM_SETTEXT, 0, LPARAM(FCaption));
end;
procedure TBrowseDirectoryDlg.SetParent(AParent: TWinControl);
begin
FParent := AParent;
end;
// Note that BOOL <> boolean type. Important!
function EnumChildWndProc(Child: HWND; Data: LParam): BOOL; stdcall;
const
STATUS_TEXT_WINDOW_ID = 14147;
type
PHWND = ^HWND;
begin
if GetWindowLong(Child, GWL_ID) = STATUS_TEXT_WINDOW_ID then begin
PHWND(Data)^ := Child;
Result := FALSE;
end else
Result := TRUE;
end;
function TBrowseDirectoryDlg.FittedStatusText: string;
var
ChildWnd: HWND;
begin
Result := FStatusText;
if FFitStatusText then begin
ChildWnd := 0;
if FDlgWnd <> 0 then
// Enumerate all child windows of the dialog to find the status text window.
EnumChildWindows(FDlgWnd, @EnumChildWndProc, LPARAM(@ChildWnd));
if (ChildWnd <> 0) and (FStatusText <> '') then
if DirExists(FStatusText) then
Result := MinimizeName(ChildWnd, FStatusText)
else
Result := MinimizeString(ChildWnd, FStatusText);
end;
end;
function TBrowseDirectoryDlg.GetDisplayName: string;
var
ShellFolder: IShellFolder;
Str : TStrRet;
begin
Result := '';
if FSelectionPIDL <> NIL then
begin
if SHGetDesktopFolder(ShellFolder) = NO_ERROR then
begin
try
if ShellFolder.GetDisplayNameOf(FSelectionPIDL, SHGDN_FORPARSING,
Str) = NOERROR then
begin
case Str.uType of
STRRET_WSTR: Result := WideCharToString(Str.pOleStr);
{$IFDEF DFS_DELPHI_4_UP}
STRRET_OFFSET: Result := PChar(LongWord(FSelectionPIDL) + Str.uOffset);
{$ELSE}
STRRET_OFFSET: Result := PChar(Longint(FSelectionPIDL) + Str.uOffset);
{$ENDIF}
STRRET_CSTR: Result := Str.cStr;
end;
end;
finally
{$IFNDEF DFS_NO_COM_CLEANUP} ShellFolder.Release; {$ENDIF}
end;
end;
end;
if Result = '' then
Result := FDisplayName;
if Result = '' then
Result := FSelection;
end;
function TBrowseDirectoryDlg.GetVersion: TDFSVersion;
begin
Result := DFS_COMPONENT_VERSION;
end;
procedure TBrowseDirectoryDlg.SetVersion(const Val: TDFSVersion);
begin
{ empty write method, just needed to get it to show up in Object Inspector }
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -