2009-06-16 4 views
2

誰かが手助けをしてもらえるよう、問題を十分に説明できることを願っています。「スマート」リンクスクロールバーとエディットコントロール?

基本的には、水平スクロールバー(0〜1000の範囲)と、スクロールバーの位置を1000で割った位置を表す編集コントロールがあるため、ユーザーはスクロールバーを使用して0〜 1から3小数点までの精度(.001、.002、...、.987など)を入力するか、エディットボックスに自分の番号を入力します。スクロールバーをスクロールすると、編集コントロールの番号が新しいスクロール位置に反映されます。新しい番号が入力されると、スクロールバーは入力された番号を反映した新しい位置に自分自身を設定します。一方、私はまた、(スクロールバーまたはエディットコントロールのいずれかを介して)変更されると、この数値でいくつかの計算を行い、結果を別のダイアログで表示します。

これは私の問題です。ユーザーがエディットコントロールに数値を入力したときに、適切な動作を生成するために使用するイベントハンドラを決定することができません。

私は、私の編集コントロールを処理するためにfuelMarginという二重値変数と、スクロールバーを処理するfuelScrollというCScrollBarコントロール変数を使用しています。

私のHSCROLLイベントでは、編集コントロールをスクロール位置/ 1000に設定しました。問題はありません。ユーザーがスクロールバーをスクロールすると、編集ボックスが正しく更新されます。エディットボックスのよう

、私の最初の試みは、onChangeイベントだった:

void MarginDlg::OnEnChangeFueledit() 
{ 
    CEdit* editBox; 
    editBox = (CEdit*)GetDlgItem(IDC_FUELEDIT); 

    CString editString; 
    editBox->GetWindowText(editString); 

    if (editString.Compare(".") != 0 && editString.Compare("0.") != 0 
     && editString.Compare(".0") != 0 && editString.Compare("0.0") != 0 
     && editString.Compare(".00") != 0 && editString.Compare("0.00") != 0) 
    { 
     UpdateData(); 
     UpdateData(FALSE); 

     if (fuelMargin > 1) 
     { 
      UpdateData(); 
      fuelMargin = 1; 
      UpdateData(FALSE); 
     } 
     if (fuelMargin < 0) 
     { 
      UpdateData(); 
      fuelMargin = 0; 
      UpdateData(FALSE); 
     } 
     fuelScroll.SetScrollPos(int(fuelMargin*1000)); 
    } 
} 

