LoginSignup
1
0

More than 5 years have passed since last update.

[廃版] C++ Builder > TTrackBar と TEdit > 値の同期 > TTrackBar:OnChange | TEdit:OnExit

Last updated at Posted at 2017-09-06

(追記 2017/09/06)

下記に記載事項は「ビルド環境」「OS環境」により再現しないかもしれません。
環境が変わった時点でバグとなる可能性が考えられるため、お薦めの方法ではありません。
なんらかの参考にはなるかもしれないため、記事としては残しておきます。


動作環境
C++ Builder XE4
  • TTrackBarを使ったスライダー表示
  • TEditを用いた数値の入力

上記を同期させるとする。

失敗編

方法

  • TTrackBarのOnChangeイベントでTEditの値を変更する
  • TEditのOnExitイベントでTTrackBarの値を変更する

こうした場合、TEditの値を変更してフォーカスをはずしたとき、以下となる。

  • TEditのOnExitイベントが発生
    • => TTrackBarの値が変更される
      • => TTrackBarのOnChangeイベントが発生
        • => TEditの値が変更される

回避案

方法

こうした場合、TEditの値を変更してフォーカスをはずしたとき、以下となる。

  • TEditのOnExitイベントが発生
    • => TTrackBarの値が変更される
      • 変更終了時(i.e., 値がpreと同値)でないためTTrackBarのOnChangeイベントは発生しない

code

Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ComCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE で管理されるコンポーネント
    TEdit *Edit1;
    TTrackBar *TrackBar1;
    TMemo *Memo1;
    void __fastcall TrackBar1Change(TObject *Sender);
    void __fastcall Edit1Exit(TObject *Sender);
private:    // ユーザー宣言
public:     // ユーザー宣言
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------


static const bool kCatchEndChange = true;  // true: TrackBar1の最後の変更(+1)だけ検知する

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    TrackBar1->Min = 0;
    TrackBar1->Max = 100;
    TrackBar1->Frequency = 10;

    Memo1->Clear();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TrackBar1Change(TObject *Sender)
{
    static int pre = -1;

    if (kCatchEndChange) {
        if (pre == TrackBar1->Position) {
            Memo1->Lines->Add(L"TrackBar1Change [" + IntToStr(TrackBar1->Position) + L"] " + DateTimeToStr(Now()));
            Edit1->Text = IntToStr(TrackBar1->Position);
        }

        pre = TrackBar1->Position;
        return;
    }

    Memo1->Lines->Add(L"TrackBar1Change [" + IntToStr(TrackBar1->Position) + L"] " + DateTimeToStr(Now()));
    Edit1->Text = IntToStr(TrackBar1->Position);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Edit1Exit(TObject *Sender)
{
    Memo1->Lines->Add(L"Edit1Exit [" + Edit1->Text + L"] " + DateTimeToStr(Now()));

    int val = StrToIntDef(Edit1->Text, -1);
    if (val > 0) {
        TrackBar1->Position = val;
    }
}
//---------------------------------------------------------------------------

実行例

失敗編

kCatchEndChange = false;で実行。

qiita.png

  • (1)の部分: TrackBar1の値を2から24に上げた
    • 途中の変更がイベント処理されてしまう
  • (2)の部分: TEditからフォーカスをはずした
    • OnExitイベントに加えて、TrackBar1:OnChangeイベントが発生してしまう

成功編

kCatchEndChange = true;で実行。

qiita.png

  • (1)の部分: TrackBar1の値を2から45に上げた
    • 最後の二回のイベントが発生
  • (2)の部分: TEditからフォーカスをはずした
    • OnExitイベントのみ発生
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0