How to wxIsKindOf class check for a wxTextEntry derived classes? Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
tomay3000
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 207
Joined: Mon Apr 24, 2017 4:23 am

How to wxIsKindOf class check for a wxTextEntry derived classes?

Post by tomay3000 »

Hello,
I know that doing it for a wxTextCtrl should work, but I want to make it work for all wxTextEntry derivatives as well, so I can call wxTextEntry::Clear()

Here is my code that worked for wxTextCtrl, and I want to make it work for wxTextEntry once for all its derivatives:

Code: Select all

void MyFrame::Btn_VK_Clear_OnButtonClick(wxCommandEvent& WXUNUSED(event))
{
    if (m_pWndLastFocused)
    {
        m_pWndLastFocused->SetFocus();
    }

    //wxUIActionSimulator actionSimulator;
    //actionSimulator.Char(WXK_CLEAR);

    if (wxIsKindOf(m_pWndLastFocused, wxTextCtrl))
    {
        wxTextCtrl * const pTxtCtrlLastFocused = wxStaticCast(m_pWndLastFocused, wxTextCtrl);
        pTxtCtrlLastFocused->Clear();
    }

    // Process the resulting char events
    wxYield();
}
Any ideas on how to achieve this?
TIA.
User avatar
doublemax
Moderator
Moderator
Posts: 19161
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: How to wxIsKindOf class check for a wxTextEntry derived classes?

Post by doublemax »

I can't think of any elegant way using wxWidgets' RTTI. I would just write a small helper function that checks for all eight classes that derive from wxTextEntry. And if it's a match, cast the object to wxTextEntry.
Use the source, Luke!
tomay3000
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 207
Joined: Mon Apr 24, 2017 4:23 am

Re: How to wxIsKindOf class check for a wxTextEntry derived classes?

Post by tomay3000 »

doublemax wrote: Sat Jun 22, 2019 6:26 pm I can't think of any elegant way using wxWidgets' RTTI. I would just write a small helper function that checks for all eight classes that derive from wxTextEntry. And if it's a match, cast the object to wxTextEntry.
That is exactly what came to my mind, using like:

Code: Select all

bool wxHasTextEntry(const wxWindow *pWindow);
and

Code: Select all

wxTextEntry *wxGetTextEntry(const wxWindow *pWindow);
What I am struggling about is what kinda cast should I use!? wxDynamicCast or wxStaticCast?
TIA.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4204
Joined: Sun Jan 03, 2010 5:45 pm

Re: How to wxIsKindOf class check for a wxTextEntry derived classes?

Post by PB »

I am probably missing something here: wny not use C++ RTTI? I would just do

Code: Select all

wxTextEntry* te = dynamic_cast<wxTextEntry*>(m_pWndLastFocused);

if ( te )
   te->Clear();
I have just tested it and works as expected

Code: Select all

#include <wx/wx.h>

class MyDialog : public wxDialog
{
public:
    MyDialog() : wxDialog(NULL, wxID_ANY, "Test", wxDefaultPosition, wxSize(600, 600))
    {
        wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);

        wxCheckBox* checkBox = new wxCheckBox(this, wxID_ANY, "CheckBox");
        mainSizer->Add(checkBox, wxSizerFlags().Expand().Border());
        
        wxTextCtrl* textCtrl = new wxTextCtrl(this, wxID_ANY, "TextCtrl");
        mainSizer->Add(textCtrl, wxSizerFlags().Expand().Border());

        wxRadioButton* radioButton = new wxRadioButton(this, wxID_ANY, "RadioButton");
        mainSizer->Add(radioButton, wxSizerFlags().Expand().Border());

        wxComboBox* comboBox = new wxComboBox(this, wxID_ANY, "ComboBox");
        mainSizer->Add(comboBox, wxSizerFlags().Expand().Border());

        wxButton* button = new wxButton(this, wxID_ANY, "Clear Text Entries");            
        mainSizer->Add(button, wxSizerFlags().Expand().Border());
        Bind(wxEVT_BUTTON, &MyDialog::OnClearTextEntries, this);

        m_logCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
            wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);
        wxLog::SetActiveTarget(new wxLogTextCtrl(m_logCtrl));
        wxLog::SetTimestamp("");
        mainSizer->Add(m_logCtrl, wxSizerFlags().Proportion(1).Expand().DoubleBorder());

        SetSizer(mainSizer);
    }
private:        
    wxTextCtrl* m_logCtrl;

    void OnClearTextEntries(wxCommandEvent&)
    {                
        const wxWindowList& children = GetChildren();

        for ( wxWindowList::Node* node = children.GetFirst(); node; node = node->GetNext() )
        {
            wxWindow* window = dynamic_cast<wxWindow*>(node->GetData());
            wxTextEntry* te = dynamic_cast<wxTextEntry*>(window);

            wxLogMessage("Window type = %s, is derived from wxTextEntry: %s",
                window->GetClassInfo()->GetClassName(), te ? wxS("Yes") : wxS("No"));  

            if ( te && te != m_logCtrl )
            {
                wxLogMessage("Clearing value '%s'", te->GetValue());
                te->Clear();
            }
        }        
    }
};

