2012-06-07 12 views
22

En un sistema de monitores múltiples, una aplicación VCL "en blanco" maximiza la multa, pero la misma aplicación con estilos habilitados (y una elegida como predeterminada) maximiza incorrectamente. Lo que estoy viendo es que el borde derecho de la ventana se extiende al segundo monitor (mi principal está a la izquierda). Cuando comencé a comparar con otras aplicaciones de Windows, noté que en Windows 7 (al menos), las ventanas maximizadas ni siquiera tienen bordes que no sean del cliente en los lados izquierdo, derecho o inferior. Y, de hecho, la aplicación estándar VCL (sin estilo) se comporta de la misma manera, sin fronteras de clientes.¿Qué puedo hacer con las ventanas maximizadas y con estilo, que muestran sus bordes en monitores adyacentes?

¿Cómo puedo solucionar esto? Noté que TFormStyleHook tiene un controlador para WMNCCalcSize, que aún no he analizado, pero me hace preguntarme si VCL podría estar manejando incorrectamente este mensaje para una ventana maximizada.

+5

Sin embargo, más errores de estilos VCL. Por favor, control de calidad esto. –

+1

Dirección web de control de calidad: http://qc.embarcadero.com/wc/qcmain.aspx –

+0

¿Se puede reproducir este comportamiento en un solo monitor? Pregunto porque en mi ubicación actual no tengo otro monitor para probar este problema. – RRUZ

Respuesta

5

Después de jugar algo de tiempo en esto, mi opinión es que este no es un error de vcl-styles en absoluto. Esto de hecho está relacionado con el comportamiento en el article mencionado en un comment a la pregunta por mghie.

El comportamiento específico es que, el tamaño de una ventana maximizada es mayor que el área de trabajo del monitor en el que se maximiza la ventana. Supuestamente, el administrador de ventanas oculta los bordes salientes. Aparentemente, no lo hace con marcos personalizados. Tenga en cuenta que el propio custom window frame example de MSDN parece sufrir el mismo problema (consulte la publicación titulada "Error al maximizar la ventana" en contenido de la comunidad). La aplicación de VCL es diferente al ejemplo de MSDN porque no está basado en DWM, pero sigo pensando que es el mismo problema.

Los bordes salientes tienen el tamaño del borde del tamaño del sistema (SM_C [X | Y] SIZEFRAME), pero esto es irrelevante para la solución siguiente ya que ignora el tamaño/posición sugerido del sistema operativo y utiliza el área de trabajo.

Lamentablemente, no creo que esta solución alternativa se pueda utilizar en absoluto. Por un lado, el comportamiento mencionado no está documentado, para dos, la solución no es perfecta; todavía hay un píxel extraño. Si ajusta la ventana exactamente en el área de trabajo, el administrador de ventanas decide desplazar la ventana hacia donde cree que debe ubicarse la ventana (con marcos ocultos). (El VCL probablemente podría modificarse para hacer lo que hace el administrador de ventanas, y tener en cuenta el voladizo y no dibujarlos o algo similar, pero sería más trabajo y aún sería una solución de comportamiento no documentado ...)

De todos modos;

type 
    TForm1 = class(TForm) 
    .. 
    protected 
    // overriding styles is not necessary since TFormStyleHook.WMGetMinMaxInfo 
    // first calls the default window procedure 
    procedure WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo); 
     message WM_GETMINMAXINFO; 

.. 

procedure TForm1.WMGetMinMaxInfo(var Message: TWMGetMinMaxInfo); 
var 
    R: TRect; 
begin 
    // always arrives with MinMaxInfo.ptMaxPosition = (-SM_CXFRAME, -SM_CYFRAME) 
    // and MinMaxInfo.ptMaxSize = (PrimaryMonitor.Width (?) + 2 * SM_CXFRAME, ...) 
    inherited; 

    // should test for OS, styles etc. before running the below 
    R := Monitor.WorkareaRect; 
    InflateRect(R, -1, -1);    // odd pixel 
    OffsetRect(R, -Monitor.Left, -Monitor.Top); 
    Message.MinMaxInfo.ptMaxPosition := R.TopLeft; 
    Message.MinMaxInfo.ptMaxSize := Point(R.Width, R.Height); 
end; 
+0

Raymond dice específicamente "truco visual", así que supongo que no cambiamos el tamaño de la ventana, sino que solo cortamos los bordes que sobresalen. – whosrdaddy

+0

@whos - Claro, sería mucho mejor (también deshacerse de los marcos internos). Pensé que necesitaríamos la cooperación de VCL para eso, pero tal vez no. –

0

La única forma que encontré es manejar el evento WM_SIZE y modificar la región de la ventana para cortar el borde adicional.

Cuestiones relacionadas