2010-03-31 10 views
35

¿Cuáles cree que son las mejores prácticas para hacer que un diálogo de Windows sea compatible con fuentes estándar (96 ppp) y configuración de "fuentes grandes" (120 ppp) para que los objetos no se superpongan o se corten?Haga que los diálogos sean compatibles con "fuentes grandes".

BTW: en caso de que sea relevante, me interesa hacer esto para los cuadros de diálogo Delphi.

¡Gracias de antemano!

+2

11 votos positivos y ninguna respuesta aún! Parece una buena pregunta. –

+0

La pregunta es un poco inespecífica. Sería más fácil responder a un problema específico. Entonces las respuestas son de amplio alcance también. – merula

+0

El problema es amplio en alcance, también. Prefiero tener una solución que funcione en todas las situaciones en lugar de tener múltiples soluciones pequeñas para problemas específicos que pueden no funcionar bien juntos. –

Respuesta

7

Hay un artículo bastante bueno en el archivo de ayuda D2007, bajo "Considerations When Dynamically Resizing Forms and Controls" (tenga en cuenta que la URL es al archivo de ayuda en sí, y no a una página web como tal).

El mismo tema, con el mismo nombre, se puede encontrar en el D2010 help file (misma advertencia sobre la URL que arriba), o en el docwiki.

También vale la pena (al menos un poco) examinar TForm.Scaled y TForm.ScaleBy.

8

En general, uno debe usar administradores de diseño para este propósito. Para lo que están diseñados.

Delphi (no funcionó con esto durante mucho tiempo) no tiene tales administradores, pero es capaz de manejar diferentes ppp desde entonces. Debe usar la propiedad autosize de los componentes para asegurarse de que tengan el tamaño correcto para el texto que muestran. Para evitar la superposición de componentes, organícelos en el formulario utilizando las propiedades de alineación y anclaje. Finalmente, debe agrupar los componentes en contenedores para lograr un diseño adecuado.

+4

Creo que la respuesta corta es "este es un gran punto débil del delfín". XAML lo hace mejor. Java/Swing lo hace mejor. Francamente, todo lo demás lo hace mejor que Delphi. Incluso las cosas de código abierto como Glade, que está basado en el administrador de disposición, hacen esto mejor. –

+0

