Thread: Using TObject class in Borland C++ Builder event handling

  1. #1
    Registered User
    Join Date
    Jun 2004
    Posts
    7

    Using TObject class in Borland C++ Builder event handling

    I'll give an example to illustrate what I want to do:

    Code:
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
        TButton* Button1 = new TButton(Form1);
        Button1->OnClick = func;
        Form1->InsertControl(Button1);
    
        TButton* Button2 = new TButton(Form1);
        Button2->OnClick = func;
        Form1->InsertControl(Button2);
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::func(TObject* Sender)
    {
        //What do I write here?
    }
    How could I implement func so that when the user clicks on Button1 or Button2, it changes the caption of the clicked button to "hello"? This seems to reduce to the problem of accessing the object whose address the Sender pointer holds. While the ClassName and ClassNameIs methods allow you to find out what class sends the OnClick message, I can't find any TObject methods that let you access the properties and methods of the clicked object. Can anybody help?

    Thanks!

  2. #2
    Code Monkey Davros's Avatar
    Join Date
    Jun 2002
    Posts
    812
    To answer your question, you could do this:

    Code:
    void __fastcall TForm1::func(TObject* Sender)
    {
      TButton* btn = dynamic_cast<TButton*> (Sender);
      if (btn != 0)
        btn->Caption = "Hello";
    }
    The dynamic_cast will set btn to NULL(0) if the Sender object is not of type TButton*.

    However, whatever you're trying to do, you're doing it wrong.

    If you create buttons in this way you're gonna have no way of destroying them. Also, InsertControl should not be used - use the Parent property instead.

    It would be much easier to create the buttons at design time, and simply hide or show them by changing the Visible property. If you want to create them at runtime, create a list to hold the pointers to runtime controls so you can ensure they are destroyed in forms destructor (do not use the form's OnDestroy event).
    OS: Windows XP
    Compilers: MinGW (Code::Blocks), BCB 5

    BigAngryDog.com

  3. #3
    Registered User
    Join Date
    Jun 2004
    Posts
    7
    Thanks, dynamic_cast looks like exactly what I was looking for.

    Regarding your other comments:
    I would not actually create buttons that way; in the program I am working on all of the panels are created at design time but the OnClick event is to be handled similarly for each panel and there are enough of them that writing a handler for each panel would be tedious and wasteful. Still, I'm not sure I agree that it's always best to create them at design time - as far as I know, that makes it impossible to fit them into data structures such as stacks or queues, and furthermore it could be very tedious to create large numbers of components manually.

    When I do employ runtime controls, I typically declare them in the given form's public or private area and instantiate them in the form's constructor. Is this enough to ensure that the form's destructor deletes them? Also, why do you recommend against deleting pointers in the form's OnDestroy event?

    Finally, what is the difference between assigning a form to an object's parent property and calling the form's InsertControl method, and why do you prefer the former over the latter?

    Thanks

  4. #4
    Code Monkey Davros's Avatar
    Join Date
    Jun 2002
    Posts
    812
    >When I do employ runtime controls, I typically declare them in the given form's public or private area

    Good stuff!

    Just in case you don't know, there's nothing stopping you having lots of design time controls and linking their events to a single handler.

    >what is the difference between assigning a form to an object's parent property and calling the form's InsertControl method, and why do you prefer the former over the latter?

    InsertControl (along with the Owner parameter in the objects constructor) are used by BCB in construction of design time objects. Here's what the Borland help says about InsertControl:

    "Applications should not need to call InsertControl directly. Child controls are automatically inserted and removed when added or deleted at design time. At runtime, use the Parent property of the child control to insert it in the Controls array. If the child control is already the child of another windowed control, setting the Parent property ensures that the child is removed from the Controls of the original parent."

    Here's another IMPORTANT point. Call this in your code:

    TButton* Button2 = new TButton((TComponent*)0);
    Button2->Parent = Form1;

    and ensure Button2 is destroyed somewhere in your code.

    Notice I've passed NULL into the TButton constructor. When you are destroying components yourself, they should not be owned. It will cause you errors later otherwise.
    OS: Windows XP
    Compilers: MinGW (Code::Blocks), BCB 5

    BigAngryDog.com

  5. #5
    Registered User
    Join Date
    Jun 2004
    Posts
    7
    All good to know! Thanks a lot for your help.

    -Paul

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Class design problem
    By h3ro in forum C++ Programming
    Replies: 10
    Last Post: 12-19-2008, 09:10 AM
  2. Defining derivated class problem
    By mikahell in forum C++ Programming
    Replies: 9
    Last Post: 08-22-2007, 02:46 PM
  3. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM
  4. gcc problem
    By bjdea1 in forum Linux Programming
    Replies: 13
    Last Post: 04-29-2002, 06:51 PM
  5. Difficulty superclassing EDIT window class
    By cDir in forum Windows Programming
    Replies: 7
    Last Post: 02-21-2002, 05:06 PM