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 :

Cloner un TForm (ADODataSet et ReadComponent)


Sujet :

Composants VCL Delphi

  1. #1
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2016
    Messages : 2
    Points : 2
    Points
    2
    Par défaut Cloner un TForm (ADODataSet et ReadComponent)
    Bonjour à tous,
    j'ai besoin pour une appli. de cloner plusieurs tform different ('première' mêre identique). L'idée c'est de cloner le tform, de le détruire et de le rouvrir plus tard avec les mêmes valeur saisie par l'utilisateur. A savoir que je ne connais ni la fonction d'ouverture du tform (plusieurs appels possible) ni les arguments de l'appel de la fonction d'ouverture de ce tform.
    Cloner/dupliquer le tform avant sa destruction semble être la facon de faire la plus adapté afin de pouvoir le rouvrir à l'identique plus tard.
    Je sais que pour arriver à mes fin je doit utiliser les fonction 'WriteComponent' et 'ReadComponent'.
    Le problème est que ce tform contient des composants connectés à un adodataset dont la connexion à la bdd est géré dans un autre fichier.

    Un peu de code de la duplication:

    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
     
    destructor TF_MonForm.Destroy;
    var
      ms: TMemoryStream;
      newform : TF_MonForm;
    begin
      ms := TMemoryStream.Create;
      try
    //    Self.ADODS.Active := false;   <---- n'empeche pas l'ado dupliquer plus loin de lancer la tentative de connection à la bdd
     
        ms.WriteComponent(Self);
     
        inherited;
     
    // Blabla. Ici s'éxecute le code à faire pendant la fermeture du tform.
     
        newform := TF_MonForm.Create(Form);
     
        // La partie qui suit vide le form pour éviter d'avoir à changer le nom de chacun des composants. Sinon explose car le composant est déjà existant. 
        for I:=TForm(newform).ComponentCount - 1 downto 0 do
        begin
          TWinControl(TForm(newform)).RemoveComponent(TForm(newform).Components[I]);
        end;
     
        ms.Position := 0;
        ms.ReadComponent(newform); // <--- Explose ici
        newform.ShowModal;
      finally
        ms.Free
      end;
    L'erreur qui m'est renvoyé est : 'Valeur connection ou Connection String manquante'.

    Le problème viendrait du fait que le fonction ReadComponent 'active' l'adodataset du Tform avant de 'gérer' la connection à la bdd.
    J'ai essayé de 'désactivé' l'ado avant d'utiliser le WriteComponent mais ca ne change rien.
    J'ai fait pas mal de recherche sur le sujet mais impossible de trouver la solution. Je suis à deux doigts de réussir mais je bloque sur ce problème.
    Je ne cherche pas à cloner le curseur/recordset de l'ado. Je veux juste rouvrir le form avec toutes les valeurs saisie dans les différents composants et la connection de l'ado effective (pour les composants qui en ont besoin).
    Je ne suis pas sûr d'avoir été assez clair alors n'hésitez pas à demander plus de précision.

    Merci d'avoir pris le temps de me lire et j'espère trouver un réponse ici.

  2. #2
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 661
    Points : 5 224
    Points
    5 224
    Par défaut
    Bonjour,

    Pourquoi stocker les composants en entier si tout ce que tu veux c'est garder les valeurs.
    Il suffit de garder ces valeurs dans un Objet quelconque et les relire une fois la nouvelle fiche chargée.

  3. #3
    Membre expérimenté Avatar de guillemouze
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    876
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2004
    Messages : 876
    Points : 1 448
    Points
    1 448
    Par défaut
    Citation Envoyé par axel.friedel Voir le message
    j'ai besoin pour une appli. de cloner plusieurs tform different ('première' mêre identique). L'idée c'est de cloner le tform, de le détruire et de le rouvrir plus tard avec les mêmes valeur saisie par l'utilisateur.
    Et ne peux tu pas tout simplement ne pas détruire ta form, juste la masquer (CloseAction := caHide par exemple), et la rafficher quand tu en a de nouveau besoin ?

  4. #4
    Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2016
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2016
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Désolé de ne pas avoir répondu plutôt, après 2-3 jours d'attente j'ai oublié ce post.

    Citation Envoyé par guillemouze Voir le message
    Et ne peux tu pas tout simplement ne pas détruire ta form, juste la masquer (CloseAction := caHide par exemple), et la rafficher quand tu en a de nouveau besoin ?
    Non car ce form s'ouvre par dessus un autre, en format réduit et grise le fond d'écran pour obliger au focus de l'utilisateur (Un peu comme les messages de sécurité windows pour executer une appli en admin). Cette dernière partie à été un peu compliqué à mettre en place et du coup on ne préfère pas la modifier juste pour mon problème.

    Les jours suivants on a fini par résoudre le soucis mais d'autre problème sont intervenu par la suite.
    Du coup on a complétement abandonné l'idée pour le moment car cette partie n'était pas du tout importante.
    Merci de vos réponse.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 628
    Points : 10 553
    Points
    10 553
    Par défaut
    J'ai fait la même chose que toi, mais au lieu de cloner un TForm, je prend un aperçu avec le méthode C BitBlt.


    Je sais je vais me faire taper sur les doigts parce que je travaille en C++ , mais voici mon code C++ avec des TImage32

    Un truc important c'est que la boîte de dialogue doit utiliser les propriétés suivantes:
    • PopupMode = pmExplicit;
    • PopupParent = parent;


    Ce code fait quoi? C'est une boite de dialogue qui prend la taille de la fenêtre mère pour se mettre par-dessus, il y a une image pleine-fenêtre (qui est un aperçu de la fenêtre mère) et ses 2 couches transparentes (la couche la plus au dessus affiche un rectangle avec un message sur 2 lignes).

    Le seul "glitch" que j'ai eu, c'est dans une machine virtuelle, lorsqu'on déplace la fenêtre, l'aperçu correspond à l'endroit précédent où était la fenêtre mère (mais elle n'y est plus).
    Il me semble que la correction que j'ai fait c'est mettre la taille fenêtre à (0, 0) et rappeler Waiting_Screen::setup
    Code c++ : 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
    class Waiting_Screen : public Forms::TCustomForm
    {
    // Constructor & Destructor
    public:
     
    	__fastcall Waiting_Screen(TComponent* /*owner*/);
     
    	__fastcall ~Waiting_Screen();
     
     
    // Life Management
    __published:
     
    	void __fastcall form_close(TObject*, TCloseAction&);
     
     
    // Public Interface
    public:
     
    	void change_size(int height, int width) {
    		waiting_screen->Height = height;
    		waiting_screen->Width  = width;
    	}
     
    	void prepare(Forms::TForm* /*window*/, System::UnicodeString /*message_01*/, System::UnicodeString /*message_02*/);
     
    	void setup(Forms::TForm*);
     
    	void update_rect(Forms::TForm* /*window*/, unsigned int /*rect_left*/, unsigned int /*rect_top*/, unsigned int /*rect_width*/, unsigned int /*rect_height*/);
     
     
    // Attributes
    private:
     
    	Gr32_image::TImage32* waiting_screen;
     
    	Gr32_layers::TBitmapLayer* layer_transparent;
    	Gr32_layers::TBitmapLayer* layer_message_box;
     
    	Types::TSize msg_01_size;
    	Types::TSize msg_02_size;
    };



    Code c++ : 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
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    //---------------------------------------------------------------------
    #define ALPHA_VALUE        128
    #define BORDER_WIDTH         3
    #define MESSAGE_INNER_SPACE  5
    #define BETWEEN_SPACE        5
    //---------------------------------------------------------------------
     
     
    /*****************************************************************************/
    /************************   Constructor & Destructor   ***********************/
    /*****************************************************************************/
     
    __fastcall Waiting_Screen::Waiting_Screen(TComponent* owner) : TCustomForm(owner, 1), waiting_screen(new TImage32((TComponent*) NULL)), layer_transparent(NULL), layer_message_box(NULL) {
    	OldCreateOrder = false;
     
    	OnClose = &form_close;
    }
     
     
    __fastcall Waiting_Screen::~Waiting_Screen() {
    	if (layer_transparent != NULL) {
    		layer_transparent->LayerCollection = NULL;
    		layer_transparent->Bitmap = NULL;
     
    		delete layer_transparent;
    		layer_transparent = NULL;
    	}
     
    	if (layer_message_box != NULL) {
    		layer_message_box->LayerCollection = NULL;
    		layer_message_box->Bitmap = NULL;
     
    		delete layer_message_box;
    		layer_message_box = NULL;
    	}
     
    	waiting_screen->Layers->Clear();
     
    	if (waiting_screen!= NULL) {
    		waiting_screen->Parent = NULL;
    		delete waiting_screen;
    		waiting_screen= NULL;
    	}
    }
     
     
    /*****************************************************************************/
    /****************************   Life Management   ****************************/
    /*****************************************************************************/
     
    void __fastcall Waiting_Screen::form_close(TObject*, TCloseAction& action) {
    	action = caHide;
    }
     
     
    /*****************************************************************************/
    /****************************   Public Interface   ***************************/
    /*****************************************************************************/
     
     
    void Waiting_Screen::prepare(TForm* window, UnicodeString message_01, UnicodeString message_02) {
    	if ((window == NULL) || (waiting_screen == NULL)) { return; }
     
    	waiting_screen->Bitmap->BeginUpdate();
     
    //	Screenshot
    	BitBlt(waiting_screen->Bitmap->Handle, 0, 0, Width, Height, GetDC(window->Handle), 0, 0, SRCCOPY);
     
    //	Message computations
    	waiting_screen->Bitmap->Font = Font;
    	waiting_screen->Canvas->Font = Font;
     
    	msg_01_size = waiting_screen->Bitmap->TextExtentW( message_01.w_str() );
    	msg_02_size = waiting_screen->Bitmap->TextExtentW( message_02.w_str() );
     
    	if (layer_transparent != NULL) {
    		layer_transparent->Bitmap->DrawMode = dmBlend;
    		layer_transparent->Bitmap->MasterAlpha = ALPHA_VALUE;
    		layer_transparent->Bitmap->Clear(clBlack32);
    	}
     
    	if (layer_message_box != NULL) {
    		layer_message_box->Bitmap->DrawMode = dmOpaque;
     
    		for(unsigned short step = 0; step < BORDER_WIDTH; ++step) {
    			layer_message_box->Bitmap->FrameRectS(step, step, (260 - step), (80 - step), 0x00814A00);
    		}
     
    		layer_message_box->Bitmap->FillRect(BORDER_WIDTH, BORDER_WIDTH, (260 - BORDER_WIDTH), (80 - BORDER_WIDTH), (TColor) 0x00F5F5F5);
     
    		layer_message_box->Bitmap->Font = Font;
    		layer_message_box->Bitmap->TextoutW(((0 + ((260 - 0 - msg_01_size.cx) / 2))), (0 + 15), message_01.w_str());
    		layer_message_box->Bitmap->TextoutW(((0 + ((260 - 0 - msg_02_size.cx) / 2))), (0 + 45), message_02.w_str());
    	}
     
    	waiting_screen->Bitmap->EndUpdate();
     
    	waiting_screen->Refresh();
    }
     
     
    void Waiting_Screen::setup(TForm* parent) {
    	if (parent == NULL) { return; }
     
    	Left = 0;
    	Top  = 0;
    	BorderStyle  = bsNone;
    	Height = parent->Height;
    	Width  = parent->Width;
    	Color = (TColor) 0x00F5F5F5;
    //	TransparentColor = true;
    	DoubleBuffered   = true;
    	Font->Charset    = DEFAULT_CHARSET;
    	Font->Color      = clBlack;
    	Font->Name = L"Tahoma";
    	Font->Size = 11;
    	PopupMode  = pmExplicit;
     
    	if (waiting_screen == NULL) { waiting_screen = new TImage32((TComponent*) NULL); }
     
    	waiting_screen->AutoSize = false;
    	waiting_screen->BitmapAlign    = baTopLeft;
    	waiting_screen->DoubleBuffered = true;
    	waiting_screen->Scale     = 1;
    	waiting_screen->ScaleMode = smNormal;
    	waiting_screen->TabOrder  = 0;
    	waiting_screen->Parent    = this;
     
    	waiting_screen->Top  = 0;
    	waiting_screen->Left = 0;
    	waiting_screen->Width  = parent->Width;
    	waiting_screen->Height = parent->Height;
     
    	waiting_screen->SetupBitmap();
     
    	waiting_screen->Bitmap->ResamplerClassName = L"TNearestResampler";
     
    	if (layer_transparent == NULL) {
    		layer_transparent = new TBitmapLayer(waiting_screen->Layers);
    	}
     
    	layer_transparent->Location.Left   = 0;
    	layer_transparent->Location.Top    = 0;
    	layer_transparent->Location.Right  = Width;
    	layer_transparent->Location.Bottom = Height;
    	layer_transparent->Scaled  = 1.0;
    	layer_transparent->Visible = true;
     
    	layer_transparent->Bitmap->SetSize(Width, Height);
     
    	if (layer_message_box == NULL) {
    		layer_message_box = new TBitmapLayer(waiting_screen->Layers);
    		layer_message_box->Location.Left   = ((Width - 260) / 2);
    		layer_message_box->Location.Top    = ((Height - 80) / 2);
    		layer_message_box->Location.Right  = (layer_message_box->Location.Left + 260);
    		layer_message_box->Location.Bottom = (layer_message_box->Location.Top  + 80);
    		layer_message_box->Scaled  = 1.0;
    		layer_message_box->Visible = true;
     
    		layer_message_box->Bitmap->SetSize(260, 80);
    	}
     
    	PopupMode   = pmExplicit;
    	PopupParent = parent;
    }
     
     
    void Waiting_Screen::update_rect(TForm* window, unsigned int rect_left, unsigned int rect_top, unsigned int rect_width, unsigned int rect_height) {
    	waiting_screen->Bitmap->BeginUpdate();
     
    	BitBlt(waiting_screen->Bitmap->Handle, rect_left, rect_top, rect_width, rect_height, GetDC(window->Handle), rect_left, rect_top, SRCCOPY);
     
    	waiting_screen->Bitmap->EndUpdate();
     
    	waiting_screen->Refresh();
    }


    Édit: @tourlourou ouais je fais l'effort de le mettre en C++

  6. #6
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 853
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 853
    Points : 11 285
    Points
    11 285
    Billets dans le blog
    6
    Par défaut
    Disons que tu devrais moins souffrir de ton ajout de code c++ que de ton oubli des bonnes balises entre crochets :
    - dans un forum Delphi, les balises CODE le colorent syntaxiquement par défaut comme du Pascal...
    - si tu précises CODE=c++ elles le colorent correctement !
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/09/2003, 09h36
  2. Taille d'un TForm à l'état Maximized
    Par Altau dans le forum C++Builder
    Réponses: 2
    Dernier message: 13/06/2003, 12h57
  3. Comment cloner un composant
    Par totoranky dans le forum Composants
    Réponses: 2
    Dernier message: 12/04/2003, 15h29
  4. [TForm] Ne pas autoriser l'ouverture d'un form
    Par sbeu dans le forum Composants VCL
    Réponses: 6
    Dernier message: 11/10/2002, 11h20
  5. Probleme d'impression avec la méthode TForm->Print()
    Par Kid Icarus dans le forum C++Builder
    Réponses: 13
    Dernier message: 31/07/2002, 14h26

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