ユーザーが番号を入力しようとしているとき、私は)にupdateDataを(やってから保つためにそこにいるかの最初の文を必要と.5または.05または.005のように。しかし、それはいくつかの不運な行動を引き起こします。ユーザーが.56のようなものを入力しようとすると、UpdateData()が実行された後に数字が0.5になり、カーソルが一番左に移動するので、.56を入力しようとすると、 60.5を入力すると1になります。なぜなら、0より小さい数または1より大きい数を入力させないからです。しかし、0.56を入力すると、この動作は回避されます。

私の第二の試みのために、私は私のonChangeイベントをコメントアウトし、代わりにONKILLFOCUSイベントに置く:

void MarginDlg::OnEnKillfocusFueledit() 
{ 
    UpdateData(); 
    UpdateData(FALSE); 

    if (fuelMargin > 1) 
    { 
     UpdateData(); 
     fuelMargin = 1; 
     UpdateData(FALSE); 
    } 
    if (fuelMargin < 0) 
    { 
     UpdateData(); 
     fuelMargin = 0; 
     UpdateData(FALSE); 
    } 
    fuelScroll.SetScrollPos(int(fuelMargin*1000)); 
} 

だから今、ユーザーが自分の番号を入力し終えることができると、すべてが互角のドーリーです - 限り、彼らとしては、編集ボックスをクリックします。スクロールバーは移動せず、ボックスがフォーカスを失うまで結果は計算されません。

ボックス内の数字が入力されると結果が計算されます。数字が入力されると、スクロールバーが動くようにしたい。しかし、私は入力を中断させたくない、すなわちボックス内の実際の数字が変更されたか、カーソルが何らかの形で動いた。

提案?

ありがとうございます!

答えて

2

最初のアプローチでは、ほぼそこにいるように見えます。ユーザーがカーソル位置でUpdateData()を繰り返し呼び出すと、入力が重大な問題になります。

コントロール間の合理的に複雑なやりとりをしようとしているので、私が示唆しているのは、OnChange()での検証をまったく行わないことです。ユーザーが入力しているときに、 (ほとんどの数値エディットコントロールがどのように動作するか)ユーザーがダイアログを閉じると、コントロールがオンになり(または何らかの方法でデータを使用するボタンがクリックされます)、検証がトリガーされ、適切なエラーが表示されます。

OnChange()で検証しなくても、OnChange()でUpdateData()を呼び出さないようにするだけで、カーソル移動の問題を修正できます。代わりに、 "editString"から数値を解析し、有効範囲内にあればスクロールバーを更新してください。そうすれば、スクロールバーはユーザーのタイプに応じて更新され、無効な値を入力するとスクロールバーはそのままの状態になり、次のステージに移動するとエラーになります。このような何か(テストしていません):

void MarginDlg::OnEnChangeFueledit() 
{ 
    CString editString; 
    GetDlgItem(IDC_FUELEDIT)->GetWindowText(editString); 

    double editValue; 
    if ((sscanf(editString,"%lf",&editValue) == 1) 
    { 
    if (editValue >= 0.0) && (editValue <= 1.0)) 
     fuelScroll.SetScrollPos(int(editValue*1000)); 
    } 
} 

ザ・のみに注目することが重要な問題とされて残り、そのユーザの種類いくつかの無効な値、または有効な範囲外の数、そしてエディットコントロールとスクロールバーするかどうか同期していないこれを処理する最も簡単な方法は、編集コントロールが「マスター」値であることを決定することです。ユーザーが入力した内容を知りたいときは、常にスクロールバーではなくエディットコントロールを見て、データを検証します。

2つ目の方法としては、タイマーメッセージハンドラを実装する方法が考えられます。タイマーハンドラでは、「ユーザーが何も入力していない場合は、 '完了し、番号を解析してスクロールバーを更新します。私はそれほど解決策としてそれほど熱心ではない。

+0

私はこの方法を私のオンキーに使用しました。私は結果に非常に満足しています。ありがとう! 私はkillfocusでエラーチェックを最小限に抑えています。つまり、数値が範囲内にあることを確認し、そうでない場合は0または1に設定します(それに応じてスクロールバーを更新します)。私はそこに私の結果を更新したいと思いますが、私はいくつかの問題を抱えています...私は現在、それをデバッグ中です。しかし、あなたの解決には非常に感謝します。 – Lauren

0

私はEnterキーを見て、UpdateData()とOnKillFocusとOnChangeを実行することをお勧めします。よりユーザーフレンドリーな方が良いでしょう。

次に、あなたにupdateData()ルーチンは唯一のあなたが必要とする方向に働くことを確認してください:OnChangeイベントが発生したときに、あなたにupdateData()ルーチンを実行し、「0.5" のエディットコントロールに入力された場合

、スクロールバーのみを更新してください。 OnKillFocusが呼び出されるまでエディットコントロールを "0.5"に更新することは心配しないでください。逆方向(エディットコントロールに対する)での更新は、カーソルを混乱させます。エディットコントロールが何らかの形でこのダブル変数にバインドされていて、varが変更されたときに自動更新された場合は、OnKillFocusイベントが発生するまで、エディットコントロールとエディットコントロールを別々のままにしてください。

他の方向にも同じ概念が適用されます。ユーザーがスクロールするときに、スクロールバーを混乱させないでください。編集コントロールを更新してそのまま残しておきます。

XAMLのデータバインディング機能は、正しく使用する方法がわかっている場合は、このような状況で役立ちます。ネイティブタイプの開発者にとっては、イベントハンドラのみを使用して同様の機能を実装することは非常に難しいことは残念です。

関連する問題