TBrowseForFolder选择了焦点行

时间:2011-05-12 09:09:17

标签: delphi windows-7 delphi-xe

当我在Delphi XE中使用带有选项

的“TBrowseForFolder”时
object actBrowseCommonData: TBrowseForFolder
  Category = 'Base'
  Caption = 'Browse...'
  DialogCaption = 'Browse for Common data path'
  BrowseOptions = [bifUseNewUI]
  BeforeExecute = actBrowseCommonDataBeforeExecute
  OnAccept = actBrowseCommonDataAccept
end

在代码中,事件BeforeExecute具有以下代码:

begin
  actBrowseProjectPath.Folder := eProjectPath.Text;   // "C:\test\"
end;

大多数情况下,对话框不会聚焦所选路径,而只会显示顶部的列表。有时(随机?)虽然所选行是可见的。为什么不浏览文件夹显示所选路径?

2 个答案:

答案 0 :(得分:3)

它似乎适用于Microsoft Connect的示例:

uses ShlObj; //BFFM_INITIALIZED...

OnCallBack := actBrowseProjectPathCallback;

procedure TSettingsDialogBase.actBrowseProjectPathCallback(
  Sender: TBrowseForFolder; Wnd: HWND; uMsg: Cardinal; lParam, lpData: Integer;
  var Result: Integer);
begin
  inherited;

  if uMsg = BFFM_INITIALIZED then
  begin
    SendMessage(Wnd, BFFM_SETSELECTION, 1, Integer(@Sender.Folder[1]));
    Sleep(1000);
    PostMessage(Wnd, BFFM_SETSELECTION, 1, Integer(@Sender.Folder[1]));
  end;
end;

这会将焦点放在所选文件夹上 - 即使它不在树之前的可见区域中。我的问题似乎已经解决了!如果有人发现此问题 - 请回复!

以下是该解决方案的OP必须说明的内容:
http://connect.microsoft.com/VisualStudio/feedback/details/518103/bffm-setselection-does-not-work-with-shbrowseforfolder-on-windows-7#

  

我找到了解决方法。问题似乎是当发生BFFM_INITIALIZED回调并发送BFFM_SETSELECTION消息时,必须在发送BFFM_SETSELECTION消息之前打开并初始化树。换句话说,看起来好像是在树完全打开并且失败之前正在执行滚动代码。

     

如果在回调中发送BFFM_SETSELECTION消息,则会打开树,但选择不会滚动到。要使其滚动,您必须在延迟时发送一条相同的BFFM_SETSELECTION消息。然后树滚动到所选文件夹。仍然必须发生BFFM_INITIALIZED回调中的第一条消息才能打开树,然后必须发送第二条延迟消息并且它将起作用。有两种方法可以做到这一点。一种是在BFFM_INITIALIZED发生时设置一个标志,然后继续为每次回调发送BFFM_SETSELECTION。或者,您可以在代码中设置一个计时器,以便再次触发消息,比如500到1000毫秒。

答案 1 :(得分:0)

我意识到这是一个古老的线索,但很好的解决方案是找不到的......

这对我有用,在C ......

INT CALLBACK BFFHookProc(HWND Dlg, UINT Msg, LPARAM Lparam, LPARAM Data)
  {
    switch(Msg)
      {
        case BFFM_INITIALIZED :   
          PostMessage(Dlg, BFFM_SETSELECTION, 1, Data);  
          return 0;
       case BFFM_SELCHANGED :
         Sleep(20);
       default :
         return 0;
      }
  }

这是一个时间问题,但它的确切性质是一个神秘的东西。使用PostMessage代替SendMessage几乎可以正常工作......在BFFM_SELCHANGED中添加Sleep使其工作非常可靠。