2011-05-12 82 views
1

的。當我使用「TBrowseForFolder」德爾福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; 

大多數對話框不會聚焦所選路徑,而只顯示頂部的列表。有時候(隨機?),儘管所選行是可見的。爲什麼不瀏覽文件夾顯示選定的路徑?

+0

哪個操作系統? - 我很確定XP不支持顯示選定的路徑。 – daven11 2011-05-12 10:54:31

+0

我在Microsoft Connect上找到了以下內容: 「在下面的代碼中使用BFFM_SETSELECTION和BIF_NEWDIALOGSTYLE時,在XP和Vista中選擇該文件夾並滾動列表以使用戶可以看到選定的文件夾,但在Windows 7中,列表不滾動以顯示選定的文件夾「 https://connect.microsoft.com/VisualStudio/feedback/details/518103/bffm-setselection-does-not-work-with-shbrowseforfolder-on-windows-7 它可以相互關聯或使我更接近解決方案嗎? – Tool 2011-05-12 11:03:10

+0

------------ --- – Tool 2011-05-12 11:18:33

回答

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毫秒。

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可以非常可靠地工作。