检测Firemonkey应用程序中是否已打开给定类型的表单

时间:2016-03-09 15:44:59

标签: c++ forms templates firemonkey c++builder-xe8

我正在试图想出一种方法来判断在我的应用程序中是否打开了给定类型的表单,然后再打开一个新表单。这样做的原因是,应用程序中有某些形式,只有一次打开它们的一个实例才有意义,但我宁愿不使它们严格模态化。

为了解决这个问题,我实现了以下方法,该方法遍历Screen->Forms并尝试将每个表单强制转换为提供的表单类型。我想如果演员表演了,我发现那种表格已经打开了。

template <typename T>
bool __fastcall FormOfTypeExists( T * Form )
{
    for( int i = 0; i < Screen->FormCount; i++ )
    {
        T * CurrentForm = (T*)Screen->Forms[i];

         if( CurrentForm != 0 )
         {
             return true;
         }
    }

    return false;
};

然后,无论我在哪里尝试创建表单,我都会调用该方法,如下所示:

TFormA *Form;

if( FormOfTypeExists( Form ) )
{
    return;
}

Form = new TFormA( Owner );

Form->Show();

我遇到的问题是,我似乎总是能够成功地将TCommonCustomForm Screen->Forms对象转换为我传入的任何形式。

有没有办法可以改变我的逻辑来成功检测应用程序中是否已存在某种类型的表单?我应该看一下这个问题的更好方法吗?

1 个答案:

答案 0 :(得分:1)

您正在使用不会将对象的真实类型考虑在内的强制转换。这就是为什么演员总是成功(当它真的没有)。要测试某个对象是否属于特定类型,您需要使用dynamic_cast代替。

当你实际上没有将变量用于任何事情时,不要将变量作为输入传递。

请改为尝试:

template <typename T>
bool __fastcall FormOfTypeExists()
{
    for( int i = 0; i < Screen->FormCount; i++ )
    {
        T * CurrentForm = dynamic_cast<T*>(Screen->Forms[i]);
        if( CurrentForm != NULL )
        {
            return true;
        }
    }

    return false;
}

if( FormOfTypeExists<TFormA>() )
{
    return;
}

TFormA *Form = new TFormA( Owner );
Form->Show();