Las versiones modernas de Delphi tienen componentes de administración de diseño, al menos en FireMonkey: [Estrategias de diseños de FireMonkey] (http://docwiki.embarcadero.com/RADStudio/es/FireMonkey_Layouts_Strategies). Sin embargo, hay componentes de diseño de terceros disponibles para VCL. –

0
  • Nunca coloque un control y su etiqueta descriptiva una al lado de la otra, siempre coloque la etiqueta encima.

¿Pero aparte de eso? Tal vez:

  • Deje suficiente espacio a la derecha e inferior de las etiquetas para que no se superpongan con otros controles cuando se utilizan fuentes grandes.

Nunca he intentado utilizar TLabeledEdit en ese escenario, ¿quizás lo hagan automáticamente?

0

Existen supuestas soluciones comerciales (Developer Express VCL Layout Manager). Pero no confío en ninguno de ellos. Sospecho que Embarcadero debería abordar esto como una debilidad crítica en el conjunto de componentes de interfaz de usuario (VCL) actual.

Creo que el conjunto de componentes de terceros podría ser su solución más rápida en este momento. Es comercial, pero no muy costoso.

http://www.devexpress.com/products/VCL/ExLayoutControl/

+0

¿Ya hay soporte para este tema en las versiones modernas de Delphi? (XE y superior) – EProgrammerNotFound

+0

No para pantallas con alta DPI, que es el problema subyacente, "tamaños de fuente grandes" realmente significa pantallas superiores a 96 ppp, así como el "pirateo DPI" utilizado por Microsoft (PPO falso para ampliar fuentes). –

2

Esta es la forma en que trato de hacer frente a los píxeles de Delphi VCL independientemente del ajuste de tamaño de la fuente de Windows.

unit App.Screen; 

interface 

uses Controls; 

type 
    TAppScreen = class(TObject) 
    private 
    FDefaultPixelsPerInch: integer; 
    FPixelsPerInch: integer; 
    function GetPixelsPerInch: integer; 
    procedure SetPixelsPerInch(const Value: integer); 
    public 
    procedure AfterConstruction; override; 
    function DefaultPixelsPerInch: integer; 
    function InAcceptableRange(const aPPI: integer): boolean; 
    procedure ScaleControl(const aControl: TWinControl); 
    property PixelsPerInch: integer read GetPixelsPerInch write SetPixelsPerInch; 
    end; 

    TAppScreenHelper = class helper for TAppScreen 
    private 
    class var FInstance: TAppScreen; 
    class function GetInstance: TAppScreen; static; 
    public 
    class procedure Setup; 
    class procedure TearDown; 
    class property Instance: TAppScreen read GetInstance; 
    end; 

implementation 

uses 
    TypInfo, Windows, SysUtils, Forms, Graphics; 

type 
    TScreenEx = class(TScreen) 
    published 
    property PixelsPerInch; 
    end; 

    TScreenHelper = class helper for TScreen 
    public 
    procedure SetPixelsPerInch(Value: integer); 
    end; 

procedure TScreenHelper.SetPixelsPerInch(Value: integer); 
begin 
    PInteger(Integer(Self) + (Integer(GetPropInfo(TScreenEx, 'PixelsPerInch').GetProc) and $00FFFFFF))^ := Value; 
end; 

procedure TAppScreen.AfterConstruction; 
begin 
    inherited; 
    FDefaultPixelsPerInch := Screen.PixelsPerInch; 
    FPixelsPerInch := FDefaultPixelsPerInch; 
end; 

function TAppScreen.DefaultPixelsPerInch: integer; 
begin 
    Result := FDefaultPixelsPerInch; 
end; 

function TAppScreen.GetPixelsPerInch: integer; 
begin 
    Result := FPixelsPerInch; 
end; 

function TAppScreen.InAcceptableRange(const aPPI: integer): boolean; 
begin 
    if DefaultPixelsPerInch > aPPI then 
    Result := DefaultPixelsPerInch * 0.55 < aPPI 
    else if DefaultPixelsPerInch < aPPI then 
    Result := DefaultPixelsPerInch * 1.55 > aPPI 
    else 
    Result := True; 
end; 

procedure TAppScreen.ScaleControl(const aControl: TWinControl); 
begin 
    aControl.ScaleBy(PixelsPerInch, DefaultPixelsPerInch); 
end; 

procedure TAppScreen.SetPixelsPerInch(const Value: integer); 
begin 
    FPixelsPerInch := Value; 
    Screen.SetPixelsPerInch(FPixelsPerInch); 
end; 

class function TAppScreenHelper.GetInstance: TAppScreen; 
begin 
    if FInstance = nil then 
    FInstance := TAppScreen.Create; 
    Result := FInstance; 
end; 

class procedure TAppScreenHelper.Setup; 
begin 
    TAppScreen.Instance; 
end; 

class procedure TAppScreenHelper.TearDown; 
begin 
    FInstance.Free; 
    FInstance := nil; 
end; 

initialization 
    TAppScreen.Setup; 
finalization 
    TAppScreen.TearDown; 
end. 

intente lo siguiente para probar los efectos de distinto valor píxeles:

TAppScreen.Instance.PixelsPerInch := 120; 
TAppScreen.Instance.PixelsPerInch := 96; 
TAppScreen.Instance.PixelsPerInch := 150; 

debe cambiar el PixelsPerInch antes de crear una instancia descendiente de TForm incluyendo diálogos VCL de Delphi.

+0

¿Por qué estás usando 'clase helper' para tu propia clase' TAppScreen'? Todos los miembros de 'clase' deberían estar en la clase' TAppScreen'. No hay necesidad de usar un 'clase helper' para' TAppScreen' en absoluto. En cuanto a obtener acceso al miembro 'TScreen.FPixelsPerInch', considere usar Enhanced RTTI a través de la unidad' System.Rtti', que puede acceder a campos privados y públicos, no solo propiedades publicadas como con Legacy RTTI de la unidad 'TypInfo'. –

Cuestiones relacionadas