Добавлены TForms в TPageControl, как мне уведомить TForm о том, что он отображается?
-
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();