0

My C# project starts some other processes, which create windows of their own. Displaying all those windows is messy - is there a way to clip/mask these windows (which my project does not own) so only a small portion of them is displayed and able to be interacted with?

E.g. something one'd pass a wHnd together with a Rectangle.

Is this a thing that exists?

chigauyone
  • 21
  • 1
  • You could hide them with [ShowWindow](https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-showwindow)? – Idle_Mind Jun 04 '19 at 21:21
  • Are you trying to create something like an MDI window, but with child windows from separate processes? – Michael Gunter Jun 04 '19 at 21:31
  • So you'd start the Process, call [WaitForInputIdle](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.waitforinputidle?view=netframework-4.8), then pass [MainWindowHandle](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.mainwindowhandle?view=netframework-4.8) to the aforementioned ShowWindow() API. – Idle_Mind Jun 04 '19 at 21:46
  • @Idle_Mind Hmmm, well I don't want to hide the entire window. I just want to clip out a specific part - something like this: ![clip](https://i.imgur.com/MsOz7KA.png) – chigauyone Jun 04 '19 at 22:08
  • @MichaelGunter MDI would work, I suppose - I would be able to make a borderless window myself and put the target window inside it in such a position that it's clipped. Would that be possible with non-WinForms windows though? – chigauyone Jun 04 '19 at 22:08
  • 1
    Yes. MDI can be accomplished with just Win32. https://learn.microsoft.com/en-us/windows/desktop/winmsg/multiple-document-interface – Michael Gunter Jun 04 '19 at 22:18
  • @MichaelGunter Are we allowed to just attach any old window willy-nilly to ours, though? I presume this'd use `SetParent(IntPtr hWndChild, IntPtr hWndNewParent)` to connect a child to a parent, but what if that's a completely random window that otherwise has no connection to our host (other than the host knowing the child's hWnd)? – chigauyone Jun 04 '19 at 22:23
  • 1
    You can have a child window that is of a different process than the parent window. Google Chrome, Internet Explorer, Edge, and my company's primary product (the Bloomberg Terminal) do this extensively. However, there are _many_ pitfalls of this. And I've never tried to do it with MDI windows. – Michael Gunter Jun 04 '19 at 23:25
  • @MichaelGunter That indeed works, thank you very very much!! – chigauyone Jun 05 '19 at 12:58

1 Answers1

1

Very, very many thanks to @Michael Gunter, MDI indeed allows to make such constructions!

For anyone who stumbles into this question years from now, here's what works:

IntPtr finalhWnd; // the window to clip's handle

Form mdiP = new MDIParent(); // MDIParent is custom, just a simple form without a border
mdiP.Show();

SetParent(finalhWnd, mdiP.Handle); // set the target form as a child of our own
SetWindowPos(finalhWnd, (IntPtr)0, -30, -50, 100, 100, 0x0200); // clip a 100x100 block, starting at (30,50)

Application.Run();

Here's an example of using it to clip the borders off of a Chrome instance:

enter image description here

Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
chigauyone
  • 21
  • 1
  • If you're only hosting one child window, you don't need an MDI container for this. The way the original post was worded, it sounded like you wanted to display multiple windows in some sort of container. – Michael Gunter Jun 05 '19 at 16:46