【问题标题】:Pass List<IntPtr>* to EnumWindows' lParam in C#在 C# 中将 List<IntPtr>* 传递给 EnumWindows 的 lParam
【发布时间】:2012-12-20 13:40:18
【问题描述】:

我正在尝试编写一个函数,该函数在顶级窗口上进行迭代,如果它们满足一组条件,则将它们放入列表中。目前,我可以通过将窗口添加到静态 List&lt;IntPtr&gt; instances 变量中来使其工作,但我想将指针传递给 EnumWindowsProclParam 中的列表以避免此静态变量.

我想我必须使用fixed 来修复列表在内存中的位置,但我不确定如何执行此操作。我尝试将列表传递给我的回调函数:

unsafe
{
    fixed (void* dp = &instances)
    {
        WinApi.EnumWindows(new WinApi.EnumWindowsProc(FindPPWindows), dp);
    }
}

但我明白了

Cannot take the address of, get the size of, or declare a pointer to a managed type ('System.Collections.GenericList<IntPtr>')

我对 c# 很陌生,所以我真的不知道如何做到这一点 - 或者即使有可能,我也读过编组包含引用的托管类型是不可能的,但我只需要在内存中修复它并创建一个指向它的指针,然后将指针转换回去并使用它。如果有的话,我怎样才能完成这项工作?

【问题讨论】:

  • 您不能创建指向类的指针。您唯一能做的就是创建一个数组,并传递第一项的指针,void* dp = &amp;instancesArray 将指向第一项。但是你仍然必须保持数组大小,并发送一个足够大的数组来包含所有窗口。

标签: c# winapi interop marshalling fixed


【解决方案1】:

您可以使用 lambda 表达式调用 EnumWindows 函数。然后 EnumWindowsProc 回调将是内联的,您可以访问局部变量:

List<IntPtr> list = new List<IntPtr>();            

WinApi.EnumWindows((hWnd, lParam) =>
{
      //check conditions
      list.Add(hWnd);

      return true;

}, IntPtr.Zero);

您可以将此内联调用封装在一个额外的函数中,例如:

List<IntPtr> GetMatchingHWnds()
{
    List<IntPtr> list = new List<IntPtr>();            

    WinApi.EnumWindows((hWnd, lParam) =>
    {
          //check conditions
          list.Add(hWnd);

          return true;

    }, IntPtr.Zero);

    return list;        
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 2018-05-12
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    相关资源
    最近更新 更多