[.net] Finding all windows using C#

Started by
6 comments, last by thona 19 years, 1 month ago
Do you guys know of any generic way to enumerate all the windows in a C# application (kind of similar to EnumWindows in Win32). I could import and use EnumWindows, but I'm not sure how to get a C# Form back from an hwnd... I guess EnumWindows also scans all the windows currently active, and not just the ones in my application. Thanks if you guys have any ideas. [Edited by - Washu on March 8, 2005 5:34:34 PM]
Advertisement
Are you trying to find all top-level windows, or just descendents of a window? In the latter case I believe you can simply use the Control.Controls collection to do the enumeration.

If you're enumerating all top-level windows with EnumWindows, you can restrict windows to those in your process via a combination of GetWindowThreadProcessId and GetProcessId (gets the ID of the current process).

As for getting a Form from a window, I don't know if this'll work but you could try deriving your own class from Form and overriding Control.Handle, Control.CreateHandle, Control.DestroyHandle, and possibly other methods to use the HWND you want.

This is an ugly solution that needs P/Invoke, though :/

Yeah I was looking to scan all the top-level windows as you guessed. The second part of your response was helpful, but I'm not sure the last part will help me get the actual Form once I have the hwnd... Unless I've overlooked the documentation, overriding the Handle properties and functions in a Form will not somehow down the road get me a reference to the actual Form I want to access.

I guess the crux of my question now is how to get a Form reference once I have an HWND.
The idea was to create a Form wrapper class that "constructed" an HWND by using an HWND you provide, so something like:

public class FormWrapper : Form{  public FormWrapper(IntPtr hwnd)  {    _hwnd = hwnd;  }  private IntPtr _hwnd;  public override IntPtr Handle  {    return new _hwnd;  }  public override CreateHandle()  {    // do nothing, we already have a handle  }  // etc.}Form form = new FormWrapper(hwnd);
Then you can use that form instance, assuming that the Form implementation uses the Handle property whenever it needs a window handle. But for some reason I can't override Handle in the test code I'm writing, despite it being marked virtual in both the documentation and object browser.

What are you trying to do (high-level view)?

Using HWND in a managed application isn't really good (although sometimes necessary). Consider the Handle property in System.Windows.Forms.Form as a hack - it's needed because not all win32 windowing functions are implemented in managed code.

So if this is purely inside your application, is there any way you could solve your problem in an alternate way without using the HWND? If you give the full picture someone might be able to give other suggestions.
AP has a good point. Could you keep track of your top-level forms somehow since they're all in your app?

Update: Okay I poked around in System.Windows.Forms.dll using ildasm and get_Handle is declared native, so that's probably why you can't override it. I guess you're out of luck :)

[Edited by - mutex on March 9, 2005 1:01:38 AM]

Thanks for help even though it may be fruitless. The reason I wanted this functionality was I wanted the ability to iterate through all the Forms in my application. I could register each Form in a list when it is made, but I viewed this as an inferior solution - it might have to do, however.
::I could register each Form in a list when it is made, but I viewed this as an
::inferior solution

Delusion. This is the superior solution.
RegardsThomas TomiczekTHONA Consulting Ltd.(Microsoft MVP C#/.NET)

This topic is closed to new replies.

Advertisement