Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Violación en ejecución (https://www.clubdelphi.com/foros/showthread.php?t=91396)

Angel.Matilla 26-01-2017 19:35:22

Violación en ejecución
 
Para una aplicación en BCB 6 con una BB.DD. en Firebird tengo el formulario de la imagen.

Los botones señalados con una flechita son, como es evidente, ayudas del campo adjunto. Al pulsar sobre los botones señalados se despliega bajo el campo correspondiente una ayuda similar a la que se muestra con la información correspondiente. La misma se puede seleccionar (o esa es la idea) bien haciendo doble click sobre el valor bien pulsando la tecla Enter una vez seleccioando el valor.

Para dsplegar la ayuda uso un TListBox que está definido en el .h del formulario, al igual que los eventos asociados, y que despliego así:
Código PHP:

void __fastcall TfPersona::BotAyu(TObject *Sender)
{
     
POINT P1P2;
     
TBitBtn *Boton;
    
TComponent *Source;
     
TNotifyEvent OnExit_;

    for (
nItem 0nItem this->ComponentCountnItem ++)
     {
          
Source this->FindComponent("AyuLis");
          if (
Source != NULL)
               return;
     }

    for (
nItem 0nItem this->ComponentCountnItem ++)
     {
        
Source this->Components[nItem];
          if (!
Source->ClassNameIs("TBitBtn"))
               continue;

          
Boton static_cast<TBitBtn *>(Source);
          
Boton->OnClick NULL;
     }

     
Boton dynamic_cast<TBitBtn *>(Sender);
    for (
nItem 0nItem this->ComponentCountnItem ++)
     {
          
Source this->FindComponent(Boton->Name.SubString(2Boton->Name.Length()));
          if (
Source != NULL)
               if (
Source->ClassNameIs("TEdit") || Source->ClassNameIs("TLabeledEdit"))
               {
                    
AyuEdit static_cast<TCustomEdit *>(Source);
                    if (
Source->Name == "Afiliacion")
                         
Afiliacion->OnExit NULL;
                    else if (
Source->Name == "ForPago")
                         
ForPago->OnExit NULL;
                    else if (
Source->Name == "Iban")
                         
Iban->OnExit NULL;
                    else if (
Source->Name == "Junta")
                         
Junta->OnExit NULL;
                    else if (
Source->Name == "Pais")
                         
Pais->OnExit NULL;
                    else if (
Source->Name == "PerPago")
                         
PerPago->OnExit NULL;
                    else if (
Source->Name == "Profesion")
                         
Profesion->OnExit NULL;
                    else if (
Source->Name == "Provincia")
                         
Provincia->OnExit NULL;
                    else if (
Source->Name == "Situacion")
                         
Situacion->OnExit NULL;
                    break;
               }
     }

     if (
Source == NULL)
          return;

     
P1.AyuEdit->Left;
     
P1.AyuEdit->Top;
     
P2   this->ScreenToClient(AyuEdit->Parent->ClientToScreen(P1));

     
Query->Close();

     
AyuLis              = new TListBox(this);
     
AyuLis->Name        "AyuLis";
     
AyuLis->Parent      this;
     
AyuLis->BevelInner  bvNone;
     
AyuLis->BevelKind   bkFlat;
     
AyuLis->BevelOuter  bvLowered;
     
AyuLis->BorderStyle bsNone;
     if (
AyuEdit->Name == "Situacion" || AyuEdit->Name == "ForPago" || AyuEdit->Name == "PerPago")
     {
          
AyuLis->Height AyuLis->ItemHeight;

          
Query->SQL->Text "SELECT Literal FROM Instalacion WHERE Etiqueta = :Etiqueta ORDER BY Literal";
          
Query->ParamByName("Etiqueta")->AsString AyuEdit->Name;
     }
     else
     {
          if (
AyuEdit->Name == "Afiliacion")
               
AyuLis->Height AyuLis->ItemHeight;
          else
               
AyuLis->Height 10 AyuLis->ItemHeight;

          
Query->SQL->Text "SELECT Nombre";
          if (
AyuEdit->Name == "Iban")
               
Query->SQL->Text "SELECT Nombre||' ('||Codigo||')' FROM Bancos";
          else
               
Query->SQL->Text "SELECT Nombre FROM " AyuEdit->Name;
          if (
AyuEdit->Name != "Iban" && AyuEdit->Name != "Pais" && AyuEdit->Name != "Provincia")
               
Query->SQL->Add("WHERE CodPrv = (SELECT Literal FROM Instalacion WHERE Etiqueta = 'Provincia')");
          
Query->SQL->Add("ORDER BY Nombre, Codigo");
     }
     
AyuLis->Left       P2.x;
     
AyuLis->Top        P2.AyuEdit->Height;
     
AyuLis->Width      AyuEdit->Width Boton->Width;
     
AyuLis->OnDblClick AyuLisClick;
     
AyuLis->OnKeyPress AyuLisKeyPress;

     
Query->Open();
     
AyuLis->Items->Clear();
     for (; !
Query->EofQuery->Next())
          
AyuLis->Items->Add(Query->Fields->FieldByNumber(1)->AsString);
     
AyuLis->Visible true;
     
AyuLis->SetFocus();

     if (
Source->Name == "Afiliacion")
          
Afiliacion->OnExit AfiliacionExit;
     else if (
Source->Name == "ForPago")
          
ForPago->OnExit SituacionExit;
     else if (
Source->Name == "Iban")
          
Iban->OnExit IbanExit;
     else if (
Source->Name == "Junta")
          
Junta->OnExit JuntaExit;
     else if (
Source->Name == "Pais")
          
Pais->OnExit PaisExit;
     else if (
Source->Name == "PerPago")
          
PerPago->OnExit SituacionExit;
     else if (
Source->Name == "Profesion")
          
Profesion->OnExit ProfesionExit;
     else if (
Source->Name == "Provincia")
          
Provincia->OnExit ProvinciaExit;
     else if (
Source->Name == "Situacion")
          
Situacion->OnExit SituacionExit;
}
//--------------------------------------------------------------------------- 

En los dos eventos asociados al TListBox (OnDblClick y OnKeyPress) tengo este codigo:
Código PHP:

void __fastcall TfPersona::AyuLisClick(TObject *Sender)
{
     
TBitBtn *Boton;
    
TComponent *Source;

     if (
AyuLis->ItemIndex 0)
          return;

     
cAux AyuLis->Items->Strings[AyuLis->ItemIndex];
     if (
AyuEdit->Name == "Iban")
     {
          
NomBan->Text      cAux.SubString(1cAux.Pos("(") - 1).Trim();
          
AyuEdit->Text     cAux.SubString(cAux.Pos("(") + 14);
          
AyuEdit->SelStart 5;
     }
     else
     {
          
AyuEdit->Text cAux;
          
Query->Close();
          if (
AyuEdit->Name == "ForPago" || AyuEdit->Name == "PerPago" || AyuEdit->Name == "Situacion")
          {
               
Query->SQL->Text "SELECT Valor FROM Instalacion WHERE Etiqueta = :Etiqueta AND Literal = :Literal";
               
Query->ParamByName("Etiqueta")->AsString AyuEdit->Name;
               
Query->ParamByName("Literal")->AsString  AyuEdit->Text;
          }
          else
          {
               
Query->SQL->Text "SELECT Codigo FROM " AyuEdit->Name " WHERE Nombre = :Nombre";
               if (
AyuEdit->Name != "Provincia" && AyuEdit->Name != "Pais")
                    
Query->SQL->Add("AND CodPrv = (SELECT Literal FROM Instalacion WHERE Etiqueta = 'Provincia')");
               
Query->ParamByName("Nombre")->AsString  AyuEdit->Text;
          }
          
Query->Open();
          if (
AyuEdit->Name == "Pais")
               
AyuEdit->Tag 100 *  Query->Fields->FieldByNumber(1)->AsString.c_str()[0] +  Query->Fields->FieldByNumber(1)->AsString.c_str()[1];
          else
               
AyuEdit->Tag Query->Fields->FieldByNumber(1)->AsInteger;
     }

     for (
nItem 0nItem this->ComponentCountnItem ++)
          if (
this->Components[nItem]->ClassNameIs("TListBox") && this->Components[nItem]->Name == "AyuLis")
          {
               
delete AyuLis;
               break;
          }

     for (
nItem 0nItem this->ComponentCountnItem ++)
     {
          
Source this->Components[nItem];
          if (!
Source->ClassNameIs("TBitBtn"))
               continue;

          
Boton static_cast<TBitBtn *>(Source);
          if (
Boton->OnClick == NULL)
          {
               if (
Boton->Name == "aPoblacion")
                    
Boton->OnClick aPoblacionClick;
               else if (
Boton->Name == "Button1")
                    
Boton->OnClick Button1Click;
               else
                    
Boton->OnClick BotAyu;
          }
     }
     
AyuEdit->SetFocus();
}
//--------------------------------------------------------------------------- 

Se ejecuta bien, selecciona el valor indicado y todo pero al seleccionar el valor deseado en la ayuda en algunos campos me da un mensaje de error:

Si le doy al botón de aceptar continúa la ejecución sin ningún problema pero ya no sé dónde buscar que está provocando este error. He tratado de seguirle la pista con el depurador ejecutando línea a línea, pero en algún sitio se me pierde o me pierdo yo :(.

Se admite cualquier sugerencia. Si alguno quiere ayudarme puedo enviarle el código y la base de datos asociada (evidentemente capada).

AgustinOrtu 26-01-2017 20:15:48

Haz probado la depuracion usando los debug dcu? Para C++ parece que necesitas estos pasos aunque nunca lo he probado

De esta manera, le indicas al compilador que utilice la VCL en modo "debug" en lugar de "release", y te permite llegar mas a fondo dentro del codigo fuente. Salvo es raras condiciones (API externas, mal-uso de frameworks, abuso de reference counting, threads) los Access Violation son relativamente faciles de cazar y el depurador siempre ayuda muchisimo

Sino la otra forma es ir poniendo "ShowMessage" a medida que vas avanzando asi ves "hasta donde llega el codigo" y poder localizar el lugar donde falla

Mirarlo a simple vista es muy complicado porque el codigo es demasiado largo y muy complejo para los meros mortales :)

Neftali [Germán.Estévez] 27-01-2017 08:25:30

Si ejecutas paso a paso, aunque no llegues a la línea exacta, pero tal vez si llegues a la línea que provoca el error.
A veces es una línea que provoca el "salto" de un evento asociado. Si consigues saber la línea que se ejecuta antes de provocar el error, puedes buscar eventos asociados.


La franja horaria es GMT +2. Ahora son las 03:36:40.

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