How to open external process on second Monitor

Asked

Viewed 197 times

2

I need to open an external program to stay in the second screen. I need it to be exactly embedded in the second monitor.

Let’s say I want to open the notepad, I don’t want to open it on the first monitor, but on the second monitor. That’s my goal.

I’m taking the information from the second screen to move the Notepad to it. Note that the second screen is in the form of array[1], that array is the information of the second extended screen. To execute the code below, you need to extend the screen and leave the Notepad open.

public Form1() {
  InitializeComponent();
  Rectangle area = Screen.AllScreens[1].WorkingArea;
  ScreenMove(area.X, area.Y, area.Width, area.Height);

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

[DllImport("user32.dll", SetLastError = true)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

const uint SWP_NOSIZE = 0x0001;
const uint SWP_NOZORDER = 0x0004;

public static void ScreenMove(int x, int y, int lx, int ly) {
 IntPtr hWnd = FindWindow("Notepad", null);
 if (hWnd != IntPtr.Zero) {
  SetWindowPos(hWnd, IntPtr.Zero, x, y, lx, ly, SWP_NOSIZE | SWP_NOZORDER);
 }
}

inserir a descrição da imagem aqui

That’s what I can’t, there must be some way to move the Otepad window to the second screen, but I don’t know which.

2 answers

0


You can do it this way:

[Flags]
public enum SetWindowPosFlags : uint
{
    // ReSharper disable InconsistentNaming

    /// <summary>
    ///     If the calling thread and the thread that owns the window are attached to different input queues, the system posts the request to the thread that owns the window. This prevents the calling thread from blocking its execution while other threads process the request.
    /// </summary>
    SWP_ASYNCWINDOWPOS = 0x4000,

    /// <summary>
    ///     Prevents generation of the WM_SYNCPAINT message.
    /// </summary>
    SWP_DEFERERASE = 0x2000,

    /// <summary>
    ///     Draws a frame (defined in the window's class description) around the window.
    /// </summary>
    SWP_DRAWFRAME = 0x0020,

    /// <summary>
    ///     Applies new frame styles set using the SetWindowLong function. Sends a WM_NCCALCSIZE message to the window, even if the window's size is not being changed. If this flag is not specified, WM_NCCALCSIZE is sent only when the window's size is being changed.
    /// </summary>
    SWP_FRAMECHANGED = 0x0020,

    /// <summary>
    ///     Hides the window.
    /// </summary>
    SWP_HIDEWINDOW = 0x0080,

    /// <summary>
    ///     Does not activate the window. If this flag is not set, the window is activated and moved to the top of either the topmost or non-topmost group (depending on the setting of the hWndInsertAfter parameter).
    /// </summary>
    SWP_NOACTIVATE = 0x0010,

    /// <summary>
    ///     Discards the entire contents of the client area. If this flag is not specified, the valid contents of the client area are saved and copied back into the client area after the window is sized or repositioned.
    /// </summary>
    SWP_NOCOPYBITS = 0x0100,

    /// <summary>
    ///     Retains the current position (ignores X and Y parameters).
    /// </summary>
    SWP_NOMOVE = 0x0002,

    /// <summary>
    ///     Does not change the owner window's position in the Z order.
    /// </summary>
    SWP_NOOWNERZORDER = 0x0200,

    /// <summary>
    ///     Does not redraw changes. If this flag is set, no repainting of any kind occurs. This applies to the client area, the nonclient area (including the title bar and scroll bars), and any part of the parent window uncovered as a result of the window being moved. When this flag is set, the application must explicitly invalidate or redraw any parts of the window and parent window that need redrawing.
    /// </summary>
    SWP_NOREDRAW = 0x0008,

    /// <summary>
    ///     Same as the SWP_NOOWNERZORDER flag.
    /// </summary>
    SWP_NOREPOSITION = 0x0200,

    /// <summary>
    ///     Prevents the window from receiving the WM_WINDOWPOSCHANGING message.
    /// </summary>
    SWP_NOSENDCHANGING = 0x0400,

    /// <summary>
    ///     Retains the current size (ignores the cx and cy parameters).
    /// </summary>
    SWP_NOSIZE = 0x0001,

    /// <summary>
    ///     Retains the current Z order (ignores the hWndInsertAfter parameter).
    /// </summary>
    SWP_NOZORDER = 0x0004,

    /// <summary>
    ///     Displays the window.
    /// </summary>
    SWP_SHOWWINDOW = 0x0040,

    // ReSharper restore InconsistentNaming
}


public static bool MoveToMonitor(IntPtr windowHandle, int monitor)
{
    monitor = monitor - 1;
    return WinApi.SetWindowPos(windowHandle, IntPtr.Zero, Screen.AllScreens[monitor].WorkingArea.Left,
     Screen.AllScreens[monitor].WorkingArea.Top, 1000, 800, SetWindowPosFlags.SWP_NOZORDER | SetWindowPosFlags.SWP_NOREDRAW);
}

var p = Process.Start("notepad");
MoveToMonitor(p.MainWindowHandle, 2);

Thank the SOEN

  • Bruno Where do I get the Winapi class?

  • @System Oops forgot about that dependency. You are here https://github.com/alex-tomin/Tomin.Tools.KioskMode/blob/master/Tomin.Tools.KioskMode/WinApi.cs

  • Certinho agr, thank you very much!

0

System, you need to know if the machine has two monitors... Use "System.Windows.Forms":

if (Screen.AllScreens.Length > 1)
{
 //Estendido
}
else
{
 //Duplicado, ou apenas 1 tela
}

See in:

How to know if the screen is in "Extend" mode?

  • Thanks for the reply, but like, what I put inside the first IF?

  • In the first IF you put the code to point to the other screen. To do this, you need to change the positioning of the form.

  • How do I change the placement of the Form? It’s just that I’m a layman at it :(

  • Err... is... in the case of a "CALL" or something like that for an external program... I don’t know if you can pass some "parameter" to Windows to reposition on the screen. Sorry...

  • Wait! I had an idea, but it needs to be tested. See the property: "Processstartinfo.Createnowindow", it starts the process in a new window... is it possible to control the position of this new window? See: Process.Start Method - https://docs.microsoft.com/pt-br/dotnet/api/system.diagnostics.process.start?view=netframework-4.7.2

Browser other questions tagged

You are not signed in. Login or sign up in order to post.