IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants VCL Delphi Discussion :

Utilisation d'un TStringGrid dans une DLL


Sujet :

Composants VCL Delphi

  1. #21
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par KlausGunther Voir le message
    J'ai pris un peu de temps, car les essais n'étaient pas évidents. Certes, dans le petit modèle que j'avais envoyé, j'arrivais à appliquer cette méthode. Donc, elle est valide. Cependant, en contexte de production, la situation est beaucoup plus complexe, et je n'ai pas réussi à adapter cette technique à la situation réelle, tout simplement parce que le compteur de référence pour les chaînes de caractères en question est très variable, au moment de l'appel de la fonction. Je ne peux donc pas me baser du tout sur ce nombre, même en supposant un décalage de 4, 5 ou 6...
    mais peu importe que le compteur soit 4, 5 ou 6....le but de la StringList c'est de garder au moins une main sur la chaîne en permanence pour que l'EXE ne chercher pas à la libérer. Que la chaîne soit référencée par l'exe ou par la dll elle-même on s'en fiche à la rigueur, elle peux rester dans la StringList même si l'exe ne l'utilise plus...quand la dll ne l'utilisera plus non plus, le prochaine appel à WriteStringGrid pourra faire le ménage: quand la StringGrid est le dernier endroit qui exploite encore la chaîne il est temps de la supprimer.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  2. #22
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 164
    Points
    164
    Billets dans le blog
    1
    Par défaut
    Donc, si j'ai bien compris, je dois parcourir périodiquement la StringList et chercher les éléments dont le compteur de référence est tombé à 1 (référencé par la StringList). Et je peux supprimer ceux-là, si j'ai bien compris.

  3. #23
    Membre habitué

    Homme Profil pro
    Informaticien retraité
    Inscrit en
    Mars 2010
    Messages
    287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2010
    Messages : 287
    Points : 164
    Points
    164
    Billets dans le blog
    1
    Par défaut
    Bon, je suis parti ce cette hypothèse, et j'ai remanié mon code en créant une TSTringList interne à la DLL, dans laquelle je dépose toutes les chaînes que le place dans la TSTringGrid, puis je charge cellule du TStingGrid en affectant la chaîne à la propriété CELLS. J'ai étendu ma fonction pour qu'elle agisse d'un coup sur un rectangle de cellules, indiqué par deux paires de coordonnées. Mes données sont transmises sous forme d'une seule chaîne de caractères, dans laquelle les cellules sont séparées les unes des autres par un caractère de séparation qui est défini à part, dans une variable globale. Voici ce que ça donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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;
    Chaque fois, avant de sortir de la fonction, je parcours la TSTringList interne pour éliminer les éléments qui ne servent plus (compteur de référence <=2). Et j'ai vérifié: la liste se purge bien, ma fonction est rapide et iol n'y a aucun crash ! Donc, ta solution est la bonne - opérationnelle, rapide, fiable. J'ai éliminé mon subterfuge par la simulation de frappes de touches pour adopter pleinement cette solution, et je te remercie sincèrement de ton aide et de ta patience !

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. [Débutant] Utiliser les fonctions contenues dans une DLL écrite en VB.NET
    Par vg-matrix dans le forum VB.NET
    Réponses: 1
    Dernier message: 26/11/2012, 23h35
  2. Utilisation d'un Thread dans une DLL
    Par colorid dans le forum Langage
    Réponses: 7
    Dernier message: 14/03/2009, 11h05
  3. Utilisation d'un activex dans une dll mfc
    Par regdobey dans le forum MFC
    Réponses: 2
    Dernier message: 20/11/2008, 13h19
  4. [COM] utiliser la librairie standard dans une dll COM
    Par kacedda dans le forum Visual C++
    Réponses: 5
    Dernier message: 13/03/2008, 14h57
  5. TForm dans une DLL avec utilisation d'Interface
    Par guedelmalin dans le forum Langage
    Réponses: 13
    Dernier message: 17/06/2005, 11h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo