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 :

Undo et Tstringgrid


Sujet :

Composants VCL Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Inscrit en
    Novembre 2002
    Messages
    815
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 815
    Par défaut Undo et Tstringgrid
    Bonjours a tous je suis à la recherche d'idées ou de subjections pour faire un tampon d'annulation ( undo ) sur un Tstringgrid !!
    Merci d'avance

  2. #2
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Tu cherches à annuler quoi, exactement ? Des saisies utilisateur "uniquement", ou tu peux avoir des opérations automatiques dessus ?

    J'avais utilisé un composant TStringGrid à un moment, et chaque modification de cellule devait être "vue" : j'avais utilisé les évènements suivants :
    - OnGetEditMask,
    - OnGetEditText,
    - OnSelectCell.

    Après, le principe est assez bête : lors de la sélection d'une cellule, mémoriser son contenu ainsi que ses coordonnées. Sur sortie du composant/cellule, comparer la valeur mémorisée avec la valeur actuelle.
    Si la cellule a changé, alors stocker sur une pile (LIFO, donc) les coordonnées de la cellule et son ancienne valeur.

    L'annulation se fait en dépilant le dernier élément du buffer d'annulation : on récupère les coordonnées de cellule, on remplace "bourrin" par la valeur sauvegardée.

    RAS/TVB ?
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  3. #3
    Membre éclairé

    Inscrit en
    Novembre 2002
    Messages
    815
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 815
    Par défaut
    Oui j'avais aussi penser a faire comme cela !
    mais j'aurai aimer avoir si il y avait pas plus ' propre ' .
    Pour mes "retours en arriere" je dois gerer la saisie , mais aussi les copier,coller, couper , sup... des drag drop.... en fait toutes modifications intervenant sur le tabeau.

    Je vais tenter la methode donc tu me parle en esperant quelle ne soit pas trop lourde , ou lente quand le decale mes elementd de ma pile qui peuvent parfois etre important !

    merci

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par petitcoucou31
    Oui j'avais aussi penser a faire comme cela !
    mais j'aurai aimer avoir si il y avait pas plus ' propre ' .
    A ma connaissance, non. C'est le principe de base d'un undo "pas trop gourmand", car sinon, la méthode de buffle consistant à sérialiser (dans un TStream servant de buffer d'annulation) l'intégralité du composant à chaque action de modification peut s'appliquer... Mais je ne te dis pas la taille mémoire consommée !!!

    Citation Envoyé par petitcoucou31
    Pour mes "retours en arriere" je dois gerer la saisie , mais aussi les copier,coller, couper , sup... des drag drop.... en fait toutes modifications intervenant sur le tabeau.
    Un "Coller" est vu comme si c'était une modification manuelle : donc, tu les verras. Pareil pour les suppressions et les drag & drop (du moins, les D&D de texte, pour les composants eux-même, c'est un peu différent).
    Pour les "Copier", j'avoue ne pas comprendre : pourquoi monitorer ça, étant donné que ça ne modifie pas le composant ??

    Si jamais ça marche "mal", il faut et il suffit de stocker, en plus des 3 éléments que je t'ai indiqués plus haut, le "type" de modification effectuée en fonction du gestionnaire d'évènement qui a "vu" la modif (j'sais pas si je suis super clair, là...:-P)

    Citation Envoyé par petitcoucou31
    Je vais tenter la methode donc tu me parle en esperant quelle ne soit pas trop lourde , ou lente quand le decale mes elementd de ma pile qui peuvent parfois etre important !
    Gniii ???? Non, c'est une pile, il n'y a pas de décalages à faire, voyons !!
    Pour la lenteur, il suffit d'implémenter la pile proprement, en n'empilant que le pointeur vers une structure d'annulation qui sera créée par le gestionnaire d'évènements "détecteur". C'est très rapide à faire, mais pense à bien allouer la mémoire (utilise GetMem, ou un tas privé Windows si tu sais faire).
    Pour la consommation mémoire (je pense que c'est ça que tu veux dire par "lourdeur"), une solution courante est de refuser d'empiler deux modifications de même nature, consécutives et sur la même cellule : c'est un principe courant, qui ne choquera personne (vérifie sur Excel ou Word, tu comprendras ce que je veux dire).

    Ta structure d'annulation "maximale" devrait contenir :
    - Un TPoint pour les coordonnées,
    - Un type de modification (énumération par exemple),
    - Un pointeur non-typé vers les données d'origine si ce ne sont pas toujours des String.

    Ca, c'est pour un TStringGrid. Si tu dois monitorer plus de composants, c'est légèrement plus complexe, mais largement faisable quand même et sans se casser la tête : tu empiles en même temps un Sender, et tu n'as plus qu'à implémenter des méthodes d'annulation pour chaque type de composant présent sur tes fiches. Ca demande par contre à utiliser intensivement les enregistrement à partie variable (les Record avec des "case" dedans).

    Citation Envoyé par petitcoucou31
    merci
    De rien.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  5. #5
    Membre éclairé

    Inscrit en
    Novembre 2002
    Messages
    815
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 815
    Par défaut
    OUI !! tu as entierement raison pour le "copier" çà sert a rien et comme tu dis je veux juste stocker ce qui modifie le composant !

    Par contre pour la pile : je ne te suis pas trop !!

    M oi j'allais creer une "pseudo pile " avec un array dymanique , un Stringlist ou un reccord ( je ne sais pas encore ) et limiter le nombre de undo a 100 pour ne pas etre gourmand en ressource.
    J"allais donc aussi gerer cette pile , lorsque j'aurai ete au max des "undo" possible j'allais faire un decalage ( supprimer le plus ancien pour laisser de la place au dernier ..)
    Mais vu la taille des infos a sauvegarder peut etre que la limitation est inutile , donc la gestion aussi ..surtout que je ne compte pas faire de "undo" pendant la saisie de la cellule , mais sur les modification globale des cellules .



    bon je vais tenter cela merci

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par petitcoucou31
    OUI !! tu as entierement raison pour le "copier" çà sert a rien et comme tu dis je veux juste stocker ce qui modifie le composant !
    Bravo, tu viens de comprendre 99% de la "complexité" d'un undo... Comme souvent, on se pose de "faux problèmes", tu ne trouves pas ? ;-)

    Citation Envoyé par petitcoucou31
    Par contre pour la pile : je ne te suis pas trop !!
    C'est la gestion d'une pile "vraie" qui te pose problème ?

    Citation Envoyé par petitcoucou31
    M oi j'allais creer une "pseudo pile " avec un array dymanique , un Stringlist ou un reccord ( je ne sais pas encore ) et limiter le nombre de undo a 100 pour ne pas etre gourmand en ressource.
    En fait, tu as deux manières "efficaces" de coder une pile : par tableau, ou par liste chaînée. Le tableau peut être dynamique (pas de stack overflow possible), ou fixe (risque de stack overflow au bout d'un moment). Je considère que tu ne veux pas de limite, donc tableau dynamique.

    Citation Envoyé par petitcoucou31
    J"allais donc aussi gerer cette pile , lorsque j'aurai ete au max des "undo" possible j'allais faire un decalage ( supprimer le plus ancien pour laisser de la place au dernier ..)
    Ben justement, ce n'est pas nécessaire avec une pile : je te rappelle que c'est une gestion LIFO (Last In, First Out). En clair :
    - En tableau dynamique, tu insères en fin de tableau, et tu retires en fin de tableau aussi. Le "compactage" si tu limites la taille ne décale que des pointeurs (=> faire un MoveMemory est le plus rapide).
    - En liste chaînée, tu insères en tête et tu retires en tête aussi => pour "compacter", il te suffit de ... couper les derniers éléments ! ;-)

    Citation Envoyé par petitcoucou31
    Mais vu la taille des infos a sauvegarder peut etre que la limitation est inutile , donc la gestion aussi ..surtout que je ne compte pas faire de "undo" pendant la saisie de la cellule , mais sur les modification globale des cellules .
    Effectivement, la limitation n'est pas réellement nécessaire : la quantité de RAM des PC actuels n'est plus un facteur aussi limitant qu'avant.
    Je peux aussi te proposer une variante, quasi illimitée en capacité :
    - Implémenter une liste chaînée d'undo en RAM, limitée à (par exemple) une dizaine d'undo, pas plus.
    - Lorsque tu "coupes" ta chaîne, tu vas en fait les écrire dans un fichier temporaire, sur le disque dur au lieu de simplement libérer la RAM. Le fichier, lui, est organisé comme un tableau dynamique (=> pas besoin de compactage en plus, on considère sa taille "illimitée").
    Avec ce principe, tu peux gérer un million de niveaux d'annulation si ça peut te faire plaisir : ça va te prendre une centaine de ko de RAM au maximum, et peut-être une vingtaine de mégas sur le dur (remplis au fur et à mesure, ça n'impacte même pas les perfs).

    Cool, non ? :-D
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  7. #7
    Membre éclairé

    Inscrit en
    Novembre 2002
    Messages
    815
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 815
    Par défaut
    OUi je suis dessus en ce moment ! donc cool je te le dirai plus tard

    par contre juste un detail , vu que je gere en meme tant que le undo le "redo" ! on ne peux pas effacer de suite les derniers elements restaurés.
    Donc pas tout a fait une vrai pile 'lifo' ou l'element actif serai toujours le dernier du tableau . Car je fois conserver les elements pour justement le "redo" .
    Je doit donc gerer un indice tableau sur le undo qui vient d'etre restauré
    ( en remontant dans le tableau ) et effacer les element superieur au undo courant quand les action sur le undo sont terminer ( j'espere etre clair ! !!lol

    Par contre sur un tableau limité a 10 undo par exemple , le decale reste a faire ! quand je suis en fin de tableau , je stocke toujours mon dernier element saisie en fin de tableau , je dois donc decaler tout les elements vers le bas pour faire la place a la fin du tableau .

    Merci pour tes reponses qui me disent que je suis sur la bonne voix .

  8. #8
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par petitcoucou31
    OUi je suis dessus en ce moment ! donc cool je te le dirai plus tard
    Ca roule.

    Citation Envoyé par petitcoucou31
    par contre juste un detail , vu que je gere en meme tant que le undo le "redo" ! on ne peux pas effacer de suite les derniers elements restaurés.
    Ca, c'est ta faute : relis ton premier post, tu parlais seulement d'un "undo"... Ca mérite le fouet, ça... ;-)

    Citation Envoyé par petitcoucou31
    Donc pas tout a fait une vrai pile 'lifo' ou l'element actif serai toujours le dernier du tableau . Car je fois conserver les elements pour justement le "redo" .
    En effet, ce n'est pas une "véritable" pile, car tu vas devoir gérer un pointeur de sommet de pile en plus de sa taille globale... Comme une pile de processeur, en fait !

    Citation Envoyé par petitcoucou31
    Je doit donc gerer un indice tableau sur le undo qui vient d'etre restauré ( en remontant dans le tableau ) et effacer les element superieur au undo courant quand les action sur le undo sont terminer ( j'espere etre clair ! !!lol
    C'est bien ça : la taille de la pile, ne serait-ce que pour savoir s'il y a (ou pas !) des undos/redos à faire, et le pointeur courant. Cependant, je te rappelle qu'en cas de modifications, les "redos" en cours doivent être détruits !

    Citation Envoyé par petitcoucou31
    Par contre sur un tableau limité a 10 undo par exemple , le decale reste a faire ! quand je suis en fin de tableau , je stocke toujours mon dernier element saisie en fin de tableau , je dois donc decaler tout les elements vers le bas pour faire la place a la fin du tableau .
    Bon, si tu tiens absolument à faire un tableau comme ça, la solution miracle passe par un buffer semi-circulaire (ça chie à l'oreille, hein ? )
    J'explique : on utilise les propriétés des nombres binaires pour accélérer le traitement, en prenant une taille de tableau qui soit un multiple de deux. Dans ton cas, si tu en veux au moins 10, ça sera 15.
    On utilise une numérotation à base zéro : tu vas donc de 0 à 15.
    Tu mémorises 3 éléments : premier, dernier, et courant. Pour ajouter un élément au tableau, tu l'ajoutes en fin, tu incrémentes et tu appliques un AND binaire dessus (valeur : indice maximal).
    Ca donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Indice:=(Indice+1) And 15;
    Ca va te faire une opération de type modulo, mais extrêmement rapide.
    Ensuite, il te suffit de vérifier la cohérence de tes indices, et donc penser à incrémenter l'indice du premier (= "décalage") si le dernier vient "buter" sur le premier, justement.
    En gros : au début, c'est un tableau "normal", mais une fois plein, ça devient une file circulaire.
    Si tu sais lire le C, j'ai en stock un code de gestion "Page précédente"/"Page suivante" d'un navigateur hypertexte, qui marche sur le principe des buffers semi-circulaires.

    J'ai été suffisamment clair, ou tu es en train de prendre des tranquillisants ?

    Citation Envoyé par petitcoucou31
    Merci pour tes reponses qui me disent que je suis sur la bonne voix .
    De nada.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  9. #9
    Membre éclairé

    Inscrit en
    Novembre 2002
    Messages
    815
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 815
    Par défaut
    ça va j'en suis pas encore au transquillisant lol on est cool dans mon pays ! merci a toi je pense m'en sortir pour la "pile " !
    Oui oui de ma faute pour le redo !!
    Pour l'instant j'en suis a determiner toutes les actions effectuer sur mon stringGrid ou je dois "sauver" les cellules dans ma liste de undo .
    - cellule qui change entre son activation et la sortie de la cellule( je gere pas le undo en mode edition de la cellule.
    - les supression , insertion ( simple et multiselection )...

    merci a toi !

  10. #10
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par petitcoucou31
    ça va j'en suis pas encore au transquillisant lol on est cool dans mon pays !
    Pas vrai : j'te signale qu'on est de la même ville, et j'suis pas un mec cool...

    Citation Envoyé par petitcoucou31
    Oui oui de ma faute pour le redo !!
    Pour l'instant j'en suis a determiner toutes les actions effectuer sur mon stringGrid ou je dois "sauver" les cellules dans ma liste de undo .
    - cellule qui change entre son activation et la sortie de la cellule( je gere pas le undo en mode edition de la cellule.
    - les supression , insertion ( simple et multiselection )...
    Effectivement, recenser les actions "modifiantes" est un prérequis !!
    Bon courage pour la suite, n'hésites pas à reposter.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  11. #11
    Membre éclairé

    Inscrit en
    Novembre 2002
    Messages
    815
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 815
    Par défaut TstringGrid ..
    Bonjour tout le monde ..
    Je voudrais savoir si il existe une methode pour savoir , Quand on rentre dans une cellule et quand on en la quitte !
    l'equivalent des evements " OnEnter" et "OnExit" mais pas sur le composant , mais sur la cellule !

    merci d'avance .
    _________________
    Sujets fusionnés par Sub0

  12. #12
    Expert confirmé

    Avatar de Nono40
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2002
    Messages
    8 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 8 640
    Par défaut
    Pour l'entrée tu as OnSelectCell, pour la sortie il faudrait mixer avec le OnSelectCell d'une autre cellule et le OnExit de la grille.
    Delphi :
    La F.A.Q. , 877 réponses à vos questions !
    264 sources à consulter/télécharger !

  13. #13
    Membre éclairé

    Inscrit en
    Novembre 2002
    Messages
    815
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 815
    Par défaut
    C'est deja cela que je fais ! je voulais savoir si il existait une autre solution !
    le but de la manip etant de sauver le contenu de la cellule quand j'y rentre et quand j'en sort . pour voir si il y a eux des moditifications et gerer un undo...
    Je vais essayer de voir si je peux pas gerer cela sans le "ondrawcel" , qui me permetrait aussi de gerer les copier. coller , ou les insersion dans mon tableau sans passer par le "OnSelectCell" .

    On idée est elle absurde ?

  14. #14
    Membre Expert Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Par défaut
    oui , en surcharge winproc de stringgrid pour détecté la création de zone d'edition
    puis en surcharge le winproc de cette zone de texte

    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
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
     
    unit Les_Aveces;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      StdCtrls, Grids, ExtCtrls, Spin, ComCtrls,Modul2, Buttons, Menus;
     
    type
      TFichAvences = class(TForm)
        Grid1: TStringGrid;
        procedure FormCreate(Sender: TObject);
        procedure Grid1DrawCell(Sender: TObject; ACol, ARow: Integer;
          Rect: TRect; State: TGridDrawState);
      private
        { Déclarations privées }
     
        Winda:TWndMethod;
        Procedure Monmessage(var msg:TMessage);
        Procedure MyProcedure(var msg:TMessage);
      public
        { Déclarations publiques }
      end;
     
    var
      FichAvences: TFichAvences;
    implementation
     
     
    {$R *.DFM}
     
    procedure TFichAvences.FormCreate(Sender: TObject);
    begin
         Winda:=grid1.WindowProc ;
         grid1.WindowProc :=monmessage;
    end;
    procedure TFichAvences.Grid1DrawCell(Sender: TObject; ACol, ARow: Integer;
      Rect: TRect; State: TGridDrawState);
    var
         x,y:integer;
         s:string;
         h:TSize;
    begin
         s:=grid1.cells[acol,arow];
         h:=Grid1.Canvas.TextExtent(s);
         if arow=0 then
           begin
            x:=1;y:=1;
           end
         else
           begin
            x:=titr[acol].Align  div 3;//pour colone
            y:=titr[acol].Align  mod 3;//pour ligne
           end;
         case x of
            0:x:=rect.Left+1;
            1:x:=(rect.Right+rect.Left-h.cx) div 2;
            2:x:=rect.Right-h.cx -1;
         end;
         case y of
            0:y:=rect.Top +1;
            1:y:=(rect.Bottom+rect.Top-h.cy) div 2;
            2:y:=rect.Bottom-h.cy-1;
         end;
         Grid1.Canvas.TextRect(rect,x,y,s);
    end;
    procedure TFichAvences.Grid1SelectCell(Sender: TObject; ACol,
      ARow: Integer; var CanSelect: Boolean);
    begin
         if acol=5 then grid1.Options :=grid1.Options +[goEditing]
         else grid1.Options :=grid1.Options -[goEditing];
    end;
     
     
    procedure TFichAvences.Monmessage ;
    begin
         if (msg.Msg =WM_PARENTNOTIFY) and (msg.WParamLo =1) then
           begin
             grid1.WindowProc:=winda;
             grid1.WindowProc(msg);
             winda:=grid1.Controls[0].WindowProc;
             grid1.Controls[0].WindowProc:=myprocedure;
           end
         else Winda(msg);
    end;
    procedure TFichAvences.MyProcedure ;
    begin
     
         if (msg.Msg =8)  then
           begin
            mot:=TEdit(grid1.Controls[0]).text;
            postmessage(FichAvences.Handle,wm_lecture,0,0);
           end ;
           winda(msg);
    end;
    end.

  15. #15
    Membre Expert
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Par défaut
    Pour détecter lorsqu'on change de cellule (avec la position de la souris), je pense que j'utiliserai l'évènement OnMouseMove et la fonction MouseToCell :
    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
    Var
      CurCol, CurRow: Integer;
     
    Procedure TForm1.StringGrid1MouseMove(Sender: TObject;
      Shift: TShiftState; X, Y: Integer);
    Begin
      StringGrid1.MouseToCell(X, Y, X, Y);
      If (CurCol <> X) Or (CurRow <> Y) Then
      Begin
        // <-- Détection ici --> //
        Beep;
        CurCol := X;
        CurRow := Y;
      End;
    End;
    Utilise les propriétes Col et Row du StringGrid pour connaître la cellule actuellement sélectionnée...

  16. #16
    Membre éclairé

    Inscrit en
    Novembre 2002
    Messages
    815
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 815
    Par défaut
    "edam" il me manque ton unité modul2 pour essayer ton code .
    " Sub0 " ta solution marche que pour la souris .

    En fait je suis en train de bosser sur un Redo/Undo d'un tableau , donc je veux sauvegarder le contenu d'une cellule avant qu'elle ne soit modifié
    et seulement si elle est modifié.

    Mon tableau gere la saisie , les copier/coller , drag drop ....

    En ce moment j'ai ecris une procedure pour chaque fonction
    par exemple pour le drag ou les coller je sais ou je vais ecrire , donc je sauve le contenue de la cellule avant d'ecrire a l'interieur.

    Pour la saisie manuelle je vais ecrire une autre procedure en passant le "OnselecCell" et essayer de determiner si un cellule a changer de valeur ..
    et ainsi de suite pour toute les action possible sur le tableau...

    je voudrais ecrire une procedure(s) qui me permette de savoir si une cellule change de valeur que je soit en edition ou pas . cela me permettrai de couvrir toute mes actions en une seule fois .

    mais le "OnselecCell" ne marche pas par exemple quand on ecris comme si dessous
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
      Tgris.cells[10,10]:='bonjours';
    donc je cherche le moyen de determiner le changement de valeur d'une cellule , voila le pourkoi de ma question du debut

  17. #17
    Membre Expert Avatar de edam
    Homme Profil pro
    Développeur Delphi/c++/Omnis
    Inscrit en
    Décembre 2003
    Messages
    1 894
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Développeur Delphi/c++/Omnis
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 894
    Par défaut
    mon code n'est pas a copier totalement c'est , pour aider et a toi de manipulé
    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
     
    unit Les_Aveces; 
    type 
      TFichAvences = class(TForm) 
        Grid1: TStringGrid; 
        procedure FormCreate(Sender: TObject); 
      private 
        { Déclarations privées } 
        Winda:TWndMethod; // 
        Procedure Monmessage(var msg:TMessage); 
        Procedure MyProcedure(var msg:TMessage); 
      public 
        { Déclarations publiques } 
      end; 
     
    var 
      FichAvences: TFichAvences; 
    implementation 
     
     
    {$R *.DFM} 
     
    procedure TFichAvences.FormCreate(Sender: TObject); 
    begin 
         Winda:=grid1.WindowProc ; // enregistrement de winproc de stringrid pour que les messages continue
         grid1.WindowProc :=monmessage; 
    end; 
    procedure TFichAvences.Monmessage ; 
    begin 
         if (msg.Msg =WM_PARENTNOTIFY)  // il y as un composant qui est crée et son parent c'est stringgrid
            and (msg.WParamLo =1) then  le premié composnt enfant de stringgrid est toujour la zone d'edition  begin 
             grid1.WindowProc:=winda; // remétre winproc de stringgrid a sa plasse 
             grid1.WindowProc(msg); 
             winda:=grid1.Controls[0].WindowProc; //et enregistrement winproc du nouveau control crée
             grid1.Controls[0].WindowProc:=myprocedure; 
           end 
         else Winda(msg); 
    end; 
    procedure TFichAvences.MyProcedure ; 
    begin 
         if (msg.Msg =8)  then //msg.msg=8 lostfocus du zone de d'édition
           begin 
            mot:=TEdit(grid1.Controls[0]).text; 
            postmessage(FichAvences.Handle,wm_lecture,0,0); 
    //le poste message pour envoyé vers un message personalisé car aprés des essait on peut pas applé directement une procedure le message enoyé vers la zone d'éditon doit etre terminé avant tout autre trétement ... pourqoi je sais pas vraiment 
           end ; 
           winda(msg); 
    end; 
    end.
    a vous maintenant de tout modifié selon vos besoin
    à un époque j'avait besoin de recalculé les donnée de tout une colone d'une grid aprés que l'utlisateur a changé une sellule dans cette colone

  18. #18
    Membre Expert
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Par défaut
    http://www.developpez.net/forums/viewtopic.php?t=336444

    Pourquoi ne pas avoir continuer de poster dans ton 1er sujet ?
    surtout que le tag résolu n' a pas été ajouté...

  19. #19
    Membre éclairé

    Inscrit en
    Novembre 2002
    Messages
    815
    Détails du profil
    Informations forums :
    Inscription : Novembre 2002
    Messages : 815
    Par défaut
    Pour repondre a "SUB0" ,

    En effet au final les deux problemes sont liées au 1er post "undo/redo".

    mais les questions sont deux questions bien differentes
    - Dans un premier post , ont debattaient d'un Undo/redo et de sa gestion.
    - Dans un second post ma question etait plus precide et etait sur la gestion d'une cellule de TstringGrid .

    Pour la clarté des recherches ensuite sur le forum , je pensais bien faire , car a mon avis faire une recherche sur le forum sur un probleme de cellule de Tgrids dans une rubrique de "Undo/redo" me semble pas tres judicieux , car ma seconde question a un champs d'application bcp plus vaste.

    Quand au resolu de mon premier post , je suis toujours interresé par des sujections de d'autre personne qui en l'aurait pas lu .

    Donc si mon choix de deux post n'est pas correct j'en suis dsl , mais c'etait de bonne fois ( mon smeley est quand meme plus sympa ! non ?)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. TStringGrid et édition
    Par nomdutilisateur dans le forum Composants VCL
    Réponses: 6
    Dernier message: 02/04/2004, 14h22
  2. comment gerer une TStringGrid
    Par madison59 dans le forum C++Builder
    Réponses: 3
    Dernier message: 01/03/2004, 15h03
  3. Delete dans la propriété Rows d'un TStringGrid ???
    Par Neilos dans le forum C++Builder
    Réponses: 2
    Dernier message: 26/02/2004, 23h55
  4. Delphi 7 et les TStringGrid
    Par Claude HENRY dans le forum Composants VCL
    Réponses: 6
    Dernier message: 28/05/2003, 09h18
  5. Comment imprimer le contenu d'un TStringGrid
    Par scorpiwolf dans le forum C++Builder
    Réponses: 2
    Dernier message: 19/06/2002, 15h41

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