Toon posts:

[Borland C++] Undefined symbol 'Sender'

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik wil in een Memo veld een search en replace doen. Ik wil hier een functie voor maken die ik in een apparte unit zet en daar generiek kan aanroepen.

Ik heb het nu geregeld in de unit van het form en dan werkt het perfect, maar zoals ik al zei wil ik het hier weg hebben. Dit is de manier hoe ik het nu doe:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void __fastcall TForm1::bVervangenClick(TObject *Sender)
{
  TReplaceDialog *dlg = (TReplaceDialog *) Sender;

  while (huidig != NULL)
  {
    dlg->FindText = ("NAME");
    dlg->ReplaceText = ("piet");

    for (int i=0; i<=100; i++)
    {
      int SelPos = Form1->Memo1->Lines->Text.Pos(dlg->FindText);
      if (SelPos > 0)
      {
        Form1->Memo1->SelStart = SelPos - 1;
        Form1->Memo1->SelLength = dlg->FindText.Length();
        Form1->Memo1->SelText = dlg->ReplaceText;
      }
    }
  }
}


Als ik dit stuk code hier weg haal en in een andere unit plaats dan krijg ik de volgende foutmelding.

Undefined symbol 'Sender'

Volgens mij is Sender een loze variabele die Borland overal voor kan gebruiken (als ik het helemaal mis heb, wat is het dan wel?).

Die Sender werkt dus wel in de main unit maar niet in een apparte unit. Waarom niet?

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:42
[nohtml]
Verwijderd schreef op 16 januari 2003 @ 14:36:
Ik wil in een Memo veld een search en replace doen. Ik wil hier een functie voor maken die ik in een apparte unit zet en daar generiek kan aanroepen.

Ik heb het nu geregeld in de unit van het form en dan werkt het perfect, maar zoals ik al zei wil ik het hier weg hebben. Dit is de manier hoe ik het nu doe:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void __fastcall TForm1::bVervangenClick(TObject *Sender)
{
  TReplaceDialog *dlg = (TReplaceDialog *) Sender;

  while (huidig != NULL)
  {
    dlg->FindText = ("NAME");
    dlg->ReplaceText = ("piet");

    for (int i=0; i<=100; i++)
    {
      int SelPos = Form1->Memo1->Lines->Text.Pos(dlg->FindText);
      if (SelPos > 0)
      {
        Form1->Memo1->SelStart = SelPos - 1;
        Form1->Memo1->SelLength = dlg->FindText.Length();
        Form1->Memo1->SelText = dlg->ReplaceText;
      }
    }
  }
}


Als ik dit stuk code hier weg haal en in een andere unit plaats dan krijg ik de volgende foutmelding.

Undefined symbol 'Sender'
Het probleem zal niet zozeer aan die Sender liggen, maar aan het feit dat het een member functie is van TForm1.
Als je die code in een andere unit wilt zetten, die je overal wilt gebruiken, zal je dus die TForm1:: moeten weghalen.
Weet dan wel dat je binnen die functie niet meer zomaar aan de fields / componenten van instanties van TForm1 kunt.

Ik zou dus die method als volgt herschrijven in een andere unit:
code:
1
2
3
void Vervangen ( TReplaceDialog* rpdlg )
{
}
Volgens mij is Sender een loze variabele die Borland overal voor kan gebruiken (als ik het helemaal mis heb, wat is het dan wel?).

Die Sender werkt dus wel in de main unit maar niet in een apparte unit. Waarom niet?
Nee hoor, Sender is geen loze variable. Die Sender bevat een referentie naar het object die verantwoordelijk is voor die call.
(Trouwens, als het een loze variable is, waarom gebruik je die dan? :? )

https://fgheysels.github.io/


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Hint:
C++:
1
2
void __fastcall TForm1::bVervangenClick(TObject *Sender)
                                        ^^^^^^^^^^^^^^^

Als je dat ding in die andere functie (want unit boeit niet) niet declareert maar wel gebruikt is het toch redelijk logisch dat je een error krijgt....

[ Voor 9% gewijzigd door curry684 op 16-01-2003 15:04 ]

Professionele website nodig?


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:42
curry684 schreef op 16 January 2003 @ 15:04:
[...]

Hint:
C++:
1
2
void __fastcall TForm1::bVervangenClick(TObject *Sender)
                                        ^^^^^^^^^^^^^^^

