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

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

本文关键字:Firemonkey 应用程序 是否 类型 表单 检测      更新时间:2023-10-16

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

为了解决这个问题,我实现了以下方法,该方法遍历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我传递的任何类型的形式。

有没有办法改变我的逻辑以成功检测应用程序中是否已存在某种类型的形式? 有没有更好的方法来解决这个问题,我应该看看?

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