Click to See Complete Forum and Search --> : Imp: How can I make an array of CButton Control?
Shahzad
May 13th, 1999, 10:47 PM
I am making a calculator. I want to implement it like this:
I have 10 buttons from (0-9). When I press one of the button, the caption of the button is considered as the number selected. So I want to make an array of these buttons and hence the index number tell me also the selected number! I have already done this in VB.
How can I make an array of the control in MFC?
I can define it as:
CButton M_Button_Number[10];
but what about the resource ID of the buttons? Will they be same, or different?
please help!
Jason Teagle
May 14th, 1999, 02:24 AM
It depends on how you create the buttons. Just declaring the buttons in an array does not actually create them - you have to do this explicitly.
Instead, use the resource editor to put the buttons on the dialogue / form - this is a much neater method, as it allows the ClassWizard to see the IDs. Instead of giving them a text ID such as IDC_BUTTON3, give them a literal number; 13000 - 13009 for the digits 0 - 9, for example (make sure these ID numbers are not used elsewhere in your defined IDs - but this value should be pretty safe).
The only drawback is that you will have to add a command range manually. In the header file of the window class which owns the buttons (the dialogue or CFormView which is the parent of the buttons), add this:
afx_msg void OnCalculatorDigit(UINT uID);
It does not matter whether you add it within the message map area or not - the ClassWizard will not see it anyway.
In that class' code file, in the message map section, add this:
ON_COMMAND_RANGE(13000, 13009, OnCalculatorDigit)
(no trailing semicolon (';') ).
Finally, in the window class' code file add this routine:
---
void CMyDlgOrView::OnCalculatorDigit(UINT uID)
{
// If you now subtract 13000 from uID, it will give you 0 - 9: the
// digit that was clicked.
}
---
You do not really need an array of CButtons, but if you want to (and you want to use them as if they were member variables), create your array as you suggested, and then in OnInitDialog() (for a dialogue box, or OnIntialUpdate() for a CFormView), add this:
---
int n ;
for (n = 0 ; n < 10 ; n++)
M_Button_Number[n].SubclassDlgItem(13000 + n, this);
---
Now you can use the array like member variables.
Does that help?
Shahzad
May 17th, 1999, 12:17 AM
hi Jason
thanks alot for your help. I tried your technique but it has got a problem.
All that I wanted from my way of implementation is to avoid code for individual message handler for each and every button clicked, but this objective could not be met so far.
The problem is in
ON_CONTROL_RANGE(BN_CLICKED,13000,130009,OnCalculateDigit)
Although this enables me to write a collective code for all these button controls, yet I don't know, which button has been pressed by the user (it does not give me any index number)
The main motivation of this technique was the following single line code which i wrote in VB and which does everything that i need to do (what ever button I press, it records the correspond number that i have selected):
Private Sub Command2_Click(Index As Integer)
List1.AddItem Command2.Item(Index).Caption
End Sub
You have said to subtract ids in order to reach the particular control, thats good idea but first of all I should know which ID has been pressed, so that I subtract that from the first ID among the list.
Now, i have used instead individual msg handler function for all 10 button clicks (that I wanted to avoid). If you have any idea of getting somehow the index number of the selected button, please let me know. I will still go for that way, if I know it.
Jason Teagle
May 17th, 1999, 03:05 AM
The message map entry that I talked about was
ON_COMMAND_RANGE(13000, 13009, OnCalculatorDigit)
and NOT
ON_CONTROL_RANGE(BN_CLICKED, 13000, 13009, OnCalculatorDigit)
(I was not aware of the second form). However, BOTH are valid, and BOTH take the following form:
The declaration for the routine OnCalculatorDigit() INCLUDES the ID of the button pressed. In full, it is:
---
void CMyView::OnCalculatorDigit(UINT uID)
{
int Index ;
Index = uID - 13000 ;
// Now Index is like VB's parameter.
}
---
uID IS the ID of the button pressed, i.e., 13000 to 13009 in our example. This is almost equivalent to VB's Index variable.
Does that help now?
Shahzad
July 22nd, 1999, 04:58 PM
First v v sorry for so late response!
Thankx alot for your help. It is working the way I wanted.
I am having trouble in understanding the fact that how did OnCalculatorDigit(UINT uID) gets the parameter from the user directly? Normally we pass parameters to functions in a clear way but here how does the function know what is actually uID?
I mean when I am calling it, I don't give it any parameter.
Can you please help on this.
Black Racer
July 22nd, 1999, 05:26 PM
Hi,
I'm working on a calculator,too. Could you send me the SourcCode of yourone? I have my nearly ready (I must set a Accelrator, and so, but it's working)
black racer
Jason Teagle
July 23rd, 1999, 02:07 AM
OnCalculatorDigit() is just a name given to a routine. Whatever name we had given it, it would have had the same uID parameter - that is the form of a routine required for ON_CONTROL_RANGE() or similar. Basically, when the system detects a click on one of the digit buttons, it knows the ID of the clicked control. It therefore knows that it is within the range specified in ON_CONTROL_RANGE(). So, it passes control to a routine of the correct form (with the uID parameter), as named in the message map macro, and passes along the clicked ID.
You should not need to call this routine directly, the system handles it itself. However, if you feel the need to call it directly, you need to add 13000 to the digit which appears on the button (13005 for the button which says '5' - the 13000 is the difference between the actual ID of the button and the digit the button represents - in our example earlier in this thread, we used 13000 - 13009 for the button IDs) and pass that. For example, to simulate clicking the 8, say OnCalculatorDigit(13008). If you don't want to use a fixed ID, say OnCalculatorDigit(ID_BTN_DIGIT0 + 8) for button '8'.
Does this help?
Shahzad
August 9th, 1999, 05:59 AM
Yes.
Thankx a lot for you the help!
Shahzad
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.