none
Cambiar aplicación a un segundo monitor RRS feed

  • Pregunta

  • Buenas Noches!

    No se como abrir una aplicación externa en un monitor distinto del que se está ejecutando mi aplicación

    Sí se hacerlo con los forms, pero no con las aplicaciones:

    Por ejemplo en un pc con dos monitores: Tengo dos forms (Wind1 y Wind2); Si los dos forms se muestran en el mismo monitor, enonces desplaza el Wind2 a otro monitor

    Código:

    Dim sMonitores = Screen.AllScreens 'Matriz de monitores
    Wind1.Show()
    Wind2.Show()

    'obtiene el monitor donde se está ejecutando cada form
            Dim MonitorWind1 As Integer = -1
            Dim MonitorWind2 As Integer = -1

            For i As Integer = 0 To UBound(sMonitores)
                If Screen.FromControl(Wind1).DeviceName = sMonitores(i).devicename Then
                    MonitorWind1 = i
                End If
                If Screen.FromControl(Wind2).DeviceName = sMonitores(i).devicename Then
                    MonitorWind2 = i
                End If
            Next
            'Si los dos formularios están en el mismo monitor, desplaza el Wind2
            If MonitorWind1 = MonitorWind2 Then 'Los dos formularios están en el mismo monitor
                Dim MonitorDestino As Integer = 0
                If MonitorWind1 = 0 Then MonitorDestino = 1
                Wind2.Left = sMonitores(MonitorDestino).Bounds.Left
                Wind2.Top = sMonitores(MonitorDestino).Bounds.Top
            End If

    Pregunta: lo que deseo es que el Wind2 no sea un formulario, sino una aplicación externa como el Word(Dim pr = Process.Start("C:\Doc1.docx"))
    sábado, 9 de mayo de 2020 21:49

Respuestas

  •  lo que deseo es que el Wind2 no sea un formulario, sino una aplicación externa como el Word

    Es bastante más complicado. El principio es el mismo, es decir, tienes que cambiarle el Left y el Top a la ventana. Pero el problema es que no tienes acceso directo a dichas propiedades, al tratarse de una aplicación externa.

    Podrías llamar mediante P/Invoke a la API de Windows SetWindowPos para transmitir el comando de cambio de posición a la aplicación externa:

    http://www.pinvoke.net/search.aspx?search=setwindowpos&namespace=[All]

    Esto requiere que conozcas el "handle" de la ventana. Podrías tratar de obtenerlo a partir de la propiedad MainWindowHandle del Process "pr" que has usado para lanzar la aplicación. Pero el problema es que algunas aplicaciones (creo recordar que el Word es una de ellas) crean una ventana visible que no es el mismo MainWindow. En este caso tendrías que llamar a más APIs, tales como FindWindow o EnumWindows para buscar la ventana que quieres mover.

    • Marcado como respuesta Angelnovato domingo, 10 de mayo de 2020 8:14
    domingo, 10 de mayo de 2020 6:11
  • Bueno, no es exactamente idéntico a VB6. En VB.NET existe un "Declare Sub" o "Declare Function" parecido al que había en VB6, pero los argumentos son ligeramente distintos debido a la diferencia entre ambos lenguajes. Por ejemplo, una API que requiera un entero de 32 bits se tenía que declarar como Long en VB6 pero es un Integer en VB.NET. Hay un sitio que se llama pinvoke.net que tiene las declaraciones ya preparadas para copiarlas. Ten presente que en general este sitio utiliza la sintaxis moderna de .NET, empleando el atributo <DllImport> en lugar de la sintaxis antigua de VB6 con "Declare...". Aunque ambos tipos de declaración funcionan en VB.NET, te recomiendo que te acostumbres a usar el método moderno en lugar del antiguo heredado de VB6.

    pr = Process.Start("C:\Doc1.docx")).handle.ToInt64

    No, esto no vale. Te da el "handle" del proceso, no el "handle" de una ventana. Aunque en ambos casos el handle es un número entero, no tiene nada que ver el handle de un proceso con ninguno de los handles de las varias ventanas que puede abrir el proceso. Son valores numéricos diferentes.

    • Marcado como respuesta Angelnovato domingo, 10 de mayo de 2020 15:46
    domingo, 10 de mayo de 2020 9:59

Todas las respuestas

  •  lo que deseo es que el Wind2 no sea un formulario, sino una aplicación externa como el Word

    Es bastante más complicado. El principio es el mismo, es decir, tienes que cambiarle el Left y el Top a la ventana. Pero el problema es que no tienes acceso directo a dichas propiedades, al tratarse de una aplicación externa.

    Podrías llamar mediante P/Invoke a la API de Windows SetWindowPos para transmitir el comando de cambio de posición a la aplicación externa:

    http://www.pinvoke.net/search.aspx?search=setwindowpos&namespace=[All]

    Esto requiere que conozcas el "handle" de la ventana. Podrías tratar de obtenerlo a partir de la propiedad MainWindowHandle del Process "pr" que has usado para lanzar la aplicación. Pero el problema es que algunas aplicaciones (creo recordar que el Word es una de ellas) crean una ventana visible que no es el mismo MainWindow. En este caso tendrías que llamar a más APIs, tales como FindWindow o EnumWindows para buscar la ventana que quieres mover.

    • Marcado como respuesta Angelnovato domingo, 10 de mayo de 2020 8:14
    domingo, 10 de mayo de 2020 6:11
  • Gracias Alberto.

    Deduzco que la llamada a las Apis de Windowses idéntico a como se hacía en VB6.

    Y he visto que el handle de la ventana lo recupero con

    pr = Process.Start("C:\Doc1.docx")).handle.ToInt64

    ¿Te parece que es correcto?

    domingo, 10 de mayo de 2020 8:13
  • Bueno, no es exactamente idéntico a VB6. En VB.NET existe un "Declare Sub" o "Declare Function" parecido al que había en VB6, pero los argumentos son ligeramente distintos debido a la diferencia entre ambos lenguajes. Por ejemplo, una API que requiera un entero de 32 bits se tenía que declarar como Long en VB6 pero es un Integer en VB.NET. Hay un sitio que se llama pinvoke.net que tiene las declaraciones ya preparadas para copiarlas. Ten presente que en general este sitio utiliza la sintaxis moderna de .NET, empleando el atributo <DllImport> en lugar de la sintaxis antigua de VB6 con "Declare...". Aunque ambos tipos de declaración funcionan en VB.NET, te recomiendo que te acostumbres a usar el método moderno en lugar del antiguo heredado de VB6.

    pr = Process.Start("C:\Doc1.docx")).handle.ToInt64

    No, esto no vale. Te da el "handle" del proceso, no el "handle" de una ventana. Aunque en ambos casos el handle es un número entero, no tiene nada que ver el handle de un proceso con ninguno de los handles de las varias ventanas que puede abrir el proceso. Son valores numéricos diferentes.

    • Marcado como respuesta Angelnovato domingo, 10 de mayo de 2020 15:46
    domingo, 10 de mayo de 2020 9:59
  • Gracias. Muy clara tu respuesta Saludos.

    domingo, 10 de mayo de 2020 15:47
  • Hola

     

     

    Gracias por levantar tu consulta en los foros de MSDN. Cerraremos el Hilo, por ende si tiene alguna otra consulta por favor genera otra consulta para que la comunidad de foros te pueda asesorar.

     

    Siempre es un placer atender tus consultas!

     

    Gracias por usar los foros de MSDN.

     

    Oscar Navarro

    martes, 12 de mayo de 2020 16:35
    Moderador