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

Detecting if a form of a given type is already open in Firemonkey application

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

为了解决这个问题,我实现了以下方法,它遍历 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();

我 运行 遇到的问题是,我似乎总是能够成功地将 Screen->Forms 中的 TCommonCustomForm 对象转换为我传入的任何类型的表单。

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

您正在使用不考虑对象真实类型的硬转换。这就是演员总是成功的原因(当它真的没有成功时)。要测试对象是否属于特定类型,您需要改用 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();