2012-06-05 46 views
0

我在我的應用程序中有非常異常的工作。我使用下面的代碼來枚舉所有命名空間和一些根命名空間 - 比如Nethood的工作很慢 - 超過一分鐘加載(!!)這隻發生在Win7上,在較舊的系統加載是好的。IShellFolder與異步EnumObject(SHCONTF_ENABLE_ASYNC)

我使用這個功能,從MustangPeak庫:

function TNamespace.EnumerateFolder(MessageWnd: HWnd; Folders, NonFolders, 
    IncludeHidden: Boolean; EnumFunc: TEnumFolderCallback; 
    UserData: Pointer): integer; 
var 
    Enum: IEnumIDList; 
    Flags: Longword; 
    Fetched: Longword; 
    Item: PItemIDList; 
    Terminate: Boolean; 
    OldError: integer; 
    OldWow64: Pointer; 
begin 
    Result := 0; 

    OldError := SetErrorMode(SEM_FAILCRITICALERRORS or SEM_NOOPENFILEERRORBOX); 
    try 
    if Assigned(ShellFolder) then 
    begin 
     if Assigned(EnumFunc) then 
     begin 
     Terminate := False; 
     Flags := 0; 
     if Folders then 
      Flags := Flags or SHCONTF_FOLDERS; 
     if NonFolders then 
      Flags := Flags or SHCONTF_NONFOLDERS; 
     if IncludeHidden then 
      Flags := Flags or SHCONTF_INCLUDEHIDDEN; 

    // --- This is new added 
    Flags := Flags or SHCONTF_ENABLE_ASYNC; 

     if Valid then 
     begin 
      OldWow64 := Wow64RedirectDisable; 
      try 

      if ShellFolder.EnumObjects(MessageWnd, Flags, Enum) = NOERROR then 
      begin 
       // Vista Enum is nil every once in a while 
       if Assigned(Enum) then 
       begin 
       while (Enum.Next(1, Item, Fetched) = NOERROR) and not Terminate do 
       begin 
        if EnumFunc(MessageWnd, Item, Self, UserData, Terminate) then 
        Inc(Result) 
       end 
       end 
      end 
      finally 
      Wow64RedirectRevert(OldWow64) 
      end 
     end 
     end 
    end 
    finally 
    SetErrorMode(OldError); 
    end 
end; 

現在我在MSDN文檔閱讀,在Win7的新異步標誌已經爲了得到結果即刻支持,但隨後收到其他結果時系統讀取它。

該標誌被稱爲SHCONTF_ENABLE_ASYNC我加入它代碼上的地方,我已經標有(// ---這是新加的)

問題是,因爲我不知道如何捕捉事件時我收到更新。

如何掛鉤新收到的物品?系統(對象)發送給某個控件或結構等的事件(消息等)是否存在?

謝謝!

回答

1

SHCONTF_ENABLE_ASYNC不使枚舉本身異步。它只是讓IShellFolder知道您正在監視IShellFolder以外的異步更改通知,例如SHChangeNotifyRegister(),因此枚舉不需要一次返回所有內容,因爲更改通知會讓您知道何時添加/刪除/更改了項目實時。

+0

你是說用SHChangeNotifyRegistry可以檢測到變化嗎?好吧,兩個問題: 1)SHChangeNotifyRegistry作爲第一個參數應該有應用程序句柄(或MainForm句柄),以便MainForm接收消息? 2)網絡鄰居掃描將發送異步哪種類型的消息> FolderUpdate,DirUpdate,File added等? 非常感謝您的回答。我需要更多一點來理解這一點,並完成那個討厭我的問題。 :) –

+1

我不會使用'MainForm.Handle',因爲它可以在應用程序的生命週期內動態更改。我會使用'Application.Handle',然後使用'Application.OnMessage'事件和/或'Application.HookMainWindow()'方法來接收消息,或者2)使用'AllocateHWnd()'創建一個專用窗口只是爲了接收該消息。我無法回答你的其他問題,你只需要看看你實際收到的是什麼樣的事件。 –

+0

雷米,我做了什麼我不能接收來自SHChangeNotifyRegister的任何消息。我不知道明顯地設置好旗幟。如果你有這方面的知識,並知道什麼和如何設置請幫助。 –