2011-12-17 72 views
0

我不完全理解這些話題。代表和回調如何工作?

我的工作與幾個WinAPI的方法

public delegate bool Win32Callback(IntPtr hwnd, ref IntPtr lParam); 

[DllImport("user32.Dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
public static extern bool EnumChildWindows(IntPtr parentHandle, Win32Callback callback, IntPtr lParam); 

public static bool BrowserEnumChildrenCallback(IntPtr hWnd, ref IntPtr lParam) 
{ 
    if (hWndMeetsConditions) 
     return true; 
    //code 
    return false; 
} 

是否有可能得到hWndBrowserEnumChildrenCallback返回正確的有哪些?

Win32Callback callBack = new MainWindow.Win32Callback(BrowserEnumChildrenCallback); 
if (EnumChildWindows(hWnd, callBack, hWnd)) 
{ 
    //here 
} 
+0

問題是什麼? - 你可以說得更詳細點嗎。 – Niklas

+0

@Niklas最後的'代碼'。如何讓hWnd返回'真'。現在不一樣了。 – Saint

回答

3

幾個問題:

  • 的委託聲明是錯誤的,最後一個參數是IntPtr的,不是裁判的IntPtr
  • 該回調應該返回true以繼續迭代,你做它倒退
  • EnumChildWindows()調用後寫入GC.KeepAlive(callBack)以防止委託對象被垃圾收集。
  • 不要使用EnumChildWindows()的返回值,SDK文檔指出它沒有被使用。您通過找不到窗口來檢測失敗。

回答實際問題:將窗口句柄存儲在類的字段中。因此:

private IntPtr windowFound; 

private void iterateChildWindows(IntPtr parent) { 
    windowFound = IntPtr.Zero; 
    var callBack = new MainWindow.Win32Callback(BrowserEnumChildrenCallback); 
    EnumChildWindows(parent, callBack, IntPtr.Zero); 
    GC.KeepAlive(callBack); 
    if (windowFound != IntPtr.Zero) { 
     // etc.. 
    } 
} 

private bool BrowserEnumChildrenCallback(IntPtr hWnd, IntPtr lParam) 
{ 
    if (hWndMeetsConditions(hWnd)) { 
     windowFound = hWnd; 
     return false; 
    } 
    return true; 
} 

拉姆達運作良好。

1
List<IntPtr> _hwnds = new List<IntPtr>(); 
public static bool BrowserEnumChildrenCallback(IntPtr hWnd, ref IntPtr lParam) 
{  
    if (hWndMeetsConditions)   
    { 
      _hwnds.Add(hWnd); 
      return true;  
    } 

    //code  
    return false; 
} 

Win32Callback callBack = new MainWindow.Win32Callback(BrowserEnumChildrenCallback); 
if (EnumChildWindows(hWnd, callBack, hWnd)) 
{  
    // here 
    // you have it in _hwnd 
}