Firemonkeyで次のタブストップオブジェクトを得る

VCLフレームワークであれば、以下のコードでタブで移動する先のコントロールを得ることができる。

  TWinControl* pNext = FindNextControl( Edit1, true, true, false );

しかしFiremonkeyフレームワークにはFindNextControlに相当する機能はない。
いろいろ探してみたところFindNextTabStopを用いて、以下のようなコードを記述する。

// 検索関数
TControl* find_next_control( TControl* pCurrent )
{
  for(;;)
  {
    _di_IControl iControl;
    pCurrent->GetInterface( iControl );

    TControl* pParent = pCurrent->ParentControl;
    if( pParent == nullptr )
    {
      TForm* pForm = dynamic_cast<TForm*>(pCurrent->Parent);
      if( pForm == nullptr )
        return nullptr;

      _di_IControl iFNext = 
                     pForm->GetTabList()->FindNextTabStop( iControl, true, true );
      if( iFNext == nullptr )
        return nullptr;
      return dynamic_cast<TControl*>(iFNext->GetObject());
    }
    else
    {
      _di_IControl iCNext = 
                     pParent->GetTabList()->FindNextTabStop( iControl, true, true );
      if( iCNext != nullptr )
        return dynamic_cast<TControl*>(iCNext->GetObject());

      pCurrent = pParent;
    }
  }
}
// 利用側
void TForm1::OnEdit1Click( TObject* Sender )
{
  TControl* pNext = find_next_control( Edit1 );
}

自分のIControlインターフェースを得た上で、親コントロールタブリストを検索し、無ければさらに上位のコントロールタブリストで検索する。TFormはTControlの派生クラスではない為、場合分けをする。
VCLフレームワークと異なり、フォームのGetTabListだけでは正しく得ることができないことに注意だ。
コンパイラーをBorlandコンパイラー(bcc32.exe)を用いる場合はnullptrをNULLに置き換えすること。
無条件ループを'for(;;)'にするか'while(true)'にするかは好みだと思う。

なお、FindNextTabStopはアンドキュメントなので、今後のバージョンで利用可能なのかは不明だ。
できればVCLと同じように扱えると便利なのだが。