Добавление элементов управления в TPageControl в TabSheet1Show

Когда я пытаюсь добавить элементы управления к уже существующему TTabSheet во время выполнения эти элементы управления остаются невидимыми, когда они добавляются в OnShow событие TTabSheet,

Действия по воспроизведению:

  1. Добавить TPageControl к TForm в дизайнере
  2. Добавить 3 TTabSheet возражает против этого TPageControl в дизайнере.
  3. Установите первый TTabSheet активный (во время разработки).
  4. Запустите код ниже:

Заголовочный файл:

#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 а затем вернуться к TabSheet1, ButtonOnTabShow также будет виден

Это ошибка, которая не может быть решена, или я что-то упустил?

1 ответ

Решение

Я не уверен точно, почему это происходит, но я могу воспроизвести это. Это, вероятно, связано с тем, как 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();
    }
}
Другие вопросы по тегам