在TabSheet1Show

时间:2017-03-07 18:10:42

标签: delphi c++builder tpagecontrol ttabsheet

当我尝试在运行时向已存在的TTabSheet添加控件时,这些控件在OnShow TTabSheet事件中添加时会保持不可见。

重现的步骤:

  1. TPageControl添加到设计器中的TForm
  2. 在设计器中为此TTabSheet添加3个TPageControl个对象。
  3. 设置第一个TTabSheet有效(在设计时)。
  4. 运行以下代码:
  5. 标题文件:

    #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
    

    源文件:

    #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;
    }
    

    结果是:

    • ButtonConstructor可见
    • ButtonOnTabShow不可见

    如果您点击TabSheet2然后返回TabSheet1ButtonOnTabShow也会显示。

    这是一个无法解决的错误,还是我错过了什么?

1 个答案:

答案 0 :(得分:0)

我不确定它为什么会发生,但我可以重现它。它可能与TPageControl管理其TTabSheet对象的可见性的方式有关(因为Win32 API没有标签页的概念。TTabSheet是VCL的完全发明,可以简化管理标签内容)。但是,使用此代码很容易解决:

#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();
    }
}

可替换地:

#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();
    }
}