我有一个TPageControl,其中包含许多包含TForms的TTabSheets(或者可能是TFrame,但现在是TForms)。
当一个标签进入视图时,我希望TForm或TFrame被通知它已经出现在前面。我找不到那样做的东西。
我知道我可以在OnChange
事件中获取Active TTabSheet,所以我尝试将此类添加到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?
答案 0 :(得分:0)
您必须从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();
答案 1 :(得分:0)
我使用以下代码:
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