OnExitiイベントをキャンセルする方法があったら教えてください。

解決


ナッツ  2008-01-10 17:22:18  No: 29281  IP: 192.*.*.*

Delphiを初めて3ヶ月ほどの初心者です
データベースのマスターメンテを作るようにいわれ手探り状態で作ろうとしています。
  マスメン用のフォームに
TEdit×32個、TDBGrid×1個、TButton(取消、保存、削除、終了)を貼り付けメンテできるところまでは漕ぎ着けましたが、問題が発生しました。
  最初はTButtonのオンクリック時に内容チェックをし、フォームをクリアして
先頭の項目にSetFocusする様にしたのですが入力項目が多いため、各項目を入力した直後にチェックする様に指示され各々TEditのOnExitイベントでチェックする様に書き直しました。    これだと「取消」、「終了」ボタンをクリックするとTEditのOnExitイベントも発生するようでエラーメッセージが出てしまいます。
  「取消」、「終了」ボタンのOnClickいイベントで指定したTEditのOnExitイベントを一時的に無効にする方法があったら教えてください。
開発にはWinXPとDelphi6を使っています。
よろしくお願いします。

編集 削除
らくする  2008-01-10 17:36:17  No: 29282  IP: 192.*.*.*

無効にするには、OnExitイベントハンドラに nilを代入すればいいけど、
32個のEditの個々のハンドラを変えるのは面倒なので、イベントハンドラを
一つにまとめておけば楽だね。
どのEditかを区別するには、Tagが使える。

編集 削除
そうね...  2008-01-10 17:55:56  No: 29283  IP: 192.*.*.*

AbortFlag変数などを用意して...

procedure TForm1.EditExit(Sender: TObject);
begin
  if AbortFlag then exit;
  // 通常処理
  .........
end;

編集 削除
KHE00221  2008-01-10 18:27:43  No: 29284  IP: 192.*.*.*

OnExit が実行される際に次の項目に移動か、キャンセルボタンへの移動
かは把握する事ができません

procedure TForm10.Button1Click(Sender: TObject);
begin
    Caption := Caption + '2';
end;

procedure TForm10.Edit1Exit(Sender: TObject);
begin
    Caption := Caption + '1';
end;

こうやるとわかるけど 1 のほうが先に表示されます

>  「取消」、「終了」ボタンのOnClickいイベントで指定したTEditのOnExitイベントを一時的に無効にする方法があったら教えてください。

OnClick が実行される時点で OnExit が実行されていますので

OnClick で  OnExit を無効にしても意味がありません

編集 削除
KHE00221  URL  2008-01-10 19:27:28  No: 29285  IP: 192.*.*.*

こんな感じ?

function CheckData(Sender:TObject):Boolean;
var
    I : Integer;
begin
    Error := False;
    if Assigned(Sender) = True then
    begin
      case TEdit(Sender).Tag of
        1:
        begin
          if Length(TEdit(Sender).Text) <> 4 then Error := True;  //4桁でなければ ERR
          if TryStrToInt(TEdit(Sender).Text,I) = False then Error := True; //数字でなければ ERR
        end;
        2:
        begin
          if not (StrToIntDef(TEdit(Sender).Text,0) in [1..12]) then Error := True;  //1〜12でなければエラー
        end;
        3:
        begin
          if not (StrToIntDef(TEdit(Sender).Text,0) in [1..31]) then Error := True; //1〜31でなければエラー
        end;
      end;
      if Error = True then
      begin
        SaveSender2 := SaveSender;
        TEdit(SaveSender).SetFocus;
      end;
    end;
    Result := Error;
end;

procedure TForm10.FormCreate(Sender: TObject);
begin
    Edit1.Tag := 1;
    Edit2.Tag := 2;
    Edit3.Tag := 3;
end;

{初期化}
procedure TForm10.Button1Click(Sender: TObject);
begin
    Edit1.Text := '';
    Edit2.Text := '';
    Edit3.Text := '';
    SaveSender := nil;
end;

{保存}
procedure TForm10.Edit1Enter(Sender: TObject);
begin
    if CheckData(SaveSender) = False then
    begin
      SaveSender := Sender;
    end;
    Enter := True;
end;

編集 削除
KHE00221  2008-01-10 19:29:05  No: 29286  IP: 192.*.*.*

コメントが変だな

編集 削除
通りすがお  2008-01-11 08:56:51  No: 29287  IP: 192.*.*.*

根本的な解決にはならないかもしれませんがTSpeedButtonを使ってみてはいかがでしょうか?
TSpeedButtonはフォーカスを受け取らないのでEditのOnExitは発生しないと思います。

的外れな回答ならごめんなさい_(._.)_

編集 削除
もしかして  2008-01-11 12:48:20  No: 29288  IP: 192.*.*.*

OnExitイベントでは、ActiveControlが次のコントロールを指していたりします。
なので、

if (ActiveControl = Button1) then Exit;

などとして処理を飛ばせると思います。
全てのOnExitに追加する必要がありますが。

編集 削除
ナッツ  2008-01-16 09:48:10  No: 29289  IP: 192.*.*.*

らくするさん他色々ありがとうございました。
まず動かすことが最優先のため、もしいかしてさんの方法でOnExitイベントに判断を追加しました。
  しかし仰るとおりあまりスマートではありませんので、Tagを使う等の他の方の方法も研究してゆっくりチューンナップしようと思います。

編集 削除