Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Encontrar un componente (https://www.clubdelphi.com/foros/showthread.php?t=96591)

Angel.Matilla 08-02-2024 11:26:27

Encontrar un componente
 
Buenas a todos. A ver si soy capaz de explicarme. Tengo un TPageControl en el que de forma dinámica creo las pestañas y en cada pestaña hay un único TListView que también se crea de forma dinámica.

La creación la hago así:
Código:

TListColumn *pColumn;
TListItem *pItem;

Auxiliar->Close();
Auxiliar->SQL->Text = "SELECT Disco, Cancion, Interprete, Tiempo, Pista FROM Pistas WHERE Registro = :Registro ORDER BY Disco, Pista";
Auxiliar->ParamByName("Registro")->AsInteger = PageControl1->Tag;
Auxiliar->Open();

for (; !Auxiliar->Eof; Auxiliar->Next())
{
    if (PageControl2->PageCount == 0 || PageControl2->ActivePageIndex < Auxiliar->FieldByName("Disco")->AsInteger - 1)
    {
          TTabSheet *tPagina  = new TTabSheet(PageControl2);
          tPagina->PageControl = PageControl2;
          tPagina->Parent      = PageControl2;
          tPagina->Caption    = "Disco " + FormatFloat("0", Auxiliar->FieldByName("Disco")->AsInteger);
          tPagina->Name        = FormatFloat("'Disco'0", Auxiliar->FieldByName("Disco")->AsInteger);
          tPagina->TabVisible  = true;
          PageControl2->ActivePageIndex = Auxiliar->FieldByName("Disco")->AsInteger - 1;

          lvCanciones                    = new TListView(tPagina);
          lvCanciones->Parent            = tPagina;
          lvCanciones->Align            = alClient;
          lvCanciones->BevelKind        = bkFlat;
          lvCanciones->BorderStyle      = bsNone;
          lvCanciones->GridLines        = false;
          lvCanciones->Name              = FormatFloat("'Lista'0", Auxiliar->FieldByName("Disco")->AsInteger);
          lvCanciones->ReadOnly          = true;
          lvCanciones->RowSelect        = true;
          lvCanciones->ShowColumnHeaders = false;
          lvCanciones->ViewStyle        = vsReport;
          lvCanciones->Columns->Clear();
          lvCanciones->Items->Clear();

          pColumn = lvCanciones->Columns->Add();
          pColumn->Width = 194;
          pColumn = lvCanciones->Columns->Add();
          pColumn->Width = 193;
          pColumn = lvCanciones->Columns->Add();
          pColumn->Alignment = taRightJustify;
          pColumn->Width = 55;
          pColumn = lvCanciones->Columns->Add();
          pColumn->Width = 0;
    }

    pItem = lvCanciones->Items->Add();
    pItem->Caption = Auxiliar->FieldByName("Cancion")->AsString.Trim();
    pItem->SubItems->Add(Auxiliar->FieldByName("Interprete")->AsString.Trim());
    pItem->SubItems->Add(Auxiliar->FieldByName("Tiempo")->AsDateTime.FormatString("n:ss"));
    pItem->SubItems->Add(Auxiliar->FieldByName("Pista")->AsInteger);
}

Como veis a las pestañas y a las listas las nombro con el número de disco que he leído en el query. Luego, cuando necesito recuperar la información de esas pestañas, hago esto:
Código:

TComponent *Source;

for (int nDisco = 0; nDisco < PageControl2->PageCount; nDisco ++)
{
    Source = this->FindComponent(PageControl2->Pages[nDisco]->Name);
    TTabSheet *Sheet = static_cast<TTabSheet *>(Source);
    [...]
}

Con el depurador he comprobado que, por ejemplo en la imagen, la primera pestaña se llama Disco1, pero al correr el bucle y ejecutar el FindComponent me encuentro que Source da siemrpe valor NULL. He probado también esto:
Código:

TComponent *Source;

for (int nDisco = 0; nDisco < PageControl2->PageCount; nDisco ++)
{
    PageControl2->ActivePageIndex = nDisco
    Source = this->FindComponent(PageControl2->ActivePage->Name);
    TTabSheet *Sheet = static_cast<TTabSheet *>(Source);
    [...]
}

pero tampoco me encuentra los TTabSheet.

También he probado con esto:
Código:

for (int nDisco = 0; nDisco < PageControl2->ControlCount; nDisco ++)
{
    Source = PageControl2->Controls[nDisco];
    if (!Source->ClassNameIs("TTtabSheet"))
          continue;
    [...]
}

Curiosamente con el depurador compruebo que el elemento que encuentra (Source->Name) es Disco1, pero cuando hago la comprobación siguiente (Source->ClassNameIs) vuelve al inicio del bucle.

Angel.Matilla 08-02-2024 11:59:23

¡¡¡aclarado!!!
 
Ya sé por qué estaba funcionando mal: Estaba haciendo el FindComponent sobre el formualrio y no sobre el TPageControl.

Neftali [Germán.Estévez] 08-02-2024 12:33:02

Sólo como apunte de información general.
FindComponent no es muy eficiente, al contrario es bastante lento.
Si lo usas mucho, lo más ágil es guardar una lista con los componentes creados (para eso va muy bien las TObjectList) y luego buscar el componente en esa lista en lugar de recorrerlos todos. Una variante, es usar un TStringList ordenada con el nombre del componente; De esa forma la búsqueda es dicotómica en lugar de secuencial.
Más eficiente cuantos más componentes tengamos..


La franja horaria es GMT +2. Ahora son las 09:56:50.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi