Ell
Ell

Reputation: 4376

Pass List<IntPtr>* to EnumWindows' lParam in C#

I'm trying to write a function which iterates over top level windows and puts them into a list if they fulfil a set of criteria. At the moment I can get this to work by adding the windows into a static List<IntPtr> instances variable, but I would like to instead pass a pointer to a list in the EnumWindowsProc's lParam in order to avoid this static variable.

I think I have to use fixed to fix the list's position in memory, but I am unsure how to do this. I tried this to pass the list to my callback function:

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

but I get

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

I'm newish to c# so I don't really know how to do this - or even if it's possible, I've read that marshalling a managed type containing references is impossible but I only need to fix it in memory and create a pointer to it, then cast the pointer back and use it. How can I make this work, if at all?

Upvotes: 1

Views: 1327

Answers (1)

tklepzig
tklepzig

Reputation: 638

You could call the EnumWindows function with an lambda expression. Then the EnumWindowsProc Callback would be inline and you can access to local variables:

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

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

      return true;

}, IntPtr.Zero);

You could capsulate this inline call in an extra function, e.g.:

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

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

          return true;

    }, IntPtr.Zero);

    return list;        
}

Upvotes: 2

Related Questions