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 :

copier-Coller d'objet dynamique TSHape


Sujet :

Composants VCL Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Par défaut copier-Coller d'objet dynamique TSHape
    Bonjour à tous.

    J'aimerais une idée lumineuse dans la manière de gérer un copier coller d'un SHape que je créer dynamiquement

    Code de la création dynamique :

    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
    Procedure TFormPrincipal.MiseEnPlaceDesTShapeDejaExistant;
    Var
     Shape: TRuShape;
     DateDebut, DateFin : TDateTime;
    begin
    
    // Ici petit calcul pour les 2 variables de Dates...
    
      With ModuleDeDonneeSecondaire.ADOQueryCalendrier do
      Begin
    // Lecture des enregistrements qui permettrons la création des Shape
        Sql.Clear;
        Sql.Add('Select * From Calendrier ');
        Sql.Add('Where DateDebut Between :xDebut AND :xFin ' );
        Parameters.ParamByName('xDebut').Value := FormatDateTime('dd/mm/yyyy',DateDebut);
        Parameters.ParamByName('xFin').Value := FormatDateTime('dd/mm/yyyy',DateFin);
        Try
          Try
            Open;
            while not Eof do
            Begin
              Shape := TruShape.Create(StringGridSemaine); // Préféré à Self.StringDridSemaine pour des raisons technique
              With Shape do
              Begin
                ParentFont := False;
                Font.Size := 7;
                Font.Name := 'Tahoma';
                Name := 'PANEL' + Fields.Fields[31].AsString; // Important c'est la numéro qui corresponds à la clé de l'enregistrement
                Caption := Fields.Fields[45].AsString;
                Top := Fields.Fields[28].AsInteger;
                left := Fields.Fields[25].AsInteger;
                Height := Fields.Fields[22].AsInteger;
                Width := Fields.Fields[30].AsInteger;
                Parent := StringGridSemaine;
                PopupMenu := Self.PopupMenu1; // Ici le cliqueDroit qui permet actuellement la suppression 
                OnDblClick := Self.ShapeDblClick;
                OnMouseDown := Self.ShapeMouseDown;
                OnMouseMove := Self.ShapeMouseMove;
                OnMouseUp := Self.ShapeMouseUp;
                Hint := Fields.Fields[23].AsString;
                ShowHint := True;
                Pen.Color := Fields.Fields[20].AsInteger;
                StartColor := clCream;
                EndColor := Fields.Fields[20].AsInteger;
                Tag := Fields.Fields[3].AsInteger; 
              end;
              StringGridSemaine.CheckInBounds;
              Next;
            end;
          Except
            on E : Exception do
            Begin
              ShowMessage(E.ClassName + ' erreur soulevée : '+#13+#10+
              'Message : '  + E.Message       +#13+#10+
              'Unit : '     + Self.ClassName  +#13+#10+
              'Procedure : '+ 'TFormPrincipal.MiseEnPlaceDesTShapeJourDejaExistant'      +#13+#10+
              'Table : '    + '<Néant>'       +#13+#10+
              'Requete : '  + SQL.Text       +#13+#10+
              '-----------------------------------------------------------------------'+#13+#10+
              'La lecture des tâches dans l''onglet Semaine n''est pas possible.'+ #13 +#10 +
              'Si le problème persiste, merci de contacter votre revendeur');
            end;
          end;
        Finally
          Close;
        end;
      end;
    end;
    Sachant qu'un Shape pointe équivaut à un enregistrement de ma base de données (Access 97 + ADO) quel serais la meilleurs méthode pour gérer un copier coller ?

    Mon application fonctionne en réseau, donc chaque utilisateur peuvent faire un copier-coller, voir peut-être plusieur copier-coller ?

    Est-ce que lors du copier il est préférable :
    - de mettre dans une table de mon MBD avec le nom de l'user ?
    - d'écrire ces infos dans un fichier INI ?
    - d'écrire plutot dans le registre ?
    - Où utiliser un tableau de variable ?

    J'hesite dans ces choix et je sais pas si il pourrais y en avoir d'autre. J'aimerais que l'utilisateur puisse faire plusieur copier-coller de Shape, peut-être créer une sorte de corbeille temporaire et ensuite il pourrais coller ? est-ce possible.


    Merci de vos remarques et lumières.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Février 2008
    Messages
    141
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 141
    Par défaut
    Salut,

    Tout dépend des choix que tu veux faire. Définis un ensemble de fonctionnalités et de comportements, et choisis un moyen de les implémenter.

    Des exemples de questions que je me poserais :
    1. quelles sont les infos à stocker d'un TShape?
    2. sous quelle forme les stocker? sous forme de texte (par exemple formatté comme un fichier .ini), ou sous forme de données binaires?
    3. est-ce que je veux que l'utilisateur puisse coller ces infos dans une application autre que la mienne (ex: dans NotePad, OpenOffice, Word, Excel...)?


    La question [3] est liée à la question [2] : par exemple, si tu veux qu'il puisse coller ses infos dans un éditeur de texte, tu voudras sûrement stocker, dans le presse-papier, les infos que tu as récupérées sous forme de texte humainement compréhensible ; si c'est pour les coller dans un tableur (Excel ou OpenOffice...), tu voudras les stocker sous forme d'un tableau (il y a plein de formats standards, dont j'ai oublié les noms...)

    A la question [2] : si tu veux pouvoir envoyer tes infos à l'extérieur, passe par le clipboard standard ; sinon, tu peux utiliser un objet avec un format de stockage interne, qui sera sûrement plus pratique à utiliser dans ton cas.

    Si tu choisis de pouvoir exporter tes infos : d'une part il faut que tu écrives une fonction pour stocker tes données dans le presse-papier sous un format, que tu choisis, mais qui doit correspondre à qqch de compréhensible pour d'autres applis, d'autre part, il faut que tu écrives la fonction qui permet, à partir du truc stocké dans le presse-papier, de recréer ta structure de données interne - cf par le mécanisme utilisé par Delphi : TStream.ReadCompoenent/TStream.WriteComponent.


    Fais d'abord ces choix pour stocker 1 Shape toute seule, ensuite tu pourras y voir plus clair si tu veux étendre ton mécanisme de "copier/coller" pour pouvoir copier plusieurs objets à la suite.
    Pour ce deuxième point, je vois plusieurs question sur l'interface : le mécanisme "aggréger/coller l'aggrégat/réinitialiser l'aggrégat" est un peu moins standard que le "copier/coller" - tous tes utilisateurs auront vu "copier/coller" dans d'autres applis, et tu vas sûrement utiliser le mécanisme standard ; il faudra sûrement détailler un peu plus ton mécanisme pour coller plusieurs trucs ensemble...

    En espérant avoir un peu aidé...

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    j'ai pas tout lu, mais personnellement je créerais un dériver de TruShape :

    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
     
    type
      TMyTruShape = class(TruShape)
      public
        constructor Create(AForm: TFormPrincipal; AFields: TFields);
      end;
     
    constructor TMyTruShape.Create(AForm: TFormPrincipal; AFields: TFields);
    begin
      inherited Create(AForm.StringGridSemaine);
      ParentFont := False;
      Font.Size := 7;
      Font.Name := 'Tahoma';
      Name := 'PANEL' + Fields.Fields[31].AsString;
      Caption := Fields.Fields[45].AsString;
      Top := Fields.Fields[28].AsInteger;
      left := Fields.Fields[25].AsInteger;
      Height := Fields.Fields[22].AsInteger;
      Width := Fields.Fields[30].AsInteger;
      Parent := AForm.  
      PopupMenu := AForm.PopupMenu1; 
    {
    // là je préfère surchager les méthodes de l'objet...
    // soit on garde une référence à AForm et on redirige vers ses méthodes
    // soit le code reste dans le composant...c'est selon
      OnDblClick := Self.ShapeDblClick;
      OnMouseDown := Self.ShapeMouseDown;
      OnMouseMove := Self.ShapeMouseMove;
      OnMouseUp := Self.ShapeMouseUp;
    }
      Hint := Fields.Fields[23].AsString;
      ShowHint := True;
      Pen.Color := Fields.Fields[20].AsInteger;
      StartColor := clCream;
      EndColor := Fields.Fields[20].AsInteger;
      Tag := Fields.Fields[3].AsInteger; 
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  4. #4
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Par défaut
    Bonjour, bonsoir à vous 2 et merci de vos propositions.

    Je vais etre plus precis.
    Mon composant TRuShape est déjà dérivé comme ça
    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
    type
     
      TRuShape = class(TShape)     
        Private
          FStartColor:Tcolor;
          FEndColor:Tcolor ;
          fCaption1:String;
          fCaption2:String;
        Protected
          Procedure Paint;override;
        Published
          property StartColor : Tcolor read fStartColor write fStartColor ;
          property EndColor : Tcolor read FEndColor write FEndColor ;
          property Caption1 : String read fCaption1 write fCaption1;
          property Caption2 : String read fCaption2 write fCaption2;
      end;
     
    // ....
     
    procedure TRuShape.Paint;
      Procedure Degrader;
      Var
        TailleDuTexte : Integer;
        aBand : TRect;    { Bande rectangulaire de couleur courante }
        i : Integer;  { Compteur pour parcourir la hauteur de la fiche }
        FStartRGB  : Array[0..2] of Byte;    { RGB de la couleur de départ }
        FCurrentRGB : Array[0..2] of Byte;    { RGB de la couleur courante  }
        FDeltaRGB  : Array[0..2] of Integer; { RGB à ajouter à la couleur de départ pour atteindre la couleur de fin }
        nbtranches: integer;
        Rect:TRect;
     
      Begin
        Try
          Rect.Left := 2;
          Rect.Top := 2;
          Rect.Right := Self.Width-2;
          Rect.Bottom := Self.Height-2;
          self.ParentColor := false;
     
          { Calcul des valeurs RGB pour la couleur courante }
          FStartRGB[0] := GetRValue( ColorToRGB( StartColor ) );
          FStartRGB[1] := GetGValue( ColorToRGB( StartColor ) );
          FStartRGB[2] := GetBValue( ColorToRGB( StartColor ) );
          { Calcul des valeurs à ajouter pour atteindre la couleur de fin }
          FDeltaRGB[0] := GetRValue( ColorToRGB( EndColor )) - FStartRGB[0] ;
          FDeltaRGB[1] := GetgValue( ColorToRGB( EndColor )) - FStartRGB[1] ;
          FDeltaRGB[2] := GetbValue( ColorToRGB( EndColor )) - FStartRGB[2] ;
     
          { Initialisation des dimensions de la bande de couleur }
          aBand.Left :=Rect.Left;
          aBand.Right:=Rect.Right;
          nbtranches:=min(256, Rect.Bottom-Rect.Top);
          { Boucle pour remplir la fiche courante en dégradé }
          With Canvas Do
          Begin
    //
    //  Tous le programme pour le dégradé
    //
            end;
          End;
        Except
          on E : Exception do
          Begin
    // Mon message d'erreur
          end;
        End;
      End;
    begin
      Try
        inherited Paint;
        Degrader;
      Except
        on E : Exception do
        Begin
    // Mon message d'erreur
        end;
      end;
    end;
    Paul THOT
    - Comment intégré ta proposition ton mon coposant actuel ?
    - Et surtout comment m'en servir ? commen sa marche ?
    - Est-ce que je peux, si par exemple je clique droit sur 3 TRushapes je choisi copier, pouvoir ensuite coller l'un des trois ?

    LeGEC
    - Pour être claire, 1 TRuShape représente 1 enregistrement dans ma base avec 15 ou 16 données (qui appraisse sur le Hint du Shape)
    - Le but est de copier ces infos pour les coller en créer un autre TruShape, comme si tu voulais le déplacer. (je gere des le déplacement) mais la c'est pour le recréer dans une autre masque de la même form du même parent.


    Cela pourra peut-être plus vous faire comprendre mon besoins.

    Merci à vous...

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

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    Citation Envoyé par BuzzLeclaire Voir le message
    Paul THOT
    - Comment intégré ta proposition ton mon coposant actuel ?
    - Et surtout comment m'en servir ? commen sa marche ?
    - Est-ce que je peux, si par exemple je clique droit sur 3 TRushapes je choisi copier, pouvoir ensuite coller l'un des trois ?
    alors déjà je veux bien que tu me donnes le nom d'un Dieu

    sinon il suffit de déclarer la nouvelle classe quelque part et de l'utiliser en lieu et place de la précédente
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #6
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 493
    Par défaut
    salut

    un copier coller ne peut etre que local a ton poste car c'est windows qui gere
    le clipboard
    il faut que tu définisse une constante afin que le clipboard puisse reconnaitre le format

    le reste n'est rien dautre qu'un passage de pointeur
    a toi de déterminer les éléments que tu a besoin pour définir ton dessin

    voici un exemple simple d'utilisation

    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
    function TRuShape.AppendToClipboard: string;
    begin
      Result := Fields.Fields[31].AsString+';'+Fields.Fields[45].AsString+';'+...+ #13#10;
    end;
     
    procedure TRuShape.CopyToClipBoard;
    var
      Data     : THandle;
      DataPtr : Pointer;
      tmpString: string;
    begin
      tmpString := self.AppendToClipboard;
      { Allocate memory from global heap }
      Data := GlobalAlloc(GMEM_MOVEABLE, SizeOf(tmpString));
      try
        DataPtr := GlobalLock(Data);  
        try
          Move(tmpString, DataPtr^, SizeOf(tmpString));  
          ClipBoard.SetAsHandle(CF_MYDATA, Data);
        finally
          GlobalUnlock(Data);   
        end;
      except
        GlobalFree(Data);        
        raise;                        
      end;                           
    end;
     
    procedure TRuShape.CreateFromClipboard(var ClipboardStr: string);
    var
      index: Byte;
      Lst := TStringlist;
    begin
      index := Pos(#13#10, ClipboardStr);
      Lst : TStringlist.create;
      Lst.text :=  Copy(ClipboardStr,1, index-2);
      ...
      Name := 'PANEL' + Lst[0];
      Caption := Lst[1];
      Top := Lst[2];
      left := Lst[3];
      Height := Lst[4];
      Width := Lst[5];
      ...
      Delete(ClipboardStr, 1, index+1);
      Lst.free; 
    end;
     
    function TRuShape.GetFromClipBoard: TRuShape;
    var
      Data: THandle;
      DataPtr: Pointer;
      Size: Integer;
      tmpString: string;
      Shape: TRuShape;
    begin
      try
        Data := ClipBoard.GetAsHandle(CF_MYDATA);    
        if Data = 0 then exit;                           
        DataPtr := GlobalLock(Data);                 
        try
          Size := GlobalSize(Data);                    
          Move(DataPtr^, tmpString, Size);        
        finally
          GlobalUnlock(Data);                           
        end;
      except
        GlobalFree(Data);                                
        raise;                                           
      end;                                              
      Shape := CreateShape();
      Shape.CreateFromClipboard(tmpString);
      Result := Shape;
    end;
     
     
    ...
    initialization
      CF_MYDATA := RegisterClipBoardFormat('CF_MYD');    {enregistrement du format dans le clipboard}

Discussions similaires

  1. [OWB] Erreur copier/coller d'objet
    Par Ujitsu dans le forum Outils
    Réponses: 0
    Dernier message: 28/11/2008, 11h42
  2. Réponses: 0
    Dernier message: 18/12/2007, 13h59
  3. [Excel 2007] Utilisation d objet au lieu du copier/coller
    Par wabo67 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 10/11/2007, 14h57
  4. Réponses: 2
    Dernier message: 01/08/2007, 15h46
  5. Protéger Couper/Copier/Coller dans un Objet en développement
    Par tibi666 dans le forum Composants VCL
    Réponses: 14
    Dernier message: 06/12/2004, 14h52

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