Als je dat ding in die andere functie (want unit boeit niet) niet declareert maar wel gebruikt is het toch redelijk logisch dat je een error krijgt....


:?
Is toch gewoon een functie - parameter ?
* whoami snapt curry684 niet

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ik had er niet aan gedacht om de TReplaceDialog* dlg te declareren op de plaats waar ik de fuctie VervangTekst(...) aanroep en dan dlg als parameter mee te geven.

Op deze manier dus:
C++:
1
2
3
4
5
void __fastcall TForm1::bVervangenClick(TObject *Sender)
{
  TReplaceDialog *dlg = (TReplaceDialog *) Sender;
  
  VervangTekst(dlg, "NAME", "piet");


Dat werkt dus goed.

Maaaaaar.

Op deze manier werkt het ook en dat vind ik eigenlijk mooier. Want nu kan de declaratie van de TReplaceDialog ook in de functie staan.

Zo dus:

C++:
1
2
3
void __fastcall TForm1::bVervangenClick(TObject *Sender)
{
  VervangTekst(Sender, "DEVICE-NAME", huidig->Tdata.Get_DeviceName());

i.c.m.

C++:
1
2
3
void VervangTekst(TObject *Sender, AnsiString TeVervangen, AnsiString VervangenDoor)
{
  TReplaceDialog *dlg = (TReplaceDialog *) Sender;


Bedankt dus voor het advies heren.

[ Voor 45% gewijzigd door Verwijderd op 16-01-2003 16:00 . Reden: uitgebreid ]


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

whoami schreef op 16 januari 2003 @ 15:06:

[...]

:?
Is toch gewoon een functie - parameter ?
* whoami snapt curry684 niet
Een parameter is gewoon een luxe uitvoering van een lokale variabele. TS probeert de code te kopieren naar een andere method die die parameter niet heeft, en dus is Sender niet gedeclareerd zoals ik zei.

Errug basic stuff.

Professionele website nodig?


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:42
curry684 schreef op 16 januari 2003 @ 18:19:
[...]

Een parameter is gewoon een luxe uitvoering van een lokale variabele. TS probeert de code te kopieren naar een andere method die die parameter niet heeft, en dus is Sender niet gedeclareerd zoals ik zei.

Errug basic stuff.


Ah, de function-body kopieerde hij naar een andere functie die die parameter had. Ja, dan is het idd basic.
Ik dacht dat hij gewoon de volledige functie, incl. functie-definitie kopieerde naar een andere unit...

https://fgheysels.github.io/


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

Verwijderd schreef op 16 January 2003 @ 15:49:
C++:
1
2
3
void __fastcall TForm1::bVervangenClick(TObject *Sender)
{
  VervangTekst(Sender, "DEVICE-NAME", huidig->Tdata.Get_DeviceName());

i.c.m.
C++:
1
2
3
void VervangTekst(TObject *Sender, AnsiString TeVervangen, AnsiString VervangenDoor)
{
  TReplaceDialog *dlg = (TReplaceDialog *) Sender;

Bedankt dus voor het advies heren.
Dit is niet mooier want zo type-unsafe als de tyfus. Je weet dat het event altijd wordt aangeroepen met als sender ReplaceDialog, maar de VervangTekst-functie kan compleet verkracht worden met een willekeurige VCL-class als Sender. Correct is om het echt waterdicht te bouwen:
C++:
1
2
3
4
5
6
7
void __fastcall TForm1::bVervangenClick(TObject *Sender)
{
if(Sender->InheritsFrom(__classid(TReplaceDialog)))
  {
  VervangTekst((TReplaceDialog*)Sender, "DEVICE-NAME",
               huidig->Tdata.Get_DeviceName());
  }

i.c.m.
C++:
1
2
3
4
5
void VervangTekst(TReplaceDialog *Context, AnsiString TeVervangen, 
                  AnsiString VervangenDoor)
{
...
}

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

In meer portable C++ notatie is dat overigens:
C++:
1
2
3
4
5
6
7
8
9
void __fastcall TForm1::bVervangenClick(TObject *Sender)
{
TReplaceDialog*  Context = dynamic_cast<TReplaceDialog*>(Sender);

if(Context)
  {
  VervangTekst(Context, "DEVICE-NAME",
               huidig->Tdata.Get_DeviceName());
  }

Maar binnen VCL is InheritsFrom(...) imho de meest correcteaanpak.

Professionele website nodig?

Pagina: 1