Click to See Complete Forum and Search --> : Edit control, Question...


Braulio
April 29th, 1999, 06:50 AM
Hi,

I have a little problem with Edit control, I have one edit control for the user to enter one password, so I have:
****

And I want that when the user set the focus to that edit control and writes the first letter the edit control deletes its content and shows only the letter that the user has entered with the keyboard, I have tried somethings, but don't works, here is what I tried:

-> OnSetFocus, SetSel all the string ->But don't works, I don't know why... ( this is the ideal thing, but I don't know how to make it work)

-> When the user presses ( on change edit) the first time, I try to find de different character, and I delete the string and put the character ( the problem is that not always I'm able to know what character is the new), and another problem is that put the character, but the cursor is not in the end of the edit control, so the if the user wants to write fast ( "ABC"), it will do "BCA").

... Anybody can help me ? Thanks, Bye !
Braulio

tchung
April 29th, 1999, 07:14 AM
You can use Notification-Message, EN_SETFOCUS.
if you choose EN_SETFOCUS Messages in ClassWizard, then OnSetfocusXXX() function will appear.
In this function, type code like this


this->SetDlgItemText(IDC_EDIT1,"");




Is this what you want? I hope so.....

by nfuox

Braulio
April 29th, 1999, 07:45 AM
Thank But the problem then is that everytime the user put the focus on this password field its the password deleted, and I would like to do it only when the user wants to change the password ( presses one key on it), the best idea is to select all the text in OnSetFocus, but I have tried and I don't know why but it don't selects nothing ( only selects all the text by default, if the user presses double click or if he go with the tab key, with one click with the mouse it selects nothing ( put the focus, executes SetSel but nothing happens).

Can you help me a little bit more..., Thanks, Bye !
Braulio

sally
April 29th, 1999, 08:03 PM
SetSel should change...

can you show us how you call SetSel in your code please

Sally

Sally
April 29th, 1999, 08:03 PM
SetSel should change...

can you show us how you call SetSel in your code please

Sally

Braulio
April 30th, 1999, 01:28 AM
Hi !

I have tried in a lot of ways:

SetSel(0,Length_of_the_string)
SetSel(0,-1)

This things in normal cases works rights, but I think that the problem with do this on set focus, is that if it's presses with the mouse, after do this setfocus, then the application deletes what is selected.

Finally one of our friends of codeguru, has give me one solution, that is not so pretty as put the "blue" selected line, but it's very interesting, here goes:

BOOL CUserDlg::PreTranslateMessage(MSG* pMsg)
{
CEdit *pEdit = (CEdit *) GetDlgItem(IDED_PASSWORD);

if (pMsg->message == WM_CHAR) {
if (GetFocus() == pEdit && m_bNewFocusOnEditPwd) {
pEdit->SetWindowText("");
m_bBlankPassword = FALSE;
m_bPasswordChanged = TRUE;
m_bNewFocusOnEditPwd = FALSE;
}
}

return CDialog::PreTranslateMessage(pMsg);
}

With this, when the user tries to tpye something the first time that has setted the focus on it, the content of the edit control is deleted, and the new character that the user has typed is setted ( because we empty the content before this message is dispatched "?").

Thanks for your interest, Thanks, Bye !
Braulio

Rail Jon Rogut
April 30th, 1999, 01:56 AM
Is this a CEdit object created in your dialog with the resource editor, or do you create it at run time?

If you're using the resource editor, here's what I'd do:

Add the edit control to the dialog and give it the ID value IDED_PASSWORD and set it's style to Password.

Now run ClassWizard and under the member variables create a member variable for your edit control of type control and name it something like m_CtrlPassword. This will add a public member to your dialog class' header file, like:

CEdit m_CtrlPassword;

Now in ClassWizard, select the Message Maps tab and select IDED_PASSWORD in the Object ID's list and find the entry in Messages for EN_SETFOCUS and press Add Function, accept or change the suggested function name. This should create a function body for you - press Edit Code to go to the function body.

void CUserDlg::OnSetfocusPassword()
{
m_CtrlNewPath.SetSel(0, -1);

}

And that should do it.

Rail

Recording Engineer/Software Developer
Rail Jon Rogut Software
railro@earthlink.net
http://home.earthlink.net/~railro/

Rail Jon Rogut
April 30th, 1999, 02:01 AM
Oops... sorry I copied some test code from my system and didn't rename the variable:

void CUserDlg::OnSetfocusPassword()
{
m_CtrlNewPath.SetSel(0, -1);

}

should read:

void CUserDlg::OnSetfocusPassword()
{
m_CtrlPassword.SetSel(0, -1);
}

In the example I posted.

Rail

Recording Engineer/Software Developer
Rail Jon Rogut Software
railro@earthlink.net
http://home.earthlink.net/~railro/

Braulio
April 30th, 1999, 02:08 AM
I have tried this but don't works ( when the user sets the focus with the mouse with one single click), I don't know why, I have tried a more complicated thing, that don't shows the blue line but works ( it's not 100 % a solution but...), is:

BOOL CUserDlg::PreTranslateMessage(MSG* pMsg)
{
CEdit *pEdit = (CEdit *) GetDlgItem(IDED_PASSWORD);

if (pMsg->message == WM_CHAR) {
if (GetFocus() == pEdit && m_bNewFocusOnEditPwd) {
pEdit->SetWindowText("");
m_bBlankPassword = FALSE;
m_bPasswordChanged = TRUE;
m_bNewFocusOnEditPwd = FALSE;
}
}

return CDialog::PreTranslateMessage(pMsg);
}


I have learned a lot from this code, but is not the perfect solution, thanks, Bye !
Braulio

Rail Jon Rogut
April 30th, 1999, 02:17 AM
If the code I posted doesn't work, then something's a little strange...?? Have you changed the background colour or placed a bitmap on your dialog? If you use the code I posted, then you can't also have the PreTranslateMessage code in there as well...

The only time I've seen something similar to what you're describing is when I placed a bitmap on my dialog box and the background brush of the dialog or edit control was changed and the background wasn't being repainted correctly -- to overcome that, I had to adjust the brush accordingly.

Good luck.

Rail

Recording Engineer/Software Developer
Rail Jon Rogut Software
railro@earthlink.net
http://home.earthlink.net/~railro/

April 30th, 1999, 06:58 PM
I tried your exact code and it doesn't work on my machine either!!! It works if you TAB to the edit field, but not if you click with your mouse.

Rail Jon Rogut
April 30th, 1999, 08:40 PM
Okay,

I slightly misunderstood what he really wanted (that's what happens when I answer posts late at nite). To do what he wants requires that he subclass the CEdit control and look for WM_LBUTTONDOWN.

I've created a quick example project to show how to do it at my MFC Examples web page on my site:

http://home.earthlink.net/~railro/mfc_link.html

Look at Example 14.

Regards.

Rail

Recording Engineer/Software Developer
Rail Jon Rogut Software
railro@earthlink.net
http://home.earthlink.net/~railro/

sally
May 1st, 1999, 08:25 PM
Are you saying that OnSetFocus is ONLY called when someone TABs to a field and not when one clicks with the mouse in a field?

Sally

Sally
May 1st, 1999, 08:25 PM
Are you saying that OnSetFocus is ONLY called when someone TABs to a field and not when one clicks with the mouse in a field?

Sally

Rail Jon Rogut
May 2nd, 1999, 12:21 AM
No... whenever you click on an edit control, it receives focus - and when you Tab to the edit control it receives focus. However, to capture ths WM_LBUTTONDOWN message for the edit control, which differentiates between tabbing into the edit control vs. clicking in the edit control to set focus to the edit control... you have to subclass the edit control.

Rail

Recording Engineer/Software Developer
Rail Jon Rogut Software
railro@earthlink.net
http://home.earthlink.net/~railro/

May 2nd, 1999, 01:54 AM
Works great thanks!!!!

May 2nd, 1999, 02:37 AM
OK I tried your code and it worked OK, except that it didn't allow for normal text selection with the mouse. So I came up with a slightly diffrent method that only selects the text the first time the controll recieves focus. First you will need to change the OnLButtonDown handler in the CFocusEdit class like so

void CFocusEdit::OnLButtonDown(UINT nFlags, CPoint point)
{
if(this != GetFocus())
SetFocus();
else
CEdit::OnLButtonDown(nFlags, point);
}

Then you will need to impliment the OnSetfocus() for the edit controll like before

void CAboutDlg::OnSetfocusEdit1()
{
CEdit* pEC = (CEdit*)GetDlgItem(IDC_EDIT1);
pEC->SetSel(0, -1);
}

Like I said this allows the edit controll to be selected in full the first time it recieves focus, but also allows normal mouse selection by the user if needed.

Rail Jon Rogut
May 2nd, 1999, 11:25 AM
Well, I thought I'd leave that task to you guys... But now that you've shown me your solution, let me share mine....

Part of OOP is encapsulation, so you really want to keep everything inside the single class -- so when you reuse the CFocusEdit class, all you have to do is create an object of type CFocusEdit and include the header file.

So, in my example, just create a class member variable of type BOOL (let's call it m_bFocusFlag) and in the constructor make it FALSE -- then:

void CFocusEdit::OnLButtonDown(UINT nFlags, CPoint point)
{
CEdit::OnLButtonDown(nFlags, point);

if (!m_bFocusFlag)
{
SetSel(0, -1);
}

m_bFocusFlag = TRUE;
}

void CFocusEdit::OnKillfocus()
{
m_bFocusFlag = FALSE;
}

I updated the example on my web site to add this functionality.

(BTW - to change your name from Anonymous, edit your profile)

Rail

Recording Engineer/Software Developer
Rail Jon Rogut Software
railro@earthlink.net
http://home.earthlink.net/~railro/

May 2nd, 1999, 02:54 PM
Yes but the advantage to my solution is that it works no matter how the dialog recieves focus, your way only works when the user click on it with the mouse. However sticking with your OOP logic you could put the OnSetFocus() member into the CFocusEdit class, instead of the dialog class like so...

void CFocusEdit::OnLButtonDown(UINT nFlags, CPoint point)
{
if(this != GetFocus())
SetFocus();
else
CEdit::OnLButtonDown(nFlags, point);
}

void CFocusEdit::OnSetFocus(CWnd* pOldWnd)
{
CEdit::OnSetFocus(pOldWnd);
SetSel(0, -1);
}

This has the best of both worlds!!!

Dan

P.S. Even though I didn't post the original message this thread has helped me learn alot (I'm still pretty new at this.) Thanks for your help!!!

Rail Jon Rogut
May 2nd, 1999, 06:27 PM
Actually your code and mine now accomplish the same end result. There are only three ways that the edit control can receive focus. Either through a SetFocus() function call, the user Tabs to the control or the user left clicks inside the edit control. Actually there is one other way, if the user right clicks inside the edit control as well - and that normally brings up the contextual menu.

The first two methods are handled by the normal CEdit functionality, when you tab to a control or focus is passed to the control via a SetFocus() function call, then the contents of the edit control are selected. However, we added this functionality for the third method by subclassing CEdit and adding a message handler for WM_LBUTTONDOWN.

So, what I'm getting at, is that you really don't need to handle OnSetFocus() to highlight the contents, because by default that already happens.

Download my updated example and compare it to your code and see if there is any difference -- there shouldn't be.

Anyhow, glad to be of assistance :^)

Best regards.

Rail

Recording Engineer/Software Developer
Rail Jon Rogut Software
railro@earthlink.net
http://home.earthlink.net/~railro/