Delphi中的SelectDirectory对话框如何动态验证突出显示的文件夹?

时间:2010-03-15 18:54:31

标签: delphi dialog directory

是否有办法根据验证规则在SelectDirectory对话框中启用/禁用“确定”按钮,例如:

  • 如果突出显示的文件夹的名称为“config”
  • ,则启用“确定”按钮
  • 如果突出显示的文件夹包含名为“.project”的文件和名称为“.settings”的文件夹
  • ,则启用“确定”按钮

2 个答案:

答案 0 :(得分:7)

如果您使用ShBrowseForFolder API函数,则可以执行此操作。我认为Delphi附带了一个包含该函数的SelectDirectory版本,尽管包装器可能无法为您需要的内容提供足够的访问权限。您需要为callback function参数添加lpfn此签名:

function BrowseCallbackProc(Wnd: HWnd; uMsg: UInt; lParam, lpData: LParam): Integer; stdcall;

当选择更改时,对话框将调用您提供的bffm_SelChanged功能作为uMsg参数。第三个参数是表示当前选择的PIDL,因此您可能需要调用ShGetPathFromIDList来确定字符串名称。您可以通过将消息发送回Wnd参数中对话框的窗口句柄来控制“确定”按钮。例如:

SendMessage(Wnd, bffm_EnableOK, 0, 0); // disable the button
SendMessage(Wnd, bffm_EnableOK, 0, 1); // enable the button

在您选择无效选项后,请不要忘记重新启用正确选项的按钮。

如果有效选择的标准是目录应包含具有特定名称的文件,请务必包含bif_BrowseIncludeFiles标记,以便人们可以看到那些文件。

答案 1 :(得分:5)

只是为了补充@Rob的优秀答案。

请参阅此代码。

uses  ShlObj;

function BrowseCallbackProc(hwnd: HWND; MessageID: UINT; lParam: LPARAM; lpData: LPARAM): Integer; stdcall;
var
    DirName:  array[0..MAX_PATH] of Char;
    pIDL   :  pItemIDList;
begin
  case  MessageID    of
    BFFM_INITIALIZED:SendMessage(hwnd, BFFM_SETSELECTION, 1, lpData);
    BFFM_SELCHANGED :begin
                        pIDL := Pointer(lParam);
                        if  Assigned(PIDL) then
                        begin
                          SHGetPathFromIDList(pIDL, DirName);
                          if DirectoryExists(DirName) then
                           if (ExtractFileName(DirName)='config') then    //you can add more validations here
                            SendMessage(hwnd, BFFM_ENABLEOK, 0, 1) //enable the ok button
                           else
                            SendMessage(hwnd, BFFM_ENABLEOK, 0, 0) //disable the ok button
                          else
                          SendMessage(hwnd, BFFM_ENABLEOK, 0, 0);
                        end
                        else
                          SendMessage(hwnd, BFFM_ENABLEOK, 0, 0);
                     end;
  end;

  Result := 0;
end;

function SelectFolderDialogExt(Handle: Integer; var SelectedFolder: string): Boolean;
var
  ItemIDList: PItemIDList;
  JtemIDList: PItemIDList;
  DialogInfo: TBrowseInfo;
  Path: PAnsiChar;
begin
  Result := False;
  Path   := StrAlloc(MAX_PATH);
  SHGetSpecialFolderLocation(Handle, CSIDL_DRIVES, JtemIDList);
  with DialogInfo do
  begin
    pidlRoot      := JtemIDList;
    //ulFlags       := BIF_RETURNONLYFSDIRS;     //only select directories
    hwndOwner     := GetActiveWindow;
    SHGetSpecialFolderLocation(hwndOwner, CSIDL_DRIVES, JtemIDList);
    pszDisplayName := StrAlloc(MAX_PATH);
    lpszTitle       := PChar('Select a folder');
    lpfn            := @BrowseCallbackProc;
    lParam            := LongInt(PChar(SelectedFolder));
  end;

  ItemIDList := SHBrowseForFolder(DialogInfo);

  if (ItemIDList <> nil) then
    if SHGetPathFromIDList(ItemIDList, Path) then
    begin
      SelectedFolder := Path;
      Result         := True;
    end;
end;

执行

if SelectFolderDialogExt(Handle, SelectedDir) then
  ShowMessage(SelectedDir);