1

符号付きの 10 進数を符号付き区切り記号edit controlの形式で受け入れるを作成しようとしています(例: )。-1.5

インターネットで広範囲にわたる調査を行った結果、マスクされたエディット コントロールの満足のいく例はほとんど見つかりませんでしたが、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に変わりました。cstatic4e

私の質問は簡単です:

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代わりに結果が得られますか?ccab

編集の終わり

お時間をいただき、ありがとうございました。

よろしくお願いします。

4

2 に答える 2

1

I am trying to create an edit control that will accept signed decimal numbers in the format of sign number separator number ( e.g. -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;
    }
于 2014-02-18T13:36:24.517 に答える