2012-05-14 15 views
20

Esiste un metodo rapido ed efficace per applicare un carattere globale da utilizzare in un progetto?La coerenza dei font nel progetto?

Con questo voglio dire vorrei impostare un nome di carattere specifico che tutti i controlli nel mio progetto utilizzeranno come TButton, TEdit, TLabel ecc

In genere l'impostazione del tipo di carattere per la forma piuttosto che una specifica il controllo cambierà tutti i controlli su quel Form per il Font specificato.

C'è un piccolo problema con questo però, se hai modificato manualmente un Carattere su un controllo specifico, quindi l'impostazione del Carattere tramite il Modulo non aggiornerà più quei controlli che sono stati precedentemente modificati manualmente.

Idea 1

Stavo pensando di utilizzare un ciclo For e iterazione attraverso ogni componente sulle mie forme e l'impostazione del carattere in questo modo, come ad esempio:

procedure TForm1.FormCreate(Sender: TObject); 
var 
    i: Integer; 
begin 
    with TForm(Self) do 
    begin 
    for i := 0 to ComponentCount - 1 do 
    begin 
     if Components[i] is TButton then 
     begin 
     TButton(Components[i]).Font.Name := 'MS Sans Serif'; 
     TButton(Components[i]).Font.Size := 8; 
     TButton(Components[i]).Font.Style := [fsBold]; 
     end; 

     if Components[i] is TLabel then 
     begin 
     TLabel(Components[i]).Font.Name := 'MS Sans Serif'; 
     TLabel(Components[i]).Font.Size := 8; 
     TLabel(Components[i]).Font.Style := [fsBold]; 
     end; 
    end; 
    end; 
end; 

Ma fare questo sembra molto disordinato, sarà anche una notevole quantità di codice per un compito semplice.

Idea 2

So che potrei modificare manualmente i caratteri in fase di progettazione uno per uno per ogni controllo, ma con diverse forme di passare attraverso questo potrebbe richiedere tempo e anche allora potrei di mancato un controllo .

Idea 3

Simile a Idea 2, un altro modo potrebbe essere quello di visualizzare il modulo come testo (DFM) e Trova e sostituisci il tipo di carattere in quel modo.


Fondamentalmente sto andando per la coerenza all'interno della mia applicazione, e che hanno uno dei caratteri utilizzata in tutto è quello che stavo cercando di raggiungere.

Mi manca qualcosa di completamente ovvio qui, è quello che sto cercando di fare eccessivo per un tale compito?

+6

Se si modifica manualmente il carattere del controllo, si imposta anche la proprietà 'ParentFont' su' False'; impostalo 'True' per restituire il carattere predefinito (Parent) – kludg

+1

Subdolo, non mi ero reso conto che questa proprietà si stava modificando! –

+9

Prima di creare qualsiasi modulo, impostare 'Application.DefaultFont.Name: = 'MS Sans Serif';' Con ParentFont impostato su true nei moduli come indicato da Serg. Per impostare il carattere nelle finestre di dialogo dei messaggi, impostare la proprietà 'Screen.MessageFont.Name'. –

risposta

22

Come discusso nei commenti, la chiave per questo è la proprietà ParentFont. Questa proprietà è definita in vari punti della gerarchia VCL. Se si imposta ParentFont essere True per tutti i componenti della catena, quindi è possibile modificare i tipi di carattere per l'intera applicazione semplicemente modificando

Application.DefaultFont 

Per impostazione predefinita maggior parte dei componenti impostare ParentFont a True e quindi non hai nulla da fare. Quello strano è però TForm. Un nuovo modulo predefinito ha ParentFont impostato su False. Ciò è alquanto deludente, ma sospetto che rifletta il fatto che i progettisti originali della VCL non lo prevedevano e che ParentFont è stato innestato relativamente tardi nello sviluppo della VCL.

Non importa, in un mondo ideale, tutte le forme nella tua applicazione devono essere derivate da una classe base comune che controlli.In tal caso, puoi semplicemente apportare la modifica, impostare ParentFont in True, assicurarti che non vengano applicate impostazioni di carattere esplicito a nessun componente sui moduli e che tu sia d'oro. Controlla i caratteri dell'intera applicazione attraverso una singola proprietà. Se non hai una classe base comune per i tuoi moduli, ecco il momento ideale per aggiungerla. Se non si desidera farlo, è necessario impostare ParentFont per ogni modulo.

Altre proprietà correlate sono Screen.MessageFont e Screen.MenuFont. Questi forniscono il controllo globale sui caratteri utilizzati nelle finestre e nei menu. Tuttavia, le versioni recenti di Delphi hanno restituito a Windows il controllo sulla verniciatura di finestre e menu di messaggi e quindi queste proprietà non hanno alcun effetto.

