From: Joseph M. Newcomer on
Well, the reason the code doesn't put the focus back where you want it is that, well, the
code DOESN'T put the focus back where you want it! Where, exactly, did you do anything
that would result in the focus going anywhere?

First observation: if the field values are not correct, why is the OK button enabled? You
should not enable it unless there is a valid set of fields.

I would handle this as I describe in my essay on dialog control management:

void CMochikoshiDlg::updateControls()
{
c_OK.EnableWindow(
!m_edt_mochi_date_year.IsEmpty() &&
!m_edt_mhoci_date_month.IsEmpty() &&
!m_edt_mochi_date_day.IsEmpty());
}

then you would add EN_CHANGE notifications

void C...Dlg::OnChangeMochiDateYear()
{
updateControls();
}
....etc.

If the fields are not OK, the OK button should be disabled! It makes no sense to click it
if the fields are not correct.

In the updateControls function, you can do things like show an error message (in a
CStatic) that says that the fields are incomplete. I've even used a tooltip, hovering
over the OK button that is disabled shows a tooltip saying there is a missing year field;
if the year field is filled in and the month field is empty, it says there is no month
field, etc. If all fields are valid, the tooltip says "Accept changes" or something
appropriate.

If you want to set the focus back to a control, there is a SetFocus method you must call
to do this!

For example:

CString s;
c_Year.GetWindowText(s);
s.Trim();
if(s.IsEmpty())
{
c_Year.SetFocus();
return;
}
c_Month.GetWindowText(s);
s.Trim();
if(s.IsEmpty())
{
c_Month.SetFocus();
return;
}

etc.

The use of string variables suggests you are using UpdateData to store the values. I
consider this a fundamental design error, and do my best to avoid ever seeing an
UpdateData anywhere in code (I have a reasonable confidence that if UpdateData appears in
a dialog, the code is wrong, and I've been right often enough that if I ever see it, I
remove it and replace it with appropriate requests to obtain values from the controls.
joe

On Tue, 13 May 2008 01:00:01 -0700, Landon <Landon(a)discussions.microsoft.com> wrote:

>I have a form with 3 CEdit which are Year, Month and Day fields.
>
>If one of them is empty and user click OK or press Enter, an error message
>will displayed and the focus will back on where it was.
>
>I have tried this code but it won't focused back on where it was, it just
>back to the form but nothing is focused.
>
>void CMochikoshiDlg::OnOK()
>{
> // TODO: ?????????????????????????
> if ( m_edt_mochi_date_year.IsEmpty() || m_edt_mochi_date_month.IsEmpty() ||
>m_edt_mochi_date_day.IsEmpty() ) {
> MessageBox( "Error" );
> return;
> }
> CDialog::OnOK();
>}
>
>How to do that?
>
>Thank you very much.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
It is very poor style to use GetDlgItem in this case; its use should be restricted to very
special, rare, and exotic circumstances, of which this is not one. Create control
variables for your controls.

c_Year.SetFocus()

as to the "right" edit control, it will set the focus to the edit control you tell it to
set the focus to. If you want to set the focus to the year control, it will set the focus
to the year control. That's it.

Setting focus back to controls after clicking OK is generally poor style; it is far better
not disable the OK button until all the fields are filled in!

Assume the following: if you write GetDlgItem, you have made a coding error. Eventually,
you will discover the very rare and exotic circumstances where you need to do this, and
this is certainly not one of them.
joe

On Tue, 13 May 2008 02:24:01 -0700, Landon <Landon(a)discussions.microsoft.com> wrote:

>> You can use GetDlgItem to get the edit box by its id, then call SetFocus on
>> it.
>> Another way is that you can utilize dynamic data exchange of MFC to check if
>> the data of one control is valid.
>>
>> Thanks
>> Robert
>
>Will it focus to the right CEdit control? I mean if there are 5 CEdit for
>example, when I was on the 3rd CEdit, I click OK or Enter then it should be
>back to CEdit number 3 right? Does the GetDlgItem make this possible?
>
>Thank you very much.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on
I believe the fundamental approach is wrong. Keep the OK button disabled until all the
fields are filled in.
joe

On Tue, 13 May 2008 03:29:03 -0700, Landon <Landon(a)discussions.microsoft.com> wrote:

>"robert" wrote:
>
>> Maybe you don't need to check its data until you click the OK button, and do
>> that when the control lost the focus.
>> This is some part of the idea of DDX.
>> Otherwise, you need to save the last control with focus, right?
>
>I don't understand with your explanation above, can you be more specific?
>
>According to you, how is the best way to solve my problem?
>
>Thank you very much.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: James Duy Trinh on
Hi Landon,

You can do this, remember the focused control before MessageBox

void CMochikoshiDlg::OnOK()
{
CWnd *pFocusedWnd = GetFocus();
// you show msgbox here
MessageBox( "Error" );

if (pFocusedWnd )
pFocusedWnd ->SetFocus();
}
"Landon" <Landon(a)discussions.microsoft.com> wrote in message
news:AF41CFE3-F595-4552-BD53-3CCA204664CA(a)microsoft.com...
>> You can use GetDlgItem to get the edit box by its id, then call SetFocus
>> on
>> it.
>> Another way is that you can utilize dynamic data exchange of MFC to check
>> if
>> the data of one control is valid.
>>
>> Thanks
>> Robert
>
> Will it focus to the right CEdit control? I mean if there are 5 CEdit for
> example, when I was on the 3rd CEdit, I click OK or Enter then it should
> be
> back to CEdit number 3 right? Does the GetDlgItem make this possible?
>
> Thank you very much.


From: Joseph M. Newcomer on
And guess where the focus is when the OK button is clicked? THe OK button has the focus.
Whoops.

You have to track all kinds of interesting state, such as when the OK button gets focus,
figuring out what button had the old focus, and retaining that. After trying this kind of
nonsense for a couple years, I gave up, and stopped ever trying to do anything like this.
Key is not not enable the OK button until the preconditions are met. That is the sensible
approach. In fact, I'm beginning to detest modal dialogs more and more. I would very
much like to get modeless file dialogs, modeless font dialogs, modeless color dialogs,
etc. Adding a MessageBox adds gratuitous modality where none should exist.
joe

On Wed, 14 May 2008 08:44:54 +0700, "James Duy Trinh" <vietdoor(a)gmail.com> wrote:

>Hi Landon,
>
>You can do this, remember the focused control before MessageBox
>
>void CMochikoshiDlg::OnOK()
>{
> CWnd *pFocusedWnd = GetFocus();
> // you show msgbox here
> MessageBox( "Error" );
>
> if (pFocusedWnd )
> pFocusedWnd ->SetFocus();
>}
>"Landon" <Landon(a)discussions.microsoft.com> wrote in message
>news:AF41CFE3-F595-4552-BD53-3CCA204664CA(a)microsoft.com...
>>> You can use GetDlgItem to get the edit box by its id, then call SetFocus
>>> on
>>> it.
>>> Another way is that you can utilize dynamic data exchange of MFC to check
>>> if
>>> the data of one control is valid.
>>>
>>> Thanks
>>> Robert
>>
>> Will it focus to the right CEdit control? I mean if there are 5 CEdit for
>> example, when I was on the 3rd CEdit, I click OK or Enter then it should
>> be
>> back to CEdit number 3 right? Does the GetDlgItem make this possible?
>>
>> Thank you very much.
>
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm