1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| // fonction donnée par Paul Toth (forum de developpez.com)
function StringRefCount(const s: string): Integer;
var
p: PInteger;
begin
p := Pointer(s); // adresse su string à analyser
if p = nil then // string vide ?
Result := 0 // alors aucune référence !
else begin // string non vide ?
Dec(p, 2); // pointer sur le compteur de référence: 2 * 4 octets par Integer = 8 octets
Result := p^; // et retourner cette valeur
end;
end;
// écrire un rectagle de cellules, à partir d'une chaîne dont les cellules sont séparées par SG_cell_separator
function WriteGridCell(grid: integer; x1,y1,x2,y2: integer; xs: pstring):integer; stdcall; export;
var
k, x, y: integer;
ps: PChar; // pointeur vers la fin du texte global à copier
ps1: PChar; // pointeur vers le début du texte à copier
ps2: PChar; // pointeur vers la fin d'une donnée individuelle
temp: string;
begin
result := -1; // la valeur de retour de -1 est signal d'erreur
try
if TControl(grid).ClassName<>'TStringGrid' then exit; // objet non créé ?
ps := pointer(pinteger(xs)^); // pointer dans le texte transmis
ps1 := ps; // et garder une copie
while ps^<>#0 do inc(ps); // chercher la fin du texte à transmettre
if ps=ps1 then exit; // chaîne vide ?
x := x1;
y := y1;
repeat // boucle sur tous les éléments
ps2 := ps1;
while ps2<ps do begin // chercher la fin des données pour une cellule
if ps2^=SG_cell_separator then break; // séparateur de cellule ?
inc(ps2);
end;
SetLength(temp,ps2-ps1); // créer un string de la bonne longueur
for k:=0 to (ps2-ps1-1) do begin // copier les données
temp[k+1] := ps1^;
inc(ps1);
end;
if not assigned(SG_helpSL) then SG_helpSL := TStringList.Create; // créer la stringlist si necessaire
SG_helpSL.Add(temp); // y mémoriser les données
TStringGrid(grid).Cells[x,y] := temp;
x := x + 1;
if x>x2 then begin
x := x1;
y := y + 1;
end;
ps1 := ps2 + length(SG_cell_separator); // passer au-delà de l'élément traité
until ps<=ps1; // fin boucle sur les éléments
for k:=SG_helpSL.Count-1 downto 0 do begin // boucle pour purger la stringlist interne
temp := SG_helpSL.Strings[k]; // copier un élément
if StringRefCount(temp)<=2 then SG_helpSL.Delete(k); // plus référencé que par la stringlist et cette variable ?
end;
result := 0; // la valeur de retour de 0 est signal de terminaison correcte.
except
end;
end; |