|
Prev: Remove title bar, but system menu still work
Next: How to move focus / active control using Enter key?
From: Joseph M. Newcomer on 13 May 2008 10:29 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 13 May 2008 10:32 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 13 May 2008 10:33 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 13 May 2008 21:44 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 13 May 2008 23:26 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
First
|
Prev
|
Pages: 1 2 Prev: Remove title bar, but system menu still work Next: How to move focus / active control using Enter key? |