http://doughennig.blogspot.com/2007/04/handling-multiple-monitors.html
Autor: Doug Hennig
Traducido por: Ana María Bisbé York
Una de las cosas que hice con mi nuevo portátil fue configurarle múltiples monitores. Algunos desarrolladores que conozco y respeto lo han hecho desde hace años, así que supongo que ya sea hora de que yo también lo intente. No hay nada que decir, me gusta. Tengo generalmente el Examinador y explorador de Windows abiertos en el segundo monitor y mantengo el monitor primario para aquellas cosas que hago a lo largo del día (principalmente VFP y Outlook). Soy más productivo ahora que no tengo que moverme entre la pila de ventanas ni moverme o redimensionar constantemente una ventana.
Sin embargo, una de las cosas que he descubierto hoy, es que algunas de mis aplicaciones no respetan el segundo monitor. Por ejemplo, tengo una clase llamada SFPersistentForm que arrastro a la mayoría de mis formularios. Esta clase guarda el tamaño y posición del formulario cuando se cierra y lo restaura cuando se abre nuevamente, dando al usuario la experiencia que el espera al trabajar con este formulario. Sin embargo, he descubierto que si abro el formulario y lo muevo al segundo monitor, luego llo cierro, y cuando lo reabro el formulario se muestra sin embargo, en el primer monitor (es un formulario con Desktop = .T., por tanto puede existir fuera de la aplicación).
Rápidamente encontré la razón: el código intentaba evitar la situación en la que el formulario pudiera abrirse fuera de los límites de la pantalla, haciéndolo invisible. El siguiente código controla esto:
Thisform.Width = min(max(Thisform.Width, 0, Thisform.MinWidth), ; _screen.Width) Thisform.Height = min(max(Thisform.Height, 0, Thisform.MinHeight), ; _screen.Height) Thisform.Left = min(max(Thisform.Left, 0), _screen.Width - 50) Thisform.Top = min(max(Thisform.Top, 0), _screen.Height - 50)("-50" se utiliza para garantizar que el formulario no comience exactamente la derecha del borde del monitor, haciéndolo esencialmente invisible.)
Existen dos problemas con este código. Primero, la confiabilidad en _SCREEN asume que el formulario existe con _SCREEN, que es un formulario de nivel superior o uno con Desktop = .T., que no es necesariamente el caso. Segundo, si se maximiza _SCREEN, solo cabe en el monitor actual. Si el formulario está en el otro monitor, las dimensiones de _SCREEN son irrelevantes.
Inicialmente cambié el código:
if Thisform.Desktop or Thisform.ShowWindow = 2 lnWidth = sysmetric(1) lnHeight = sysmetric(2) else lnWidth = _screen.Width lnHeight = _screen.Height endif Thisform.Desktop ... Thisform.Width = min(max(Thisform.Width, 0, Thisform.MinWidth), ; lnWidth) Thisform.Height = min(max(Thisform.Height, 0, Thisform.MinHeight), ; lnHeight) Thisform.Left = min(max(Thisform.Left, 0), lnWidth - 50) Thisform.Top = min(max(Thisform.Top, 0), lnHeight - 50)Sin embargo, SYSMETRIC() sólo devuelve valores para el monitor primario. Entonces, cambié las sentencias a:
declare integer GetSystemMetrics in Win32API integer #define SM_CXVIRTUALSCREEN 78 && Ancho Virtual #define SM_CYVIRTUALSCREEN 79 && Altura Virtual lnWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN) lnHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN)Ahora el formulario se reabre en la misma posición exacta, incluyendo el monitor donde estaba antes.
Enlace a la clase Multiple Monitor Class: https://doughennig.blogspot.com/2010/02/multiple-monitor-class.html (Gracias Hernan Cano por el enlace)