2

There are two monitors and an application (e.g. IE) is currently active/displayed in the 2nd monitor. How do I detect if an application is in 1st or 2nd monitor. I need to know this - to show a userform just on top of the application irrespective of the monitor in which it is. I know what the WindowText (Title) would be (if that helps).

Right now I just show my form near the system tray but would like to show it on top of the application.

// FORM POSITION
this.StartPosition = FormStartPosition.Manual;
Rectangle workArea = Screen.PrimaryScreen.WorkingArea;
int left = workArea.Width - this.Width;
int top = workArea.Height - this.Height;
this.Location = new Point(left, top);
leppie
  • 115,091
  • 17
  • 196
  • 297
  • 1
    Can't you use the form you want to show it on top of as guide? – Lasse V. Karlsen Apr 04 '14 at 12:22
  • @LasseV.Karlsen : I didn't get what you have asked. Do you want me to show the entire code ? I can change int top = 0; in the above code which partially solves my problem, but not in two monitors. –  Apr 04 '14 at 12:28
  • I agree that you should be using the target window without any other information, if possible. If that doesn't work, you can pull the `Top` and `Left` coordinates and compare them to `System.Windows.Forms.Screen.AllScreens[]`. – John C Apr 04 '14 at 12:29
  • If he has maximized the form, the form bounds is outside the screen areas. Additionally, a form could be laid out over two or more screens. – Lasse V. Karlsen Apr 04 '14 at 12:33

2 Answers2

1

This was converted from VB but should work.

The Test() method shows how you would use it.

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}

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


[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);

public static RECT GetWindowLocationByName(string name)
{
    IntPtr handle = FindWindow(default(string), name);
    RECT result = default(RECT);
    GetWindowRect(handle, ref result);
    return result;
}

public static void Test()
{
    dynamic location = GetWindowLocationByName("Untitled - Notepad");
    Screen result = null;

    foreach (Screen s in Screen.AllScreens) {
        if (s.WorkingArea.IntersectsWith(new Rectangle(location.Left, location.Top, location.Right - location.Left, location.Bottom - location.Top))) {
            result = s;
        }
    }
}

Edit: More Info

Step 1: Get the window handle Step 2: Get the window rect (location/size) Step 3: Determin which monitor the window resides on

If your looking at overlyaying one window on top of another you don't actually need to know which monitor it is on just the position and size of the window relative to the desktop. In both windows forms and WPF when you set the window location X / Left is the distance in pixels from the left side of the left most monitor. E.g if you have two montior 1024 pixels wide setting X / Left to 2000 will put the window 86 pixels into right hand monitor.

apc
  • 5,306
  • 1
  • 17
  • 26
  • Thanks!. Just a note : Constants.vbNullString was not working for me so I changed it to default(string). –  Apr 04 '14 at 15:47
  • Ooops sorry, thats a vb thing. I passed the whole thing through a converter. – apc Apr 07 '14 at 07:18
0

To get the windows position of another process you could use the library mentioned here

How to get and set the window position of another application in C#

You should then be able to check on which screen the position of the rectangle is

private Screen IsVisibleOnScreen(Rectangle rect)
{
    foreach (Screen screen in Screen.AllScreens)
    {
        if (screen.WorkingArea.IntersectsWith(rect))
        {
            return Screen;
        }
    }

    return null;
}
Community
  • 1
  • 1
Marc Wittmann
  • 2,286
  • 2
  • 28
  • 41