2017-03-07 6 views
0

Lorsque j'essaie d'ajouter des contrôles à un TTabSheet déjà existant lors de l'exécution, ces contrôles restent invisibles lorsqu'ils sont ajoutés dans l'événement OnShow de TTabSheet.Ajout de contrôles à TPageControl dans TabSheet1Show

Étapes pour reproduire:

  1. Ajouter un TPageControl à un TForm dans le concepteur
  2. Ajouter 3 TTabSheet objets à cette TPageControl dans le concepteur.
  3. Définir le premier TTabSheet actif (au moment du design).
  4. exécuter le code ci-dessous:

fichier d'en-tête:

#ifndef Unit1H 
#define Unit1H 

#include <System.Classes.hpp> 
#include <Vcl.Controls.hpp> 
#include <Vcl.StdCtrls.hpp> 
#include <Vcl.Forms.hpp> 
#include <Vcl.ComCtrls.hpp> 
//--------------------------------------------------------------------------- 
class TForm1 : public TForm 
{ 
__published: // Von der IDE verwaltete Komponenten 
    TPageControl *PageControl1; 
    TTabSheet *TabSheet1; 
    TTabSheet *TabSheet2; 
    TTabSheet *TabSheet3; 
    TButton *Button1; 
    void __fastcall TabSheet1Show(TObject *Sender); 
private: // Benutzer-Deklarationen 
    TButton *ButtonConstructor; 
    TButton *ButtonOnTabShow; 
public:  // Benutzer-Deklarationen 
    __fastcall TForm1(TComponent* Owner); 
}; 
//--------------------------------------------------------------------------- 
extern PACKAGE TForm1 *Form1; 
//--------------------------------------------------------------------------- 
#endif 

Source fichier:

#include <vcl.h> 
#pragma hdrstop 

#include "Unit1.h" 
//--------------------------------------------------------------------------- 
#pragma package(smart_init) 
#pragma resource "*.dfm" 
TForm1 *Form1; 
//--------------------------------------------------------------------------- 
__fastcall TForm1::TForm1(TComponent* Owner) 
    : TForm(Owner) 
{ 
    // Adding a TButton in the Form's constructor works 

    TTabSheet *ts = this->TabSheet1; 

    if (!this->ButtonConstructor) 
    { 
     ButtonConstructor = new TButton(ts); 
     ButtonConstructor->Name = "ButtonConstructor"; 
     ButtonConstructor->Caption = "Construct"; 
     ButtonConstructor->Parent = ts; 
    } 


} 
//--------------------------------------------------------------------------- 
void __fastcall TForm1::TabSheet1Show(TObject *Sender) 
{ 
    // Adding a TButton in the OnShow Event of TTabSheet does NOT work: 
    // The button stays invisible 

    TTabSheet *ts = dynamic_cast< TTabSheet * >(Sender); 
    // TTabSheet *ts = this->ButtonOnTabShow; // does not make any difference 

    if (!this->ButtonOnTabShow) 
    { 
     ButtonOnTabShow = new TButton(ts); 
     ButtonOnTabShow->Name = "ButtonOnTabShow"; 
     ButtonOnTabShow->Caption = "Show"; 
     ButtonOnTabShow->Parent = ts; 
     // Button should be placed below the other 
     ButtonOnTabShow->Top = ButtonConstructor->Top + ButtonConstructor->Height + 2; 
    } 

    // The following 2 lines would make the Button visible 
    // PageControl1->ActivePageIndex = 1; 
    // PageControl1->ActivePageIndex = 0; 
} 

Le résultat est:

  • ButtonConstructor est visible
  • ButtonOnTabShow n'est pas visible

Si vous cliquez sur TabSheet2 puis revenir à TabSheet1, ButtonOnTabShow sera également visible.

Est-ce un bug qui ne peut être résolu, ou est-ce que je manque quelque chose?

Répondre

0

Je ne sais pas exactement pourquoi cela arrive, mais je peux le reproduire. Cela a probablement à voir avec la façon dont TPageControl gère la visibilité de ses objets TTabSheet (puisque l'API Win32 n'a pas de concept de feuille à onglets, TTabSheet est une invention entièrement VCL pour faciliter la gestion du contenu à onglets). Cependant, il est facile de contourner en utilisant ce code:

#define WM_ENSUREBUTTONSHOWN (WM_APP+1) 

void __fastcall TForm1::TabSheet1Show(TObject *Sender) 
{ 
    // ... 

    if (!this->ButtonOnTabShow) 
    { 
     ButtonOnTabShow = new TButton(ts); 
     // ... 
     PostMessage(Handle, WM_ENSUREBUTTONSHOWN, 0, 0); 
    } 
} 

void __fastcall TForm1::WndProc(TMessage &Message) 
{ 
    TForm::WndProc(Message); 
    if ((Message.Msg == WM_ENSUREBUTTONSHOWN) && (this->ButtonOnTabShow)) 
    { 
     this->ButtonOnTabShow->Hide(); 
     this->ButtonOnTabShow->Show(); 
    } 
} 

Autre possibilité:

#define WM_REFRESHTABSHEET (WM_APP+1) 

void __fastcall TForm1::TabSheet1Show(TObject *Sender) 
{ 
    // ... 

    if (!this->ButtonOnTabShow) 
    { 
     ButtonOnTabShow = new TButton(ts); 
     // ... 
     PostMessage(Handle, WM_REFRESHTABSHEET, 0, 0); 
    } 
} 

void __fastcall TForm1::WndProc(TMessage &Message) 
{ 
    TForm::WndProc(Message); 
    if ((Message.Msg == WM_REFRESHTABSHEET) && (this->TabSheet1->Visible)) 
    { 
     this->TabSheet1->Hide(); 
     this->TabSheet1->Show(); 
    } 
}