+0

Non c'è davvero nulla da aggiungere a ciò che voi e altri avete già commentato. Non sarebbe bello se ci fosse un'opzione nelle Opzioni progetto per impostare uno stile Font e applicarlo al progetto, nello stesso modo in cui 'Application.DefaultFont' funziona - se come me non ero a conoscenza di questo built-in funzione, avere le impostazioni visive per cambiare il font globalmente renderebbe molto più semplice. Ad ogni modo accetto la tua risposta perché le informazioni sono ben scritte e +1 per evidenziare messaggi e menu. –

+10

Ricorda che i moduli VCL non sono "layout gestiti" come Swing (java) o WPF (C#/.net) e che cambiare i caratteri in fase di esecuzione porta a un perfetto blocco del font e rende l'interfaccia utente un pasticcio illeggibile. In bocca al lupo. Non esiste un modo pratico per modificare i caratteri di un'applicazione senza rivedere i risultati a mano, modulo per modulo, per la leggibilità. –

+3

@Warren è un buon punto e intendevo menzionarlo nella mia risposta, ma ho dimenticato. Nella mia app, mostro i caratteri in Tahoma 8 per XP o Segoe UI 9 per Vista +. Ciò richiede chiamate a ChangeScale per modificare il layout del modulo. Ma sì, devi controllare i moduli in entrambe le varianti. Fintanto che le tue etichette non si incastrano l'una contro l'altra, non c'è mai un problema. ParentFont fa miracoli in tutto questo. –

1

Se si vuole fare questo runtime, come lo si descrive in Idea 1, si dovrebbe considerare la possibilità di una funzione ricorsiva, in questo modo:

procedure SetFontProperties(Control: TControl; Name: TFontName; Size: Integer; Styles: TFontStyles); 
// Set font properties 
var 
    Index: Integer; 
    Font: TFont; 
    AnObject: TObject; 
    ChildControl: TControl; 
begin 
    // Set font properties 
    AnObject := GetObjectProp(Control, 'Font', nil); 
    if AnObject is TFont then 
    begin 
    // Set properties 
    Font := TFont(AnObject); 
    Font.Name := Name; 
    Font.Size := Size; 
    Font.Style := Styles; 
    end; 

    // Set child font properties 
    if Control is TWinControl then 
    begin 
    // Set 
    for Index := 0 to TWinControl(Control).ControlCount - 1 do 
    begin 
     // Child control 
     ChildControl := TWinControl(Control).Controls[Index]; 

     // Set font properties 
     SetFontProperties(ChildControl, Name, Size, Styles); 
    end; 
    end; 
end; 

si può quindi cambiare i font per tutti i controlli all'interno di un modulo utilizzando in questo modo:

SetFontProperties(Self, 'Courier', 14, []); 

la funzione quindi impostare le proprietà dei font della forma e le proprietà dei font di tutti i controlli figlio sulla forma, compresi i controlli nidificati TPanels o altri controlli contenitore.

Tuttavia, sono d'accordo con te sul fatto che è un modo quasi disordinato di farlo.

+0

Non è ideale la codifica di una cosa del genere, ma la tua risposta è utile non di meno :) –

+3

Sfortunatamente non tutte le proprietà dei font sono denominate 'Font' ... –

+0

@MarjanVenema Era solo un esempio. Se si dispone di componenti non VCL che implementano altri nomi di proprietà dei font, è necessario espandere la funzione con tali nomi di proprietà, ovviamente. Tuttavia il punto principale di questa discussione è il punto menzionato da Warren P nel commento sopra: Solitamente non è fattibile alterare il runtime delle proprietà dei font come questo, perché altera allineamenti, introduce font-clipping, ecc. – Elling

2

La vera chiave, come è stato menzionato, è di assicurare che tutti i moduli si discostino dal proprio modulo di base dell'applicazione.

Quindi, è possibile visualizzare ogni modulo e pulsante, ecc, e rivedere le proprietà, dove qualsiasi proprietà di carattere modificato deve essere visualizzata in grassetto ed è facilmente identificabile. La maggior parte delle proprietà ha una scelta di menu "Ripristina ereditato". Questo dovrebbe essenzialmente annullare qualsiasi selezione precedente, senza dover andare alla versione di testo per l'editing. (Anche se probabilmente fa esattamente questo, cancellando qualsiasi inserimento di testo risultante dalle precedenti impostazioni dei font).

Vorrei assolutamente risolvere ogni modulo una volta anziché lasciarlo definito in modo errato e aggiungere altro codice per risolverlo in fase di runtime. Questo cambiamento ti lascerà un problema peggiore se in seguito deciderai di fare qualcosa di diverso.

+0

Grazie per i suggerimenti. –

Problemi correlati