Search code examples
mfcdynamiccontrolscreation

Dynamically creating controls in MFC (Collection question)


I have some custom control inside of which i should create radiobuttons or checkboxes. The count of child controls is available only at runtime (it loads some file from which it gets this count). So i need to create variable number of controls. Which collection i should use for this purpose?

Solution 1: simply use std::vector<HWND> (or CArray<HWND>) - not suitable because i want use MFC (CButton). Of course i can Attach() and later Detach() handle to window each time i need this window, but it will give big overhead.

Solution 2: use std::vector<CButton*> or CArray<CButton*> or CList<CButton*> or... In this case i take care about making 'new' and appropriate 'delete' when control is unneeded. I am forgetful :)

MFC handle map contains pointer to CButton and i can't use simple CArray<CButton>, because it will move my objects each time when his size will grow.

... and the question is: Which collection i should use for containing variable count of MFC control classes?


Solution

  • If you only want to read your file with the Count parameter, create your buttons, work with them and later delete them all then CArray<CButton*> is fine in my opinion. To make sure the buttons get deleted you could wrap the CArray into a helper like:

    class CMyButtonArrayWrapper
    {
    public:
        CMyButtonArrayWrapper();
        virtual ~CMyButtonArrayWrapper();
    
        void ClearArray();
        void Add(CButton* theButton);
    
    private:
        CArray<CButton*> m_Array;
    }
    
    CMyButtonArrayWrapper::CMyButtonArrayWrapper()
    {
    }
    
    CMyButtonArrayWrapper::~CMyButtonArrayWrapper()
    {
        ClearArray();
    }
    
    void CMyButtonArrayWrapper::ClearArray()
    {
        for (int i=0; i<m_Array.GetSize(); i++)
        {
            CButton* aButton=m_Array.GetAt(i);
            if (aButton)
                delete aButton;
        }
        m_Array.RemoveAll();
    }
    
    void CMyButtonArrayWrapper::Add(CButton* theButton)
    {
        m_Array.Add(theButton);
    }
    

    Then add an object of this class as a member to your custom control (m_MyButtonArrayWrapper) and add your buttons with:

    CButton* aButton=new CButton;
    aButton->Create( ... );
    m_MyButtonArrayWrapper.Add(aButton);
    

    If you need to add and remove buttons randomly a CList might be better suited for performance reasons. (But you won't probably notice a performance difference using InsertAt/RemoveAt of CArray, except your UI has several thousands of buttons. I guess this would be more an artwork than a user interface :))