c++ - 响应 EN_UPDATE 消息时避免递归

标签 c++ winapi recursion editcontrol

我正在尝试创建一个编辑控件,它将接受格式为sign number separator number 的带符号十进制数(例如-1.5 ).

在 Internet 上进行广泛研究后,我发现很少有令人满意的屏蔽编辑控件示例,但它们是在 MFC 中完成的。

因为我不懂MFC,所以我很难将代码转换成纯Win32 API,所以我决定尝试用我自己的方式,从头开始.

在仔细研究了 MFC 示例后,我得出结论,它们在响应 EN_UPDATE 消息时执行文本验证。

当我尝试执行相同操作时,我的程序立即退出,没有任何警告或错误消息。我得出结论,我的问题一定是递归。

为了确认这一点,我在主窗口的过程中编写了一个小处理程序来测试它:

case WM_COMMAND:
    switch( HIWORD( wParam ) )
    {
    case EN_UPDATE:
        if( LOWORD(wParam) == IDC_OF_MY_EDIT_CONTROL)
        {


            static int counter = 0;   // increment it each time we get EN_UPDATE

            // after we receive EN_UPDATE 4 times stop testing

            if( ( counter++) < 4 )   
            {
                wchar_t text[10];  // get sample text

                GetWindowText( (HWND)lParam, text, 10 );

                // change current char to char + 1
                // which means A will be B, B will be C and so on...

                for( int i = 0; i < wcslen(text); i++ )
                    text[i] = (wchar_t)( 1 + text[i] );   

                SetWindowText( (HWND)lParam, text );   // show changed text
            }
        }
        break;
    }
    break;

case WM_CLOSE: // WM_CLOSE and other handlers...

这是当我在 Debug 模式下启动我的程序时发生的情况:

在我输入字母 a 后,编辑控件的文本变成了 e

这证实了我关于递归的结论:在我按下 a 之后它被转换为 b,然后另一个 EN_UPDATE 被触发,重复过程 b 变成 c 等等,直到 static 变量达到 4 所以结果是 e.

我的问题很简单:

我应该如何处理 EN_UPDATE 或修改我的程序,以避免这种类型的递归?

编辑(2014 年 2 月 18 日):

我已根据成员 Jonathan Potter 的说明修改了上述 EN_UPDATE 处理程序。

虽然递归问题消失了,但输出并不是我想要的。

我已经验证了我的代码的正确性,在一个简单的控制台应用程序中用他的继任者替换了一个角色,并在点击一个按钮时做了同样的事情(我不难快速添加一个按钮和一个处理程序点击它)。

所以问题肯定是执行给定指令的问题,因此我提交更正后的代码,希望有人指出我做错了什么:

case EN_UPDATE:
    if( LOWORD(wParam) == IDC_OF_MY_EDIT_CONTROL)
    {
        static bool OK_to_process_text = true;

        if( OK_to_process_text )
        {
            OK_to_process_text = false;

            wchar_t text[10];
            memset( text, L'0', sizeof(text) );

            GetWindowText( (HWND)lParam, text, 10 );

            for( size_t i = 0; i < wcslen(text); i++ )
                text[i] = (wchar_t)( 1 + text[i] );

            SetWindowText( (HWND)lParam, text ); 

            OK_to_process_text = true;
        }
    }
    break;
}
break;

现在,在按下 a 之后,它正确地变成了 b,但是在我按下 b 之后,我没有得到预期的结果 bccc

这是预料之中的,因为在用户按下一个键后,会生成 EN_UPDATE 以显示文本。

因此,当按下 a 时,它将转换为 b。当我按下 b 之后,生成了一个新的 EN_UPDATE 消息,所以我的处理程序重新开始,这意味着它需要新的字符串 bb 并将其正确转换为 cc

有没有办法在使用当前文本进行操作时暂时抑制新的 EN_UPDATE 消息的创建,所以在上面的示例中,我得到的结果是 bc 而不是 cc 当我按 a 然后按 b 时?

编辑结束

感谢您的宝贵时间和帮助。

最好的问候。

最佳答案

我正在尝试创建一个编辑控件,它将接受符号数分隔符格式的带符号十进制数(例如 -1.5)

也许我误解了情况,为什么不使用 EN_CHANGE 并向用户提示值不正确,如下所示?

[以下代码适用于 MS Visual Studio]

case EN_CHANGE:
    if( LOWORD(wParam) == IDC_OF_MY_EDIT_CONTROL)
    {   TCHAR szValue[32];
        double dd;
        GetWindowText((HWND)lParam, szValue, _countof(szValue));
        if (_stscanf(szvalue, _T("%lf"), %dd) == 1)
        {   // optionally reset an error indicator on the screen
        }
        else
        {   MessageBeep(MB_ICONEXCLAMATION);
            // optionally set an error indicator on the screen
        }
        break;
    }

关于c++ - 响应 EN_UPDATE 消息时避免递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21850684/

相关文章:

c++ - 使用标准 :sort to sort locally

c++ - 如何正确读取子进程的 stdout/stderr 输出?

c++ - SendInput() 不等于在 C++ 键盘上手动按键?

java - 使用递归在 Java 中以正确的格式打印菱形图案

mysql - 从自引用表中获取层次结构数据

c++ - 5 法则(对于构造函数和析构函数)是否过时了?

c++ - 正确指定旋转约束?

c++ - 简单的猜谜游戏继续使用除声明的变量 Y/N 之外的任何其他字母

windows - 当两个路径可能是相对路径时,将路径与 Windows API 组合

C - 递归数组检查