Dyanamically create controls

Hello, I have a big question for Visual C++ not sure where it goes...I want to find out how to create controls dynamically. The number of Edit controls needed is not known until runtime..

In a simple example...say you have a dialog box with 1 Edit control and 1 Button control...enter a number in the Edit control and once you click the Button, the number you entered will be the number of Edit controls to appear in the dialog..

This would only occur only once each time it was run..

I figure that I will have a CEdit array(member of the dialogs class?) that is initialized at runtime...I found that a CDialog object has a CreateControl(CWnd::CreateControl) method but the parameters are a little confusing...any suggestions would be appreciated...thanks..

- In your "create edits" button click handler, add this code:[code]// base ID for the new edit controls, make sure the number you choose// does not conflict with other control ID's already in the dialogconst int IDC_EDIT_CREATED1 = 2000;

// set the font m_pEditControls[i].SetFont(GetDlgItem(IDC_EDIT1)->GetFont()); }}[/code]

=============Second method: There's no need really to store the array of CEdit controls anywhere, you do not need them. Since you have the ID's, you can easily get the CWnd or HWND of the edit control you want through GetDlgItem whenever you need it. First method used that because doing something like:[code]for(int i = 0; i < nCount; i++){ CEdit edit; edit.CreateEx( something)}[/code]Wont work, edit's destructor gets called at the for loop } and we end up with our edit boxes getting destroyed as soon as we add them.

Solution to that is to use the Win32 API to create your controls through CreateWindowEx, later on, whenever you want a CEdit of any of them, you can just do:CEdit* pEdit = (CEdit*)GetDlgItem(id);

To use this, you need:- Forget about the CEdit* m_pEditControls member, we are not going to need that.

: Hello there,: : CreateControl is for creating ActiveX controls, so it wont help you here.: : Basically, there are 2 ways I can think of to achieve what you are looking for:: : ====================: First method: As you suggested, with an array of CEdit's.: : You need to do the following:: - In your CSomethingDlg .H file, add this:: private: CEdit* m_pEditControls;: : - In your CSomethingDlg constructor, add this:: m_pEditControls = NULL;: : - In your CSomethingDlg destructor, add this:: if(m_pEditControls != NULL) delete[] m_pEditControls;: : This is your array and its initialization/cleanup. Time to use it.: : - In your "create edits" button click handler, add this code:: [code]: // base ID for the new edit controls, make sure the number you choose: // does not conflict with other control ID's already in the dialog: const int IDC_EDIT_CREATED1 = 2000;: : // say, IDC_EDIT1 is the edit box where they enter the number of : // controls to create: int nCount = GetDlgItemInt(IDC_EDIT1, NULL, FALSE);: if(nCount > 0): {: CWnd* pEdit1 = GetDlgItem(IDC_EDIT1);: : // you probably want to use the same font in those new dialogs as the one already: // in IDC_EDIT1, so get it: CFont* pFont = pEdit1->GetFont();: : // also, you probably want to use the same width and height as well: CRect rc;: pEdit1->GetWindowRect(rc);: int nEditWidth = rc.Width();: int nEditHeight = rc.Height();: : // now allocate your array: m_pEditControls = new CEdit[nCount];: : // I'm going to assume the controls are created at position 0,0: // going down, change that to suit your need: : int y = 0;: for(int i = 0; i < nCount; i++): {: // position and size (notice, CWnd::CreateEx wants to rect as left, top, right, bottom: // unlike CreateWindow or CreateWindowEx where it should be left, top, width, height: CRect rect(0, y, 0 + nEditWidth, y + nEditHeight);: : m_pEditControls[i].CreateEx(: WS_EX_CLIENTEDGE,: "edit",: "",: WS_CHILD | WS_VISIBLE | WS_TABSTOP,: rect,: this,: IDC_EDIT_CREATED1 + i);: : y += nEditHeight * 2;: : // set the font: m_pEditControls[i].SetFont(GetDlgItem(IDC_EDIT1)->GetFont());: }: }: [/code]: : =============: Second method: There's no need really to store the array of CEdit controls anywhere, you do not need them. Since you have the ID's, you can easily get the CWnd or HWND of the edit control you want through GetDlgItem whenever you need it. First method used that because doing something like:: [code]: for(int i = 0; i < nCount; i++): {: CEdit edit;: edit.CreateEx( something): }: [/code]: Wont work, edit's destructor gets called at the for loop } and we end up with our edit boxes getting destroyed as soon as we add them.: : Solution to that is to use the Win32 API to create your controls through CreateWindowEx, later on, whenever you want a CEdit of any of them, you can just do:: CEdit* pEdit = (CEdit*)GetDlgItem(id);: : To use this, you need:: - Forget about the CEdit* m_pEditControls member, we are not going to need that.: : - In your "create edits" button click handler, use the same code from the first method, only change the loop to look like this:: [code]: int y = 0;: for(int i = 0; i < nCount; i++): {: HWND hWndEdit = ::CreateWindowEx(: WS_EX_CLIENTEDGE,: "edit",: "",: WS_CHILD | WS_VISIBLE | WS_TABSTOP,: 0,: y,: nEditWidth,: nEditHeight,: GetSafeHwnd(),: (HMENU)(IDC_EDIT_CREATED1 + i),: AfxGetInstanceHandle(),: NULL);: y += nEditHeight * 2;: : ::SendMessage(hWndEdit, WM_SETFONT, (WPARAM)pFont->GetSafeHandle(), 0);: }: [/code]: : Hope this help.s: