Добавлены TForms в TPageControl, как мне уведомить TForm о том, что он отображается?

StackOverflow https://stackoverflow.com/questions/5010572

  •  14-11-2019
  •  | 
  •  

Вопрос

У меня есть TPageControl с несколькими таблицами TTabSheets, которые содержат TForms (или, возможно, TFrames, но пока TForms).

Когда вкладка появляется в поле зрения, я бы хотел, чтобы TForm или TFrame получали уведомление о том, что она вышла на передний план.Я не могу найти ничего, что могло бы это сделать.

Я знаю, что могу получить активную таблицу TTabSheet в OnChange событие, поэтому я попытался добавить этот класс в TForm:

struct iTab
{
    virtual void DoIt( void ) = 0;
};

с учетом этого в OnChange:

  ICPTab *tab = dynamic_cast<ICPTab *>( sheet->Controls[ 0 ] );

Думая, что я мог бы использовать RTTI, чтобы получить iTab указатель и вызов DoIt() из самого И я получаю предупреждение:

[BCC32 Warning] Unit1.h(18): W8130 Interface 'IPTab' does not derive from IUnknown. (Interfaces should derive from IUnknown) 
[BCC32 Warning] MainWindow.cpp(612): W8131 Casting Delphi style class 'TControl' to an interface. Use 'System::interface_cast<ICPTab>(cls)' instead

Я не заинтересован в получении всего IUnknown просто для того, чтобы форма могла использовать интерфейс.

Я могу получить указатель TFrame или TForm, используя:

  TForm *tab = dynamic_cast<TForm *>( sheet->Controls[ 0 ] );

но я не могу вызвать метод, отличающийся от TForm, с этим указателем.Было бы нормально вызвать Activate() способ?

Итак, как мне уведомить TForm или TFrame о том, что он сейчас отображается?

Это было полезно?

Решение 2

Я пошел со следующим кодом:

  void __fastcall TgMainWindow::mPageControlChange( TObject* Sender )
  {
     NOT_USED( Sender );
     TTabSheet* sheet = mPageControl->ActivePage;

     if ( sheet->ControlCount > 0 )
     {
        // form or frame, we will attempt to call the OnActivate method
        TForm* form = dynamic_cast<TForm *>( sheet->Controls[ 0 ] );

        if ( form == NULL )
        {
           ShowMessageDlg( this, L"Programming Error: Initial child on tabsheet must be a TForm", mtError, TMsgDlgButtons( ) << mbOK );
        }
        else
        {
           if ( form->OnActivate != NULL )
           {
              form->OnActivate( this );
           }
           else
           {
              ShowMessageDlg( this, L"Programming Error: From must have an OnActivate event", mtError, TMsgDlgButtons( ) << mbOK );
           }
        }
     }
  }
.

Поскольку форма на таблице никогда не имеет своего метода онактивата, это работает довольно хорошо.

Примечание. Образец метода не завершен, нет вызова ondeactivate

Другие советы

Вы должны вывести iTab От IUnknown (или IInterface) или для того, чтобы правильно использовать его в качестве интерфейса.Предупреждение компилятора даже намекает на то, что вы можете использовать interface_cast чтобы извлечь интерфейс из стиля Delphi (он же TObject-производный) объект.В качестве альтернативы используйте TObject::GetInterface() вместо этого.

В противном случае, если вы просто хотите вызвать методы вашего пользовательского класса TForm, то просто приведите указатель дочернего элемента управления из вашего TTabSheet в ваш фактический класс, производный от TForm:

TMyForm *tab = dynamic_cast<TMyForm *>( sheet->Controls[ 0 ] );
if( tab != NULL ) tab->DoSomething();

Или:

static_cast<TMyForm *>( sheet->Controls[ 0 ] )->DoSomething();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top