2010-03-31 20 views
35

Quali ritieni siano le migliori pratiche per rendere la finestra di dialogo di Windows compatibile sia con i caratteri standard (96 dpi) che con l'impostazione "caratteri grandi" (120 dpi) in modo che gli oggetti non si sovrappongano o si tagliano?Rende le finestre di dialogo compatibili con "caratteri grandi".

BTW: Nel caso sia pertinente, sono interessato a farlo per i dialoghi Delphi.

Grazie in anticipo!

+2

11 upvotes e nessuna risposta ancora! Sembra una buona domanda. –

+0

La domanda è un po 'aspecifica. Sarebbe più semplice rispondere a un problema specifico. Quindi anche le risposte sono di ampio respiro. – merula

+0

Anche il problema è di ampio respiro. Preferisco avere una soluzione che funzioni in tutte le situazioni invece di avere più piccole soluzioni per problemi specifici che potrebbero non funzionare bene insieme. –

risposta

7

C'è un articolo abbastanza buono nel file della guida di D2007, sotto "Considerations When Dynamically Resizing Forms and Controls" (si noti che l'URL si trova nel file della guida stesso e non in una pagina Web in quanto tale).

Lo stesso argomento, con lo stesso nome, può essere trovato nel D2010 help file (stessa avvertenza sull'URL come sopra) o sul docwiki.

Vale anche la pena (almeno un po ') di esaminare TForm.Scaled e TForm.ScaleBy.

8

In generale, è necessario utilizzare i gestori di layout per questo scopo. Quello per cui sono progettati.

Delphi (non ha funzionato per molto tempo) non dispone di tali gestori ma è in grado di gestire dpi diversi da allora. È necessario utilizzare l'autosize propery dei componenti per assicurarsi che abbiano le giuste dimensioni per il testo che visualizzano. Per evitare la sovrapposizione dei componenti, sistemali sul modulo utilizzando le proprietà di allineamento e ancoraggio. Alla fine devi raggruppare i componenti in contenitori per ottenere un layout corretto.

+4

Penso che la risposta breve sia "questo è un enorme punto debole delphi". XAML lo fa meglio. Java/Swing lo fa meglio. Francamente, tutto il resto là fuori lo fa meglio di Delphi. Anche roba open source come Glade che è basata sul layout manager fa meglio questa roba. –

+0

Le versioni moderne di Delphi hanno componenti di gestione del layout, almeno in FireMonkey: [FireMonkey Layouts Strategies] (http://docwiki.embarcadero.com/RADStudio/en/FireMonkey_Layouts_Strategies). Tuttavia, ci sono componenti di layout di terze parti disponibili per VCL. –

0
  • Non mettere mai un controllo e la sua etichetta descrittiva fianco a fianco, posizionare sempre l'etichetta su di esso.

Ma a parte questo? Forse:

  • Lascia uno spazio sufficiente a destra e in fondo alle etichette in modo che non si sovrappongano ad altri controlli quando si utilizzano caratteri grandi.

Non ho mai provato a utilizzare TLabeledEdit in quello scenario, forse lo fanno automaticamente?

0

Ci sono presunte soluzioni commerciali (Developer Express VCL Layout Manager). Ma non mi fido di nessuno di loro. Ho il sospetto che Embarcadero dovrebbe affrontare questo come una debolezza critica nel set di componenti dell'interfaccia utente corrente (VCL).

Penso che il set di componenti di terze parti potrebbe essere la soluzione più veloce in questo momento. È commerciale ma non eccessivamente costoso.

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

+0

Esiste già un supporto per questo argomento nelle versioni moderne di Delphi? (XE e superiore) – EProgrammerNotFound

+0

Non per i display ad alta DPI, che è il problema sottostante, "Caratteri grandi dimensioni" significa in realtà più di 96 DPI, così come "DPI hack" utilizzato da Microsoft (DPI falso per ingrandire i caratteri). –

2

Questo è come io cerco di fare con pixel di Delphi VCL indipendentemente dall'impostazione della dimensione del font di 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. 

provare il seguente per testare gli effetti del diverso valore di pixel:

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

è necessario modificare il PixelsPerInch prima di istanziare discendente di TForm tra cui i dialoghi VCL di Delphi.

+0

Perché stai usando un 'class helper' per la tua classe' TAppScreen'? Tutti i membri 'class' dovrebbero essere nella classe' TAppScreen' stessa. Non è necessario utilizzare un 'class helper' per' TAppScreen'. Per quanto riguarda l'accesso al membro 'TScreen.FPixelsPerInch', considerare l'utilizzo di Enhanced RTTI tramite l'unità' System.Rtti', che può accedere a campi privati ​​e pubblici, non solo alle proprietà pubblicate come con Legacy RTTI dall'unità 'TypInfo'. –

Problemi correlati