Click to See Complete Forum and Search --> : Dynamically creating buttons and their actions?


rrubel
June 3rd, 1999, 03:01 PM
I've got a program where the number of possible buttons is known at compile time (a const, and may not always be true anyway), but the buttons themselves are created at run-time and placed on a CDialogBar. I can create all the buttons, but I cannot figure out how to attach functions to clicking the buttons. Since they're created at run-time, there's no way to use the Class Wizard to create a message map. This seems like it should have a trivial answer but darned if I can figure it out. I've tried subclassing, but couldn't even get a clean compile using

OldProc=(WNDPROC)SetWindowLong<font colo

Jaeyeon Lee
June 3rd, 1999, 07:39 PM
If the number of buttons are known, you can create the buttons at the design time, but set the property
invisible. When you need it, you can always make it visible by calling ShowWindow function.
This way, you can use class wizard as usual.

If the number is not known, you can add the handling function manually.

In the header file,
// Generated message map functions
//{{AFX_MSG(CTabForm)
afx_msg void YourHandlingFunction();
//}}AFX_MSG

In the implementation file,
BEGIN_MESSAGE_MAP(CTabForm, CFormView)
//{{AFX_MSG_MAP(CTabForm)
ON_COMMAND(ID_YOURBUTTON, YourHandlingFunction)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

and write code for YourHandlingFunction.

xingstar
June 3rd, 1999, 08:40 PM
Sorry to bother you. I also met the same problems. Could you please tell me how can you dynamically create the buttons? Thanks a lot.

rrubel
June 7th, 1999, 07:23 AM
My problem comes with the second half of the manual implementation - if I don't know ID_YOURBUTTON until runtime, how can I add the message map? Also, can I just arbitrarily make up an ID number (or range of numbers) and use them?
Thanks again...

Hussam
June 7th, 1999, 09:38 AM
Hello!

The best way is to override (inherite) CButton and then overload
ON_CONTROL_REFLECT(BN_CLICKED, OnClicked)

Now when you have implemented OnClicked or whatever you call your function, you are free to whatever you want when button is clicked.

I have done that and it works perfectly.

Good luck

Hussam

June 7th, 1999, 10:26 AM
I have encountered the same problem.
First you have to define an ID in ressource.h
[code]
#define ID_START 20000
[/ccode]
Then you have to create dynamically your controls and store pointers to these controls in a CArray to delete them later
[code]
CButton *p_Button=new CButton;
index=m_ButtonArray.Add(p_Button);

id=ID_START+1;
(m_ButtonArray.GetAt(index))-&gt;Create("Hello",WS_CHILD|BS_GROUPBOX|WS_VISIBLE,r,this,id);

id=id+1;
[/ccode]

To get the messages that come to the controls you must override the OnCommand function
[code]
BOOL CYourClass::OnCommand(WPARAM wParam, LPARAM lParam)
{
if((wParam&lt;=id) || (wParam&gt;(ID_START)))
return BoutClick(wParam);

return CFormView::OnCommand(wParam, lParam);
}

BOOL CSaisie_Util::BoutClick(int i)
{

if(i==id)
{
}
else
{
}
return TRUE;
}
[/ccode]

And don't forget yo delete the controls
[code]
int end;
CButton *p_Button;

end=m_ButtonArray.GetUpperBound();

for(int i=0;i&lt;=end;i++)
{
p_Button=m_ButtonArray.GetAt(i);
delete p_Button;
}
[/ccode]

Good luck !

rrubel
June 7th, 1999, 01:47 PM
Thank you - this seems to solve my problem nicely.
I appreciate the quick turnaround from all of you, and definitely learned some good stuff...