2

Is it possible to do the following with WinForms/C#?

  1. Dynamically detect window size and position of a running program (for example Notepad.exe)?
  2. Snap WinForm to specific position within Notepad.exe?
  3. Minimize and maximize WinForm window with other process (so when Notepad is minimize, so is WinForm window)?

See for example (black shape would be WinForm window):

Essentially I need to create a toolbar for a program, and the toolbar should "snap" to that program in the same place regardless of position or size of window.

Athari
  • 33,702
  • 16
  • 105
  • 146

2 Answers2

2

First find the handle of the notepad window:

[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

Just pass null for the first parameter and the caption ("Notepad"?) of the window as the second parameter.

An alternative would be to enumerate all windows and select the best match based on the caption:

using System.Runtime.InteropServices;

public delegate bool CallBackPtr(int hwnd, int lParam);
private CallBackPtr callBackPtr;

public class EnumReport 
{
    [DllImport("user32.dll")]
    private static extern int EnumWindows(CallBackPtr callPtr, int lPar); 

    public static bool Report(int hwnd, int lParam) 
    { 
        Console.WriteLine("Window handle is "+hwnd);
        return true;
    }
}
static void Main()
{

     // note in other situations, it is important to keep 
     // callBackPtr as a member variable so it doesnt GC while you're calling EnumWindows

     callBackPtr = new CallBackPtr(EnumReport.Report);  
    EnumReport.EnumWindows(callBackPtr, 0);
}

Then attach a WndProc to it:

HwndSource src = HwndSource.FromHwnd(windowHandle);
src.AddHook(new HwndSourceHook(WndProc));

In the WndProc respond to the resizing and moving of the window.

I am not sure about setting the toolbar as a child of the notepad window; that might have unexpected effects when Notepad tries to manage it and order its z-depth.

At the same time I doubt this to be a good thing; the user will be able to type 'below' the overlay and lose his cursor/text.

Emond
  • 50,210
  • 11
  • 84
  • 115
  • Note: https://stackoverflow.com/questions/7860083/c-sharp-hwndsource-from-process-mainwindowhandle – Ken Kin Jan 27 '18 at 05:36
1
  1. Find Notepad's window (FindWindow).
  2. Create your window without borders.
  3. Set your window as a child of Notepad's window (SetParent).

Your window will be anchored to the top left corner of Notepad's window. Minimizing will be handled automatically, but you'll need to resize your window when Notepad's window is resized (or maximized). You may also want to move Notepad's edit control.

WinForms can be used, but you'll need some interop calls.

I have to warn that this is not a very good idea. Your controls may conflict with controls inside host process's window, host process may rearrange controls the way you don't like, draw over your controls. In general, be ready to fight with numerous issues without a good clean solution, and to accept that there may be glitches when resizing etc.

See also:

Community
  • 1
  • 1
Athari
  • 33,702
  • 16
  • 105
  • 146
  • Is there a way to center the child window halfway (so center from top left)? – Peter Hoffman Sep 17 '14 at 06:01
  • @PeterHoffman You'll have to do it the hard way: handle parent window's resize events (or just check parent window's size on timer) and move and resize your window accordingly. Anchors and alignment do not exist on OS level, they're feature of WinForms and will work only inside your window. – Athari Sep 17 '14 at 06:03