TBrowseForFolder выбрал строку не в фокусе - PullRequest
1 голос
/ 12 мая 2011

Когда я использую "TBrowseForFolder" в Delphi XE с параметрами

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 ]

3 голосов
/ 12 мая 2011

Кажется, что работает с примером из 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;

Это дает фокус на выбранную папку - даже если она не была в видимой области ранее, в дереве. Кажется, мои проблемы решены! Если кто-то видит проблему с этим - пожалуйста, ответьте!

Вот что должен был сказать ОП этого обходного пути:
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 мс позже.

0 голосов
/ 21 сентября 2014

Я понимаю, что это старая ветка, но хорошие решения нельзя найти ...

Это сработало для меня, в 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 почти работает ... добавление Sleep в BFFM_SELCHANGED обеспечивает очень надежную работу.

...