Newsgroup: it.comp.lang.delphi
Titolo: Larghezza testo

Ciao a tutti,
  ho qualche difficolta' a calcolare la larghezza del testo nelle diverse 
risoluzioni video.
 
fino ad oggi ho usato questa funzione
 
function GetTextWidth(const Text: string; const Font: TFont): Integer;
var
  Canvas: TCanvas;
begin
  Canvas := TCanvas.Create;
  try
    Canvas.Handle := GetDC(0);
    try
      Canvas.Font.Assign(Font);
      Result := Canvas.TextWidth(Text);
    finally
      ReleaseDC(0, Canvas.Handle);
    end;
  finally
    Canvas.Free;
  end;
end;
 
Il problema che ho e' che questa funzione, indipendentemente dalla 
risoluzione video, ritorna sempre lo stesso valore.
 
Per esempio se la stringa passata e' CIAO e il font e' times new Roman size 
12 e la modalita' video e'  1920x1080, la funzione ritorna (per esempio) 58.
 
Se pero' cambio la modalita' in 1024 x 768 e cambio la grandezza del font in 
10, ebbene questa funzione ritorna sempre 58.
 
Ho provato a girovagare sul web ed utilizzare altre strategie 
(fondamentalmente similari a questa), ma il risultato delle diverse 
strategie e' quello che il valore restituito e' sempre 58.
 
Qualche idea ??
 
Grazie
 
Ciao
 
Daniele 
 

Ho trovato un esempio qui 
http://stackoverflow.com/questions/9326675/accurately-compute-text-widths-in-metric-units
 
 
Altre info le trovi qui 
http://www.devsuperpage.com/search/Articles.asp?ArtID=352393
 
 
Ciao

Ciao,
  grazie per la risposta.....
 
Ci ero gia' passato ma il problema persiste !!!!
 
Cerchero' di capire meglio !!!
 
Grazie
 
Daniele

> Ho provato a girovagare sul web ed utilizzare altre strategie 
 
Quali?
 
A.

Ciao a tutti,
   ho risolto il problema della larghezza del testo nelle diverse modalita' 
video.
 
In effetti le diverse soluzioni trovate i rete su come calcolare la 
larghezza del testo vanno tutte bene, c'e' chi usa il canvans della form, 
chi (come me) usa il canvas di una bitmap ecc...
 
L'aspetto curioso del problema e' che il calcolo della larghezza del testo, 
nel mio caso e non so spiegarmi il perche' (quindi se qualcuno puo' farlo me 
lo puo' spiegare), non funziona se messo nella form create.
Ovvero per le diverse risoluzioni video la funzione, riportata nel primo 
messaggio della discussione, ritorna sempre lo stesso valore (pe esempio 
54).
La stessa procedura chiamata, invece, nella form show da valori diversi.
 
Quindi il ricalcolo della larghezza dei testi, quindi della form e degli 
altri controlli, la eseguo nell'evento onshow.
 
Grazie a tutti per l'interesse.
 
ciao
 
Daniele
 

"Daniele"  ha scritto nel messaggio news:na411e$hng$1...@gioia.aioe.org...
Ciao a tutti,
   ho risolto il problema della larghezza del testo nelle diverse modalita'
video.
---
Mi interessa, cercavo anch'io una soluzione. Non ci mostreresti quella che 
funziona ? 
 
 
---
Questa e-mail è stata controllata per individuare virus con Avast antivirus.
https://www.avast.com/antivirus
 
 

 La stessa procedura chiamata, invece, nella form show da valori diversi.
 
Una differenza tra i due momenti e' che nell'evento OnCreate non ha ancora
ottenuto dal sistema un HWND per la finestra mentre in OnShow si.
 
Detto questo, non so dire come questa possa influenzare il tuo codice, 
visto che usa GetDC(0) quindi chiede un handle per lo schermo e non per la 
finestra corrente... 
 
ciao
Giacomo
 
 
 

 finestra corrente...
 
Questa invece e' la perplessita' !
Onestamente non me lo so spiegare.
 
Grazie per l'attenzione.
 
Ciao
 
Daniele
 
 

 funziona ?
 
Tieniti forte .... e' una soluzione molto artigianale ..... piu' che 
artigianale e' da cantinaro ..... !!!
 
Ho provato a cercare qualche soluzione "elegante", ma senza risultati 
apprezzabili.
L'unica vera strada verso un real mutili screen resolution la trovi qui
 
http://delphi.about.com/od/standards/a/aa030700a.htm
 
 
Un altro approccio lo trovi  qui
 
http://users.atw.hu/delphicikk/listaz.php?id=2224&oldal=17
 
 
In definitiva queste due soluzioni prevedono l'uso massiccio di scaledby(), 
impostare i dpi a 120 ed usare font true type ....  e sperare che tutto vada 
bene !.
 
Una terza via e' quella che ragiona al contrario, ovvero si progetta tutto 
per una risoluzione video bassissima (800x600) e poi inserisci un bel 
componente (Formsizinig che trovi qui 
http://delphi.about.com/library/bluc/ucvcl.htm
, installato e funzionante in 
XE2 e 10 seattle) che riadatta tutto quello che c'e' nel form alla nuova 
risoluzione.
Il neo e' che nella 800 x 600 non ci sta quasi niente ed e' un casino con i 
nuovi ide.
 
Infine c'e' la soluzione che ho adottato, un po laboriosa e (onestamente) 
criticabile.
Questa soluzione deriva da un'osservazione di alcuni programmi commerciali 
che mettono a disposizione SOLO due risoluzioni video ( 1024x768 e 1920x1080 
che casualmente sono quelle che utilizzo) , se le risoluzioni sono diverse 
da queste, tali software NON partono (il mio si).
Quindi senza troppi convenevoli ho una variabile globale boolean (che si 
potrebbe anche eliminare) chiamata Use1024x768.
 
  TForm1 = class(TForm)
    { Private declarations }
 
    procedure Imposta1024x768;
 
  public
    { Public declarations }
  end;
 
Nell'evento oncreate della form principale
 
if (Screen.Width=1024) and (Screen.Height=768) then Use1024x768:=True
else
Use1024x768:=False;
 
Nell'evento onshow
 
procedure TForm1.FormShow(Sender: TObject);
Var WD : Integer;
begin
   If Use1024x768 then Imposta1024x768;
end;
 
dove
 
Procedure TForm1.Imposta1024x768;
begin
    // Imposti i controlli controllando altezza e larghezza delle label 
ecc...
End;
 
Per il controllo della larghezza/altezza del testo
 
function GetTextSize(St: string; Font: TFont; IsHeigth: Boolean): Integer;
var
  n, i: Integer;
  canvas: TCanvas;
begin
  Result:=0;
  if st='' then Exit;
  canvas := TCanvas.Create;
  try
    canvas.Handle := CreateDC('DISPLAY', nil, nil, nil);
    try
      Canvas.Font := Font;
      Canvas.Font.PixelsPerInch := GetDeviceCaps(canvas.Handle, LOGPIXELSY);
      If IsHeigth then n := Canvas.TextExtent(St).cx
      else
      n := Canvas.TextExtent(St).cy;
      Result := n;
    finally
      DeleteDC(canvas.Handle);
      canvas.Handle := 0;
    end;
  finally
    canvas.free;
  end;
end;
 
Riassumendo, la mia applicazione e' nativa per 1920x1080, se e' 1024x768 
riadatto ... altrimenti se X e' compreso tra 1024 e 1440 riadatto comunque, 
per risoluzioni maggiori di 1440 tenfo la 1920.
 
Buon fine settimana
 
ciao
 
Daniele