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 :

TControlHandler pour la modification dynamique de composants


Sujet :

Composants VCL Delphi

  1. #1
    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 TControlHandler pour la modification dynamique de composants
    Dans le cadre d'un projet d'écriture d'un IDE pour un autre langage, j'utilise des fonctions Delphi dans une DLL, comme bibliothèque de soutien. J'avais besoin de pouvoir changer la position et/ou les dimensions de n'importe quel objet visuel. Certes, avec un peu de recherche sur le net, on trouve pas mal d'idées. Mais une qui marche en Delphi 6 Personal Edition, et plus à l'intérieur d'une DLL pour intervenir sur les objets du programme principal en-dehors de la DLL, c'est plus rare !

    J'ai fini par trouver un fichier Control.zip, téléchargé sans aucune référence à un auteur, ni dans le ZIP ni dans un éventuel fichier de documentation qui l'accompagne. Mais ce fichier contient une unité ControlHandler.pas qui contient la définition du composant TControlHandler. Et ce module compilait directement avec mon Delphi 6 PE, et était parfaitement opérationnel. Donc, grâce à un auteur anonyme, avec une réalisation ancienne visiblement pour Delphi 5 en 2000, j'ai pu résoudre mon problème.

    Mais, il me fallait un peu plus de souplesse. J'ai apporté deux ajouts à ce composant:
    1. une propriété ExternalBorder, un boolean qui permet de placer le cadre avec les poignets à l'extérieur ou à l'intérieur de l'objet, selon la valeur passée.
    2. une propriété ObjectList optionnelle. Si elle est utilisée, on lui charge un objet TObjectList qui doit alors contenir une liste de TControlHandler, chacun commandant un composant visuel différent. Et le composant TControlHandler se charge alors d'appliquer les déplacements simultanément sur tous les objets contenus dans cette ObjectList. On peut ainsi réaliser une multi-sélection et agir sur toute la sélection, préservant ainsi les écarts relatifs entre objets d'une même sélection.

    Pour ceux qui seraient intéressés par un tel composant, il est en pièce jointe TControlHandler.pas. Et voici une fonction utilisant cela:
    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
     
    // pour Designer
    var
      DesignerCH: TControlHandler;
      DesignerExt: boolean;
      DesignerCHlist: TObjectList;
      DesignerInternalFlag: boolean;
     
    // gérer les fonctions étendues du designer
    // act:  0 = effacer toutes les sélections
    //       1 = ajouter l'objet obj à la sélection
    //       2 = retirer l'objet obj de la sélection
    //       3 = retourner la liste des objets sélectionnés dans un memo
    function DesignerFunction(act: integer; hnd: HWND; ctrl: TControl; opt: integer):integer; stdcall; export;
    var
      i: integer;
      s: string;
      present: boolean;
    begin
      result := -1;
      try
        if not assigned(DesignerCHlist) then DesignerCHlist := TObjectList.Create(false);
        case act of
          0: begin
               if DesignerCHlist.Count>0 then begin
                 for i:=DesignerCHlist.Count-1 downto 0 do begin
                   TControlHandler(DesignerCHlist.Items[i]).Free;
                   DesignerCHlist.Delete(i);
                 end;
               end;
               DesignerCH := nil;
             end;
          1: begin
               present := false;
               if DesignerCHlist.Count>0 then begin
                 for i:=0 to DesignerCHlist.Count-1 do begin
                   if integer(TControlHandler(DesignerCHlist.Items[i]).Control)=integer(ctrl) then begin
                     present := true;
                     break;
                   end;
                 end;
               end;
               if not present then begin
                 DesignerInternalFlag := true;
                 RegisterObjectForDesigner(hnd,ctrl,opt);
                 DesignerCHlist.Add(DesignerCH);
                 DesignerInternalFlag := false;
               end;
             end;
          2: begin
               if DesignerCHlist.Count>0 then begin
                 for i:=0 to DesignerCHlist.Count-1 do begin
                   if integer(TControlHandler(DesignerCHlist.Items[i]).Control)=integer(ctrl) then begin
                     if integer(ctrl)=integer(DesignerCH.Control) then begin
                       DesignerCH.Free;
                       DesignerCH := nil;
                     end else begin
                       TControlHandler(DesignerCHlist.Items[i]).Free;
                     end;
                     DesignerCHlist.Delete(i);
                     break;
                   end;
                 end;
               end;
             end;
          3: begin
               SendMessage(hnd, LB_RESETCONTENT,0, 0);
               if DesignerCHlist.Count>0 then begin
                 for i:=0 to DesignerCHlist.Count-1 do begin
                   s := inttostr(integer(TControlHandler(DesignerCHlist.Items[i]).Control));
                   SendMessage(hnd, LB_ADDSTRING,0, integer(pchar(s)));
                 end;
               end;
               SendMessage(hnd,WM_SETTEXT,0,integer(pchar(s)));
             end;
        end;
        result := 0;
       except
       end;
    end;
    EDIT

    Je viens de trouver que le code initial a été écrit par:
    Written by Bertrand Goetzmann (http://www.object-everywhere.com)
    Malheureusement, l'URL n'est plus valable.
    Mais il y a un lien de télchargement de Control.zip qui m'a servi à récupérer le fichier d'origine, à partir duquel j'ai travaille.
    Le voici: objecteverywhere.chez-alice.fr/control.zip

    Voici le commentaire que je viens d'insérer au début de cette unité:
    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
    {
      Cette unité ControlHandler.pas est issu d'un fichier Control.zip télcharge sur Internet
        URL=objecteverywhere.chez-alice.fr/control.zip   <========= téléchargé ici !
        URL=http://code.openhub.net/file?fid=59kZBVV0_rchMdntRgoBQL6_wus&cid=4UOJ_zYZy_Q&s=&fp=245619&mp=&projSelected=true#L0
        URL=http://delphi.xcjc.net/viewthread.php?tid=47703
        ...
      Auteur initial: Bertrand Goetzmann
      Conçu initialement en Delphi 5 vers l'année 2000.
     
      Ajouts par Klaus le 20/11/2015:
        propriété ExternalBorder (boolean)     indique si le cadre s'affiche à l'intérieur ou en-dehors du contrôle capté
        propriété ObjectList (IObjectList)     contient la liste des TControlHandler de tous les objets sélectionnées en multi-sélection
     
      Le composant sert à changer dynamiquement la position et/ou les dimensions d'un objet Panoramic (Delphi) visible.
      Il dessine un cadre autour de l'objet sélectionné, avec des poignets. Le cadre peut être dessiné à l'intérieur des limites
      de l'objet associé, ou à l'extérieur, en fonction de la valeur de la propriété ExternalBorder. Ce choix peut être fait
      indépendemment pour chaque objet Panoramic sélectionné (pour chaque TControlHandler).
     
      On peut tirer les bords de ce cadre pour déplacer l'objet associé, ou les poignets dans les coins pour changer les
      dimensions. Si la propriété ObjectList est présente, elle contient une TObjectList de tous les TControlHandler des
      objets sélectionnées simultanément (multi-sélecion). Le changement de position se fera alors simultanément sur tous
      ces objets référencés, de sorte à les déplacer en groupe.
    }
    Fichiers attachés Fichiers attachés

  2. #2
    Membre averti Avatar de franckcl
    Homme Profil pro
    Developpeur Delphi
    Inscrit en
    Septembre 2004
    Messages
    516
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Developpeur Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 516
    Points : 443
    Points
    443
    Par défaut
    Merci pour ce partage qui sera utile à quelqu'un.
    J'ai moi même réalisé une même fonctionnalité mais je n'ai jamais pris le temps de partager car il faudrait la détacher de mon code.
    Cordialement

Discussions similaires

  1. Réponses: 7
    Dernier message: 08/08/2007, 11h33
  2. Réponses: 5
    Dernier message: 01/08/2007, 21h31
  3. Création dynamique de composants et destruction
    Par cpdump dans le forum Composants VCL
    Réponses: 4
    Dernier message: 19/01/2005, 18h57
  4. [Swing] Ecouteur pour la taille d'un composant ?
    Par Pill_S dans le forum Agents de placement/Fenêtres
    Réponses: 4
    Dernier message: 18/01/2005, 19h14

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