1

I am writing a custom function to enumerate child windows and return a list of window handles. Here is the declaration of the function as per P/Invoke.

[System.Runtime.InteropServices.DllImport("user32.Dll")]
public static extern bool EnumWindows (EnumWindowsCallback lpEnumCallbackFunc, int lParam);

[System.Runtime.InteropServices.DllImport("user32")]
public static extern bool EnumChildWindows (IntPtr hWnd, EnumWindowsCallback lpEnumCallbackFunc, int lParam);

The problem is that I need to be able to pass an Int32 value in one scenario and IntPtr in another scenario.

  • If I change the parameter to IntPtr, can I cast an int to it and reliably cast it back to Int32 later?
  • If I leave the parameter as Int32, will IntPtr.ToInt32 always work since my own app is 32 bit but the target process is 64 bit (Windows Sidebar)?
Raheel Khan
  • 14,205
  • 13
  • 80
  • 168

1 Answers1

1

You must use IntPtr for the lParam value, but it is always guaranteed to be large enough for an Int32.

Since the value that gets put into the lParam is under your control (not the other window's) you can guarantee that you will put a value into the IntPtr which you can read out again.

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
  • Thanks. That's the thing Matthew. I am getting the IntPtr hWnd from System.Diagnostics.Process.GetProcesses()[0].MainWindowHandle. Since the target process is 64 bit, I am not sure if the hWnd will be 32 or 64 bit. I am unfamiliar with Win-API so please bear with the ignorance. – Raheel Khan Jun 10 '13 at 15:21
  • @RaheelKhan I don't think you can enumerate any 64 bit processes from a 32 bit process, so I don't think that can arise. Have you tried it? I think it won't work... – Matthew Watson Jun 10 '13 at 15:26
  • It does work as long as you do not try to access the internals of that process such as modules etc. My app is 32 bit and can get the Sidebar app easily which is 64. – Raheel Khan Jun 10 '13 at 15:28
  • Overloading works fine. But when I overload the delegate for the callback, it gives me a duplicate duplication error even though the second parameter differs between Int32 and IntPtr. – Raheel Khan Jun 10 '13 at 15:29
  • @RaheelKhan That's odd - I was sure that I couldn't enumerate 64 bit processes from a 32 bit program a while back when I tried it... Strange. – Matthew Watson Jun 10 '13 at 15:33
  • Well, apparently the GetProcesses function DOES return the SideBar instance. I am running Win 7 64, VS 2010 and my app is targeting 32. SideBar only exists in the Program Files folder and when trying to access it's module details, I get the `[cannot access 64 fromo 32]` error. But I am still able to enumerate the process and get basic info like MainWindowHandle. Am I missing something here? – Raheel Khan Jun 10 '13 at 16:14
  • @RaheelKhan Yes, it behaves like that when I try it too - I must have been using the Windows API or something - it was a while ago. – Matthew Watson Jun 10 '13 at 16:39
  • Thanks. So what are your thoughts on my question? I mean, if I was NOT using overloading, could I tell somehow whether the IntPtr should be used with the ToInt32 or ToInt64 methods? Just out of curiosity. – Raheel Khan Jun 10 '13 at 16:45
  • @RaheelKhan Ah well as far as the overload goes, you could try giving it a different name and attach it to the same Windows API function by doing `[DllImport("user32.Dll", EntryPoint = "EnumWindows")]` (note the `EntryPoint` parameter) – Matthew Watson Jun 10 '13 at 17:02