class MyApp : public wxApp
{
public:
    bool OnInit()
    {
        MyDialog().ShowModal();
        return false;
    }
}; wxIMPLEMENT_APP(MyApp);
textentry.png
textentry.png (16.55 KiB) Viewed 1105 times
tomay3000
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 207
Joined: Mon Apr 24, 2017 4:23 am

Re: How to wxIsKindOf class check for a wxTextEntry derived classes?

Post by tomay3000 »

I can see from this post: https://stackoverflow.com/questions/159 ... d-of-macro,
Vadim Zeitlin is advising the use of wxDynamicCast() instead of wxIS_KIND_OF or wxIsKindOf.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4204
Joined: Sun Jan 03, 2010 5:45 pm

Re: How to wxIsKindOf class check for a wxTextEntry derived classes?

Post by PB »

The comment for wxDynamicCast says
// note that it still has different semantics from dynamic_cast<> and so can't
// be replaced by it as long as there are any compilers not supporting it
Do you really still use a compiler not supporting dynamic_cast? Perhaps it's time to upgrade it...

TBH, I do not see a reason for disabling C++ RTTI, I do not even know if MSVC supports that.

dynamic_cast also does not require all the custom controls you may use to use the wxDECLARE/IMPLEMENT_DYNAMIC_CLASS macros.
tomay3000
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 207
Joined: Mon Apr 24, 2017 4:23 am

Re: How to wxIsKindOf class check for a wxTextEntry derived classes?

Post by tomay3000 »

Actually the code won't compile at all using wxDynamicCast()

Code: Select all

||=== Build: Static Debug in S-SMS (compiler: GNU GCC Compiler) ===|
C:\Users\Tomay\Desktop\Projects\S-SMS\S_SMSMain.cpp||In member function 'virtual void S_SMSFrame::m_pBtn_VK_Clear_OnButtonClick(wxCommandEvent&)':|
C:\devel\wxWidgets\include\wx\object.h|147|error: invalid static_cast from type 'wxWindow*' to type 'const wxTextEntry*'|
C:\Users\Tomay\Desktop\Projects\S-SMS\S_SMSMain.cpp|1068|note: in expansion of macro 'wxDynamicCast'|
C:\devel\wxWidgets\include\wx\object.h|148|error: 'ms_classInfo' is not a member of 'wxTextEntry'|
C:\devel\wxWidgets\include\wx\object.h|148|note: in definition of macro 'wxDynamicCast'|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 5 second(s)) ===|
So I am forced to use dynamic_cast<>() instead.
And BTW I didn't know that wxDynamicCast() was invented to be used for weak old compilers.

I am using:

Code: Select all

gcc version 9.1.0 (Rev2, Built by MSYS2 project)
alys666
Super wx Problem Solver
Super wx Problem Solver
Posts: 329
Joined: Tue Oct 18, 2016 2:31 pm

Re: How to wxIsKindOf class check for a wxTextEntry derived classes?

Post by alys666 »

tomay3000 wrote: Sat Jun 22, 2019 7:12 pm That is exactly what came to my mind, using like:

Code: Select all

bool wxHasTextEntry(const wxWindow *pWindow);
and

Code: Select all

wxTextEntry *wxGetTextEntry(const wxWindow *pWindow);
What I am struggling about is what kinda cast should I use!? wxDynamicCast or wxStaticCast?
TIA.
you can use static_cast<SomeType *> if you are SURE that object can be really casted to it.
for example you have a list of A class objects, but have included there ONLY objects of derived class B.
because you're sure that there is no any object of class A, but B, you can cast statically.
Or, if before static_cast<B*> you can somehow check if instance is really of class B.
ubuntu 20.04, wxWidgets 3.2.1
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7480
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: How to wxIsKindOf class check for a wxTextEntry derived classes?

Post by ONEEYEMAN »

Hi,
tomay3000 wrote: Sat Jun 22, 2019 8:44 pm Actually the code won't compile at all using wxDynamicCast()

Code: Select all

||=== Build: Static Debug in S-SMS (compiler: GNU GCC Compiler) ===|
C:\Users\Tomay\Desktop\Projects\S-SMS\S_SMSMain.cpp||In member function 'virtual void S_SMSFrame::m_pBtn_VK_Clear_OnButtonClick(wxCommandEvent&)':|
C:\devel\wxWidgets\include\wx\object.h|147|error: invalid static_cast from type 'wxWindow*' to type 'const wxTextEntry*'|
C:\Users\Tomay\Desktop\Projects\S-SMS\S_SMSMain.cpp|1068|note: in expansion of macro 'wxDynamicCast'|
C:\devel\wxWidgets\include\wx\object.h|148|error: 'ms_classInfo' is not a member of 'wxTextEntry'|
C:\devel\wxWidgets\include\wx\object.h|148|note: in definition of macro 'wxDynamicCast'|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 5 second(s)) ===|
So I am forced to use dynamic_cast<>() instead.
And BTW I didn't know that wxDynamicCast() was invented to be used for weak old compilers.

I am using:

Code: Select all

gcc version 9.1.0 (Rev2, Built by MSYS2 project)
wxWidgets was written in late 1980 -early 1990, when not all compilers/devices supported everything and STL was not a de-facto a standard.

Thank you.
Post Reply