Reputation: 4376
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
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