mfc保持两个edit control的一致性
两个edit control,比如半径R,周长L,需要保证R改变,L随之更改;L改变,R随之更改。
查了下,发现edit有一个EN_CHANGE消息,每当一个edit有更改,会发送一个EN_CHANGE消息。因此在两个edit上均添加这样一个消息处理函数,去更改另一个edit即可。
代码如下:
1 //R的消息处理函数 2 OnEnChangeEditR() 3 { 4 // TODO: 如果该控件是 RICHEDIT 控件,它将不 5 // 发送此通知,除非重写 CDialogEx::OnInitDialog() 6 // 函数并调用 CRichEditCtrl().SetEventMask(), 7 // 同时将 ENM_CHANGE 标志“或”运算到掩码中。 8 9 10 11 // TODO: 在此添加控件通知处理程序代码 12 CString RS,LS; 13 double R,L; 14 GetDlgItemText(IDC_EDIT_R,RS); 15 R=atof(RS); 16 L=2*3.14159*R; 17 LS.Format("%.2f",L); 18 SetDlgItemText(IDC_EDIT_L,LS); 19 } 20 //L的消息处理函数 21 OnEnChangeEditL() 22 { 23 // TODO: 如果该控件是 RICHEDIT 控件,它将不 24 // 发送此通知,除非重写 CDialogEx::OnInitDialog() 25 // 函数并调用 CRichEditCtrl().SetEventMask(), 26 // 同时将 ENM_CHANGE 标志“或”运算到掩码中。 27 28 29 30 // TODO: 在此添加控件通知处理程序代码 31 CString RS,LS; 32 double R,L; 33 GetDlgItemText(IDC_EDIT_L,LS); 34 L=atof(LS); 35 R=L/(2*3.14159); 36 RS.Format("%.2f",R); 37 SetDlgItemText(IDC_EDIT_R,RS); 38 }
跑了两次都挂了。debug了下发现是SetDlgItemText会发送ON_ENCHANGE消息,两个处理函数反复互相调用导致陷入死循环。
要想破解死循环,需要在处理函数中辨识是否从另一个处理函数而来,如果是的话就直接返回。因此加两个布尔变量的标记,fromR和fromL,初始值为false。代码如下:
1 OnEnChangeEditR() 2 { 3 // TODO: 如果该控件是 RICHEDIT 控件,它将不 4 // 发送此通知,除非重写 CDialogEx::OnInitDialog() 5 // 函数并调用 CRichEditCtrl().SetEventMask(), 6 // 同时将 ENM_CHANGE 标志“或”运算到掩码中。 7 8 9 10 // TODO: 在此添加控件通知处理程序代码 11 //破解死循环,如果是从OnEnChangeEditL过来,则直接返回 12 if(fromL) 13 { 14 fromL=false; 15 return; 16 } 17 18 19 // TODO: 在此添加控件通知处理程序代码 20 CString RS,LS; 21 double R,L; 22 GetDlgItemText(IDC_EDIT_R,RS); 23 R=atof(RS); 24 L=2*3.14159*R; 25 LS.Format("%.2f",L); 26 fromR=true; 27 SetDlgItemText(IDC_EDIT_L,LS); 28 } 29 30 OnEnChangeEditL() 31 { 32 // TODO: 如果该控件是 RICHEDIT 控件,它将不 33 // 发送此通知,除非重写 CDialogEx::OnInitDialog() 34 // 函数并调用 CRichEditCtrl().SetEventMask(), 35 // 同时将 ENM_CHANGE 标志“或”运算到掩码中。 36 37 38 39 // TODO: 在此添加控件通知处理程序代码 40 //破解死循环,如果是从OnEnChangeEditR过来,则直接返回 41 if(fromR) 42 { 43 fromR=false; 44 return; 45 } 46 47 48 // TODO: 在此添加控件通知处理程序代码 49 CString RS,LS; 50 double R,L; 51 GetDlgItemText(IDC_EDIT_R,RS); 52 R=atof(RS); 53 L=2*3.14159*R; 54 LS.Format("%.2f",L); 55 fromL=true; 56 SetDlgItemText(IDC_EDIT_R,RS); 57 }