Добавлены TForms в TPageControl, как мне уведомить TForm, что он показывает? - PullRequest
0 голосов
/ 16 февраля 2011

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

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

Я знаю, что могу получить Active 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 ]

0 голосов
/ 17 февраля 2011

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

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

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

примечание: пример метода не завершен, нет вызова OnDeactivate

0 голосов
/ 16 февраля 2011

Вы должны получить iTab из IUnknown (или IInterface) или заказать, чтобы использовать его как интерфейс правильно. Предупреждение компилятора даже намекает на то, что вы можете использовать interface_cast для извлечения интерфейса из объекта в стиле Delphi (aka TObject -derived). В качестве альтернативы используйте 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();
...