Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Calling methods on Sender


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Jan 25, 2018 2:05 PM Last Post By: Paul Jackson
Paul Jackson

Posts: 61
Registered: 3/2/17
Calling methods on Sender  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 25, 2018 12:09 PM
Still using 10.2.1 C++ Builder.

So can anyone see what may be wrong with the following code excerpts. I have a form of type TQuickCall. I have another form of type TQuickCallSetApp. Simple case.

From the QuickCall form I have a button that calls the method btScheduledAppointmentClick which invokes the ShowModal method on the TQuickCallSetApp form. The QuickCallSetApp object has a method on a button btAddClick which makes a call back to QuickCall->SetAppointment, using the Sender ptr.

I have two members in TQuickCall,
 bool hasApp
and
 String theDate


When I debug and watch those members they are set properly in the QuickCall object as would be expected. But when I go to use them later in my code the boolean it's set back to 0 and theDate is garbage. The watch shows this too and I can't figure out why? The members are part of the calling object QuickCall and should persist until it is disposed.

TQuickCall
//************************************************************************************
void __fastcall TQuickCall::btScheduleAppointmentClick(TObject *Sender)
{
	QuickCallSetApp->ShowModal();
}
 
//************************************************************************************
void __fastcall TQuickCall::SetAppointment(String aDate,  bool aApp)
{
	theDate=aDate;
 	hasApp=aApp;
}


TQuickCallSetApp
//***********************************************************************
void __fastcall TQuickCallSetApp::btAddClick(TObject *Sender)
{
      ((TQuickCall*)Sender)->SetAppointment(Calendar->Date.DateString(), 1);
      Close();
}

Thanks for any help.
--
-Paul

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Calling methods on Sender  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 25, 2018 1:26 PM   in response to: Paul Jackson in response to: Paul Jackson
Paul Jackson wrote:

So can anyone see what may be wrong with the following code excerpts.

You are using the Sender parameter incorrectly.

From the QuickCall form I have a button that calls the method
btScheduledAppointmentClick which invokes the ShowModal method on the
TQuickCallSetApp form. The QuickCallSetApp object has a method on a
button btAddClick which makes a call back to
QuickCall->SetAppointment, using the Sender ptr.

That will not work, because the Sender of the OnClick event is the
object that is firing the event, ie the button that was clicked. Your
code compiles, but it is functionally wrong at runtime.

When I debug and watch those members they are set properly in the
QuickCall object as would be expected.

No, they are not, actually. TQuickCallSetApp is not accessing the
TQuickCall object correctly, so it is actually accessing random memory.

The Watch window displays class members based on whichever object
pointer you give it, but if that is the Sender pointer type-casted
incorrectly, the watch window won't know any better.

But when I go to use them later in my code the boolean it's set back
to 0 and theDate is garbage.

The watch shows this too and I can't figure out why?

Because you did not actually update the TQuickCall object at all.

For what you are attempting to do, you need to add a new member to
TQuickCallSetApp to point to the TQuickCall object that is currently
displaying it, eg:

void __fastcall TQuickCall::btScheduleAppointmentClick(TObject *Sender)
{
    QuickCallSetApp->QuickCall = this; // <-- add a member for this!
    QuickCallSetApp->ShowModal();
}


void __fastcall TQuickCallSetApp::btAddClick(TObject *Sender)
{
    this->QuickCall->SetAppointment(Calendar->Date.DateString(), 1);
    Close();
}


Personally, I wouldn't go this approach at all. Since you are closing
the QuickCallSetApp window anyway, I would have TQuickCall call its own
SetAppointment() on itself after ShowModal() has exited, eg:

void __fastcall TQuickCall::btScheduleAppointmentClick(TObject *Sender)
{
    if (QuickCallSetApp->ShowModal() == mrOk)
        SetAppointment(QuickCallSetApp->GetCalendarDate(), 1);
}
 
String __fastcall TQuickCallSetApp::GetCalendarDate()
{
    return Calendar->Date.DateString();
}
 
void __fastcall TQuickCallSetApp::btAddClick(TObject *Sender)
{
    ModalResult = mrOK;
 
    // or, just set the button's ModalResult property to mrOK
    // at design-time and not use this event at all...
}


--
Remy Lebeau (TeamB)
Paul Jackson

Posts: 61
Registered: 3/2/17
Re: Calling methods on Sender  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jan 25, 2018 2:05 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Excellent explanation Remy, thank you sir. I need to read up on the Sender ptr usage. Again thank you.

Remy Lebeau (TeamB) wrote:
Paul Jackson wrote:

So can anyone see what may be wrong with the following code excerpts.

You are using the Sender parameter incorrectly.

From the QuickCall form I have a button that calls the method
btScheduledAppointmentClick which invokes the ShowModal method on the
TQuickCallSetApp form. The QuickCallSetApp object has a method on a
button btAddClick which makes a call back to
QuickCall->SetAppointment, using the Sender ptr.

That will not work, because the Sender of the OnClick event is the
object that is firing the event, ie the button that was clicked. Your
code compiles, but it is functionally wrong at runtime.

When I debug and watch those members they are set properly in the
QuickCall object as would be expected.

No, they are not, actually. TQuickCallSetApp is not accessing the
TQuickCall object correctly, so it is actually accessing random memory.

The Watch window displays class members based on whichever object
pointer you give it, but if that is the Sender pointer type-casted
incorrectly, the watch window won't know any better.

But when I go to use them later in my code the boolean it's set back
to 0 and theDate is garbage.

The watch shows this too and I can't figure out why?

Because you did not actually update the TQuickCall object at all.

For what you are attempting to do, you need to add a new member to
TQuickCallSetApp to point to the TQuickCall object that is currently
displaying it, eg:

void __fastcall TQuickCall::btScheduleAppointmentClick(TObject *Sender)
{
    QuickCallSetApp->QuickCall = this; // <-- add a member for this!
    QuickCallSetApp->ShowModal();
}


void __fastcall TQuickCallSetApp::btAddClick(TObject *Sender)
{
    this->QuickCall->SetAppointment(Calendar->Date.DateString(), 1);
    Close();
}


Personally, I wouldn't go this approach at all. Since you are closing
the QuickCallSetApp window anyway, I would have TQuickCall call its own
SetAppointment() on itself after ShowModal() has exited, eg:

void __fastcall TQuickCall::btScheduleAppointmentClick(TObject *Sender)
{
    if (QuickCallSetApp->ShowModal() == mrOk)
        SetAppointment(QuickCallSetApp->GetCalendarDate(), 1);
}
 
String __fastcall TQuickCallSetApp::GetCalendarDate()
{
    return Calendar->Date.DateString();
}
 
void __fastcall TQuickCallSetApp::btAddClick(TObject *Sender)
{
    ModalResult = mrOK;
 
    // or, just set the button's ModalResult property to mrOK
    // at design-time and not use this event at all...
}


--
Remy Lebeau (TeamB)

--
-Paul
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02