Tsynedit per evidenziare solo alcune parole del testo
(1/1)
darione:
Salve a tutti, avrei questo quesito.
Dovrei visualizzare in un memo un brano ed evidenziare di rosso solo alcune parole particolari.
Ho provato con TSynEdit ma non ho capito come fare, non riesco a trovare una chiara documentazione on line ... si vede che è un componente assai complesso e flessibile, ma un semplice tutorial su come evidenziare solamente delle proprie parole io non l'ho trovato. Magari sono imbranato io ... :-(
Qualcuno può indicarmi come fare? Grazie mille, Darione :-)
var WrkHighlighter:TSynPositionHighlighter; MyAttr, MyAttrBatComm, MyAttrBatLabel, MyAttrBatRigheEseg:TtkTokenKind;
implementation uses BonMarUtils;
procedure TrovaInSynEdit(var WrkSynEdit: TSynEdit; StrDaCerc:String; VFPartiDaInizio, VFIgnoraMinMai:Boolean); var WrkOptions: TSynSearchOptions; begin WrkOptions:=[]; if VFPartiDaInizio then begin WrkOptions:=WrkOptions + [ssoEntireScope]; end else begin WrkOptions:=WrkOptions + [ssoFindContinue]; end;
if (not VFIgnoraMinMai) then begin WrkOptions:=WrkOptions + [ssoMatchCase]; end;
if (WrkSynedit.SearchReplace(StrDaCerc, '', WrkOptions) = 0) then begin EmettiErrore(28); end; end;
procedure EvidenziaInSyn(NumRiga:Integer; St, StrDaCerc: String); var Posx, LenStrDaCerc, UltChrDaEvid:Integer; WrkLoop:Integer; begin //A volte il programma andava in loop. //Questa variabile serve per verificare se riesco ad evitarlo WrkLoop:=0;
//Valorizzo la stringa che dovrò evidenziare e la sua lunghezza. //Se non si vuole evidenziare niente di specifico, evidenzio tutta la riga if (StrDaCerc = '') then begin StrDaCerc:=St; end; StrDaCerc:=UpperCase(StrDaCerc); LenStrDaCerc:=Length(StrDaCerc);
//La stringa che devo cercare può essere contenuta più volte. //Faccio in modo di evidenziarle tutte Posx:=RPos(StrDaCerc, UpperCase(St)); while (Posx > 0) and (WrkLoop < 100) do begin //Incremento il contatore per verifica loop WrkLoop:=WrkLoop + 1;
//Se mi capita un probabile loop, provo a modificare il colore di sfondo. //In questo modo magari iesco a capire dov'è il problema if (WrkLoop > 50) then begin WrkHighlighter.TextAttri.Background:=clRed; end;
//Per ogni riga devo definire che: //- Dalla posizione iniziale, fino al carattere prima della stringa che sto cercando, non va fatta nessuna formattazione //- Dalla posizione in cui è stata trovata la stringa va fatta la formattazione //- Dalla posizione successiva alla fine della stringa da cercare non serve nessuna formattazione UltChrDaEvid:=Posx + LenStrDaCerc - 1;
if (UltChrDaEvid < Length(St)) then begin //Se la stringa da cercare è proprio in fondo, questa parte non va eseguita, //altrimenti l'istruzione successiva la annullerebbe !!! WrkHighlighter.AddToken(NumRiga, Length(St), tkText); end; WrkHighlighter.AddToken(NumRiga, UltChrDaEvid, MyAttr); WrkHighlighter.AddToken(NumRiga, Posx - 1, tkText);
//Cancello dalla stringa la parte relativa all'occorrenza che ho appena //evidenziato e verifico se ce ne sono altre System.Delete(St, Posx, Length(St)); Posx:=RPos(StrDaCerc, UpperCase(St)); end; end;
procedure InizializzaHighLighter(var WrkSynEdit: TSynEdit; ColoreCarattere, ColoreSfondo:TColor); begin WrkHighlighter:=TSynPositionHighlighter.Create(nil); WrkHighlighter.Enabled:=False; WrkSynEdit.Highlighter:=WrkHighlighter;
//Definisco la modalità di evidenziazione MyAttr:=WrkHighlighter.CreateTokenID('MyAttr', ColoreCarattere, ColoreSfondo, [fsBold]); end;
procedure ClearHighLighter; begin WrkHighlighter.Enabled:=False; WrkHighlighter.ClearAllTokens; end;
procedure AttivaHighLighter; begin WrkHighlighter.Enabled:=True; end;
procedure EvidenziaInSynPerBat(var WrkSynEdit:TSynEdit); var NumRiga:Integer; WrkSt:String; begin //Creo il nuovo HighLighter con le impostazioni specifiche per i files BAT WrkHighlighter:=TSynPositionHighlighter.Create(nil); WrkHighlighter.Enabled:=False; WrkSynEdit.Highlighter:=WrkHighlighter;
//Righe che verranno eseguite: le faccio nel colore di default, ma in grassetto + italico MyAttrBatRigheEseg:=WrkHighlighter.CreateTokenID('BatExe', WrkSynEdit.Font.Color, WrkSynEdit.Color, [fsBold, fsItalic]);
//Ora esamino riga per riga, per vedere se la devo colorare o no for NumRiga:=0 to WrkSynEdit.Lines.Count - 1 do begin //Valorizzo la stringa nell'output WrkSt:=LowerCase(Trim(WrkSynEdit.Lines[NumRiga]));
//Commento if (Copy(WrkSt, 1, 2) = '::') or (Copy(WrkSt, 1, 4) = 'rem ') then begin WrkHighlighter.AddToken(NumRiga, Length(WrkSynEdit.Lines[NumRiga]), MyAttrBatComm); end else begin //Label per GoTo if (Copy(WrkSt, 1, 1) = ':') then begin WrkHighlighter.AddToken(NumRiga, Length(WrkSynEdit.Lines[NumRiga]), MyAttrBatLabel); end else begin //Tutte le altre righe, quindi quelle che verranno effettivamente eseguite, //le faccio in grassetto + italico WrkHighlighter.AddToken(NumRiga, Length(WrkSynEdit.Lines[NumRiga]), MyAttrBatRigheEseg); end; end; end;
//Attivo l'highlighter AttivaHighLighter; end;
finalization FreeAndNil(WrkHighlighter);
end.
--- Termina codice ---
Probabilmente ti darà degli errori dovuti alla dipendenza con "BonMarUtils", che non posso condividere, ma togliendo la sua uses e verificando gli errori, dovresti comunque ricavarne qualcosa di utile.
Poi, ad esempio, nella OnChange della tua TSynEdit, puoi mettere questo:
--- Codice: --- procedure TForm1.MemoCmdDosPrimaChange(Sender: TObject); begin //Lancio la procedura che i occupa di colorare le righe in base al loro //contenuto EvidenziaInSynPerBat(MemoCmdDosPrima); end;