Edit Control 编辑框控件之EN_KILLFOCUS消息使用 [大三TJB_708]

Edit Control控件的EN_KILLFOCUS消息即当鼠标光标从编辑控件内离开时对应的消息。利用此消息就可以在光标离开当前Edit Control编辑框后就判断刚刚的输入是否合理。如果不合理再将光标置回编辑框,如此直到用户输入合理为止。

对于多个Edit Control编辑框,如果彼此之间的输入都是独立而无逻辑关系联系的,那么利用Edit Control编辑框的EN_KILLFOCUS消息来判断单个Edit Control编辑框的输入是否合理是很简单的。但是如果多个编辑框之间的输入的数据之间含有逻辑关系则处理起来可就要分析分析了。
1 EN_KILLFOCUS消息宏的工作过程

如上图,这里有三个Edit Control编辑框,它们要求用户输入的含义分别表示财富、样貌及品格。且这三个编辑框用输入的数字代表财富、样貌及品格的大小,各编辑框输入大小要求的范围为[1, 98]三个编辑框内输入的值的总和要为100。随便从哪一个编辑框开始输入都可以。那么怎么用程序来实现需求呢?

撇开高级使代码精简的算法不谈,现就用最朴实的if..else语句来实现,用分支结构列举完所有的情况,那么在对每个Edit Control编辑框输入时都有三种情况需要考虑:

第一种:另外两个Edit Control编辑框编辑框的值都不为0即为空,此时需要考虑当前EditControl编辑框输入完毕后三者之和n + m + k是否为100。

第二种:两外两个Edit Control编辑框只有其中一个编辑框的值不为0,此时就对应两种情况,在这两种情况之下,都需要保证当前编辑框的值与不为0编辑框之和小于99。如果输入不合理,则需要将光标跳回刚刚输入的编辑框重新输入正确的值。

第三种:两外两个编辑框的值都还是0。此时只需要保证当前编辑框输入的值在[1, 98]之间即可,若不在此区间则将光标重新跳回来保证正确的输入。

为实现目标,为每个编辑框添加EN_KILLFOCUS类的Event Handler,最开始在以上三种情况下编写诸如以下的代码:

[cpp] view plaincopyprint?
::MessageBox( NULL, _T("财富 + 品格 <= 99"), _T("输入错误提示"), MB_OK ); 
 
//设置光标 
pEdit->SetFocus(); 
pEdit->SetSel( 0,CS_value.GetLength() ); 
 
//保证此次值不影响下次判断 
m_MordalDemand = 0;

让第一、二、三种情况作为if内的条件。设置光标两行代码表示将光标置回本编辑框中(之前有pEdit = (CEdit *)GetDlgItem( nID )代码,nID代表具体编辑框的ID),m_MoralDemand表示与对应编辑框输入转化而来的数值。结果,在输入不合理时就会弹出众多的由MessageBox弹出来的提示框,而且看提示内容,还不是一个编辑框内弹出来的错误提示。

分析EN_KILLFOCUS消息:从财富Edit Control编辑框输入完毕后按tab键使光标进入样貌Edit Control编辑框中,光标经图2的红线指向到样貌Edit Control编辑框中,当光标离开财富Edit Control编辑框时,财富Edit Control编辑框对应的EN_KILLFOCUS消息宏对应的响应函数就开始执行函数内的代码( 弹出提示框,将光标置回 ),将光标置回这代码一执行时,光标就要从样貌Edit Control编辑框回到财富Edit Control编辑框中,那么样貌Edit Control编辑框对应的EN_KILLFOCUS响应函数也要执行( 若样貌编辑框内已经输入了数据且加上财富内刚输入的数据就不再合理时就会执行 ),由于两个编辑框内EN_KILLFOCUS消息宏对应的效应函数内的代码雷同,所以光标就会在两个编辑框之间跳来挑去以至于两个函数不断的被执行而弹出多个聊天框。这段看起来很绕,但仔细分析一下就会明白。最终的结论是:这样的代码不科学,必须修改代码来避免这种情况

图2 EN_KIIFOCUS被不断地自动地激发
2 避免 EN_KILLFOCUS自动被激发

使用if…else分支语句来控制时,条件由列举式组成,若不再采用精简的算法,条件就不用修改了。需要考虑的是代码执行过程与EN_KILLFOCUS消息激发的顺序。这样想:如果在光标离开当前Edit Control编辑框时就发生数据的输入不合理,然后在将光标跳回来之前将当前编辑框对应的数据清0( 反正是这个数据引起的不合理,清0即清空也是应该的 ),那么光标从另一个编辑框跳回来时就不会再执行另一个编辑框EN_KILLFOCUS对应的响应函数,就只会提醒一次,并能够将光标置回来供重新输入,指导用户输入了正确的数据

在各if条件下对应的代码为:

[cpp] view plaincopyprint?
m_MordalDemand = 0; 
 
::MessageBox( NULL, _T("财富 + 品格 <= 99"), _T("输入错误提示"), MB_OK ); 
 
//设置光标 
pEdit->SetFocus(); 
pEdit->SetSel( 0,CS_value.GetLength() );

3 避免EN_KILLFOCUS的缺点

EN_KILLFOCUS消息的发生就是当光标离开当前Edit Control编辑框之际,如果用户想要修改以前的输入值,如财富输入80,样貌输入10,最后品格输入就必须要为10。而且还不能再修改,这就是EN_KIILFOCUS。为了避免这一点,可以在当三个Edit Control编辑框都有输入值且输入不对时将所有Edit Control编辑框的值清空并将光标置人某个Edit Control编辑框中供用户重新输入。实现如此功能的代码如下:

//---------------------------------------------- 
//当三者都输入完毕时,如果输入不合理则清除所有输入 
//----------------------------------------------- 
void CDMarriageMatchDlg::ClearDeamandInput() 
{ 
 CEdit *pEdit; 
 
 //各值清0 
 m_MordalDemand = 0; 
 m_MoneyDemand = 0; 
 m_MordalDemand = 0; 
 
 //各编辑框的值为NULL 
 pEdit = (CEdit*) GetDlgItem( IDC_MONEY_INPUT2 ); 
 pEdit->SetWindowText( _T("\0") ); 
 
 pEdit = (CEdit*) GetDlgItem( IDC_APPEAR_INPUT2 ); 
 pEdit->SetWindowText( _T("\0") ); 
 
 pEdit = (CEdit*) GetDlgItem( IDC_MORDAL_INPUT2 ); 
 pEdit->SetWindowText( _T("\0") ); 
 
 //设置光标 
 pEdit->SetFocus(); 
 pEdit->SetSel( 0,0 ); 
}

这段代码首先将所有编辑框输入值对应变量的值清为0,然后再顺次将各编辑框内的输入清空,并将光标置入ID为IDC_MORDAL_INPUT2的编辑框中。

在if条件为三个编辑框内都有值且输入有误时的调用就可以实现上述功能。

THE END
喜欢就支持一下吧
点赞11 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容