jc64
asked on
MFC Programming(Edit Box Controls)
I have a dialog based application. The dialog has two edit boxes and one command button. I want the command button to be active only when both of the edit boxes are not empty.(If both edit boxes empty the button is disabled)
I added a subclass to the project that drives from CEdit and are tied to the Edit boxes. I added the following
handle
void CEditText::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
MessageBox("Key Pressed");
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
When a key is pressed "Key Pressed" is displayed as desired. But I can't now test the other input box to see if is empty.
What is the best approach for a solution.
Thank you.
I added a subclass to the project that drives from CEdit and are tied to the Edit boxes. I added the following
handle
void CEditText::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
MessageBox("Key Pressed");
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
When a key is pressed "Key Pressed" is displayed as desired. But I can't now test the other input box to see if is empty.
What is the best approach for a solution.
Thank you.
You can use either the EN_UPDATE or EN_CHANGE messages to determine when your edit box texts are about to change and have changed. From msdn:
The EN_CHANGE notification message is sent when the user has taken an action that may have altered text in an edit control. Unlike the EN_UPDATE notification message, this notification message is sent after the system updates the screen. The parent window of the edit control receives this notification message through a WM_COMMAND message.
~Lockias
The EN_CHANGE notification message is sent when the user has taken an action that may have altered text in an edit control. Unlike the EN_UPDATE notification message, this notification message is sent after the system updates the screen. The parent window of the edit control receives this notification message through a WM_COMMAND message.
~Lockias
I'd send a notification message to the window that holds the controls. It has a pointer to both the edit fields and the button, so it can decide whether to alter the button's state...
I'd use EN_CHANGE and handle it in the dialog - the classwizard will let you map this in the dialog without having to subclass your own controls
Hi there!!
I agree with the people who has suggested using EN_CHANGE method for edit control. It will be simple and easy way to do it. Just you need to add EN_CHANGE event for both the edit control using class wizard or other method. On changing any of the edit control .check the other edit control and see that it is empty . If both are not empty just enable the button. Like
void CXXX::OnEditChange1()
{
CButton *pButton = GetDlgItem(IDC_BUTTON1);
ASSERT(pButton != NULL);
CString csText2;
CString csText1;
CEdit *pEdit1 = GetDlgItem(IDC_EDIT1);
csText1 = pEdit1->GetWindowText();
CEdit *pEdit2 = GetDlgItem(IDC_EDIT2);
csText2 = pEdit2->GetWindowText();
if(!csText1.IsEmpty()&& csText2.IsEmpty())
pButton->EnableWindow(true );
}
void CXXX:OnEditChange2()
{
CButton *pButton = GetDlgItem(IDC_BUTTON1);
ASSERT(pButton != NULL);
CString csText2;
CString csText1;
CEdit *pEdit1 = GetDlgItem(IDC_EDIT1);
csText1 = pEdit1->GetWindowText();
CEdit *pEdit2 = GetDlgItem(IDC_EDIT2);
csText2 = pEdit2->GetWindowText();
if(!csText1.IsEmpty()&& csText2.IsEmpty())
pButton->EnableWindow(true );
}
I guess it will help you.
thanks
Keshav
I agree with the people who has suggested using EN_CHANGE method for edit control. It will be simple and easy way to do it. Just you need to add EN_CHANGE event for both the edit control using class wizard or other method. On changing any of the edit control .check the other edit control and see that it is empty . If both are not empty just enable the button. Like
void CXXX::OnEditChange1()
{
CButton *pButton = GetDlgItem(IDC_BUTTON1);
ASSERT(pButton != NULL);
CString csText2;
CString csText1;
CEdit *pEdit1 = GetDlgItem(IDC_EDIT1);
csText1 = pEdit1->GetWindowText();
CEdit *pEdit2 = GetDlgItem(IDC_EDIT2);
csText2 = pEdit2->GetWindowText();
if(!csText1.IsEmpty()&& csText2.IsEmpty())
pButton->EnableWindow(true
}
void CXXX:OnEditChange2()
{
CButton *pButton = GetDlgItem(IDC_BUTTON1);
ASSERT(pButton != NULL);
CString csText2;
CString csText1;
CEdit *pEdit1 = GetDlgItem(IDC_EDIT1);
csText1 = pEdit1->GetWindowText();
CEdit *pEdit2 = GetDlgItem(IDC_EDIT2);
csText2 = pEdit2->GetWindowText();
if(!csText1.IsEmpty()&& csText2.IsEmpty())
pButton->EnableWindow(true
}
I guess it will help you.
thanks
Keshav
kkarunakar - other people have also proposed the same solution - you have only padded someone elses solution (Lokias) - it is considered bad form to place an answer when people have already comented on the problem
Just a comment regarding GUI design:
In my opinion it's not good to disable this button.
Better output a message box when the user clicks the button without filling the editboxes.
If you only disable the button the user will not know what to do to make the button enabled.
In my opinion it's not good to disable this button.
Better output a message box when the user clicks the button without filling the editboxes.
If you only disable the button the user will not know what to do to make the button enabled.
Handle WM_KICKIDLE (include <afxpriv.h>) for your dialog.
Message map: ON_MESSAGE(WM_KICKIDLE, OnKickIdle)
//Add the code for OnKickIdle handler
void CMyDlg::OnKickIdle(WPARAM , LPARAM)
{
UpdateDialogControls(this, FALSE);
}
//Add a update command handler for the button in message map
ON_UPDATE_COMMAND_UI(IDC_B UTTON, OnUpdateBtn)
void CMyDlg::OnUpdateBtn(CCmdUI * pCmdUI)
{
CString str1,str2;
pEdit1->GetWindowText(str1 );
pEdit2->GetWindowText(str2 );
pCmdUI->Enable(!(str1.IsEm pty() && str2.IsEmpty()));
}
Message map: ON_MESSAGE(WM_KICKIDLE, OnKickIdle)
//Add the code for OnKickIdle handler
void CMyDlg::OnKickIdle(WPARAM , LPARAM)
{
UpdateDialogControls(this,
}
//Add a update command handler for the button in message map
ON_UPDATE_COMMAND_UI(IDC_B
void CMyDlg::OnUpdateBtn(CCmdUI
{
CString str1,str2;
pEdit1->GetWindowText(str1
pEdit2->GetWindowText(str2
pCmdUI->Enable(!(str1.IsEm
}
Hey ..
I have mentioned that in my answer.But i guess you need some form of code .So thought of putting some code with explanation.
Anyway, if it has helped you it is ok.Else regect the answer.
I have mentioned that in my answer.But i guess you need some form of code .So thought of putting some code with explanation.
Anyway, if it has helped you it is ok.Else regect the answer.
Fine, put some code. Just post it as a comment.
ASKER
I think the question is misunderstood. I am aware the existence of EN_UPDATE. I want to make a decision while I am in void CEditText::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) as explained in my original quation.
I have two input boxes and one button on the form. I have also another class CEditText which is subclass of CEdit. The two editboxes are tied to the CEditText::OnChar of CEditText class. I want when a user presses a key in one of the Editboxes to evaluate the key see if the other EditBox is empty and then enable or disable the command button.
So my problem is how should I access the other controls of on the form when a user presses a key in one of the EdirBoxes and I am transferred to CEditText::OnChar,
Sorry for the misunderstanding.
Please continue to add you best comment and I will only accept the one that answers my question whether someone locks it or not,
Thank you all.
I have two input boxes and one button on the form. I have also another class CEditText which is subclass of CEdit. The two editboxes are tied to the CEditText::OnChar of CEditText class. I want when a user presses a key in one of the Editboxes to evaluate the key see if the other EditBox is empty and then enable or disable the command button.
So my problem is how should I access the other controls of on the form when a user presses a key in one of the EdirBoxes and I am transferred to CEditText::OnChar,
Sorry for the misunderstanding.
Please continue to add you best comment and I will only accept the one that answers my question whether someone locks it or not,
Thank you all.
> I want to make a decision while I am in void CEditText::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) as explained in my original quation.
then in OnChar you will have to goto the parent window (the dialog) and look for the other window (GetDlgItem) becuase you are subclassing the control you will have to have 2 classes each one designed on the OnChar to look for the other one
This is not good design - you would be better of doing the work in the dialog since it knows about all the windows and gets all the relevant information and it will save you code and complication
then in OnChar you will have to goto the parent window (the dialog) and look for the other window (GetDlgItem) becuase you are subclassing the control you will have to have 2 classes each one designed on the OnChar to look for the other one
This is not good design - you would be better of doing the work in the dialog since it knows about all the windows and gets all the relevant information and it will save you code and complication
kkarunakar, I have rejected your proposed answer to return this question to the Open Question queue. Please do not post information that has been previously stated by others as an answer. This provides additional information in this regard.
https://www.experts-exchange.com/jsp/cmtyHelpDesk.jsp
https://www.experts-exchange.com/jsp/cmtyQuestAnswer.jsp
https://www.experts-exchange.com/jsp/infoMemberAgreement.jsp
As jc64 stated "Please continue to add you best comment and I will only accept the one that answers my question whether someone locks it or not," ... thus comments are preferred. jc64 can always accept any comment given that best suits the need.
Thank you.
Moondancer
Community Support Moderator @ Experts Exchange
https://www.experts-exchange.com/jsp/cmtyHelpDesk.jsp
https://www.experts-exchange.com/jsp/cmtyQuestAnswer.jsp
https://www.experts-exchange.com/jsp/infoMemberAgreement.jsp
As jc64 stated "Please continue to add you best comment and I will only accept the one that answers my question whether someone locks it or not," ... thus comments are preferred. jc64 can always accept any comment given that best suits the need.
Thank you.
Moondancer
Community Support Moderator @ Experts Exchange
ASKER
ShaunWilde, may be you have a better solution than I have now but I don't know what it is. I understand doing the work while on the dialog is better and easier but in my sitiation it is not possible as far as know.
Look, I want when someone presses a key in one of the editboxes to test the key and for instance if the key pressed is 'Y' to check if the other editbox is empty and if it is empty to ebale the command button if it is disabled.
You and everyone else agree that EN_UPDATE won't work as it is not cabable of passing the key pressed and other information.
That is why I used the subclass.
The EditBox controls are an array as
CString m_EditParam[2];
in the dialog class.
and here is the DoDataExchange
DDX_Text(pDX, IDC_EDIT1, m_EditParam[0]);
DDX_Text(pDX, IDC_EDIT2, m_EditParam[1]);
This is hand set and not from the ClassWizard. I mean I used the classWizard to create one and then I turned it to an array.
Now only one OnChar is called when either EditBox is keyed but when that happens control is transfered to the OnChar function which is out of the main Dialog class. But remember, I still need to access controls in the main dialog class. Now the quation is how. That is it.
Thank you.
Now
Look, I want when someone presses a key in one of the editboxes to test the key and for instance if the key pressed is 'Y' to check if the other editbox is empty and if it is empty to ebale the command button if it is disabled.
You and everyone else agree that EN_UPDATE won't work as it is not cabable of passing the key pressed and other information.
That is why I used the subclass.
The EditBox controls are an array as
CString m_EditParam[2];
in the dialog class.
and here is the DoDataExchange
DDX_Text(pDX, IDC_EDIT1, m_EditParam[0]);
DDX_Text(pDX, IDC_EDIT2, m_EditParam[1]);
This is hand set and not from the ClassWizard. I mean I used the classWizard to create one and then I turned it to an array.
Now only one OnChar is called when either EditBox is keyed but when that happens control is transfered to the OnChar function which is out of the main Dialog class. But remember, I still need to access controls in the main dialog class. Now the quation is how. That is it.
Thank you.
Now
if you handle EN_CHANGE then you can look at the contents of the edit box and see if there is a Y in it and then enable or disable
ASKER
ShaunWilde, I appreciate the effort but EN_CHANGE seems not to be able to do the job. How about if the Key is backspace or return key. The 'Y' was just an example I gave. I want to know the key pressed and make a decision.
Inside the EN_CHANGE is there a way I can determine the key pressed.
Thanks
Inside the EN_CHANGE is there a way I can determine the key pressed.
Thanks
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
At every tick of the timer check the contents of the two edit boxes.
If they have a non-zero length string, enable the button. Otherwise, disable it.