喫茶XRAYトップページ

[スレッド全体
]

[7609] Re2:StringGridと格闘中…結果報告返信 削除
2014/5/19 (月) 10:45:23 taki
▼ Mr.XRAYさん

>
> お疲れ様です.
> 時間のある時にいじらせていただきますです (^^;


おかぽんさんのコードで解決ずみですが、せっかくなので私が試したことを書きます。

procedure TForm1.StringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
  var Value: string);
begin
  beep;        // このイベントが発生したことを確認するため。本来不要
  wait1000;    // もし暴走した時に暴走を緩やかにするため。本来不要

  if ACol = 1 then begin
//------------------------------------------- キャレットが2列目に入ると
    テストするコード
//-------------------------------------------
  end;
end;

以下にテストしたコードです。

  StringGrid1.Cells[1,ARow] := 'aaaaa';     // 無限ループ
--
  Value := 'aaaaa';  // セーフ しかも直ちに表示される。正当な方法と思われる。
--
  ShowMessage('Help me!');     // 無限ループ
--
  Form2.ShowModal;  // エラー表示 無限ループ

無限ループに入ると、そのコードの次のコードに制御が行かない。
ErrSW:boolean;を定義しても

  StringGrid1.Cells[1,ARow] := 'aaaaa';     // 無限ループ
  ErrSW := true;    // ここへ制御が来ないのでErrSWはtrueにならない。

しかも、イベント発生(割り込み)→戻り先をスタックに積む→
イベント発生(割り込み)→戻り先をスタックに積む→…になり、
スタックがオーバーフローするみたいです。(未確認)

StringGridがEditモードでない場合は無限ループになりません。
--
  StringGrid1.Options := StringGrid1.Options - [goEditing,goAlwaysShowEditor];
  StringGrid1.Cells[1,ARow] := 'aaaaa';    // セーフ ただし確定後に表示
  StringGrid1.Options := StringGrid1.Options + [goEditing,goAlwaysShowEditor];
--
aaaaaは直ちに表示されず、キャレットが次のセルに移動した時に表示されます。
[goEditing,goAlwaysShowEditor]は[goEditing]だけでも大丈夫みたいです。

--
  StringGrid1.Options := StringGrid1.Options - [goEditing];
  StringGrid1.Cells[1,ARow] := 'aaaaa';
  StringGrid1.Col := 2;    // キャレットを3列目に移動
  StringGrid1.Options := StringGrid1.Options + [goEditing];
--
上記のコードは一見良いように見えますが、2列目に文字列があるとそのゴーストが
3列目に表示されます。
例えば、1列目に間違った商品コードを入れて、2列目に「商品未登録」となった時、
再び1列目に正しい商品コードを入れて、2列目に「きのこの山」と表示後、
3列目に「きのこの山」とゴーストが表示されます。(T_T)

--
  StringGrid1.Options := StringGrid1.Options - [goEditing];
  StringGrid1.Cells[1,ARow] := 'aaaaa';
  StringGrid1.Perform(WM_KEYDOWN, VK_TAB, 1);
  StringGrid1.Perform(WM_KEYUP, VK_TAB, 1);
  StringGrid1.Options := StringGrid1.Options + [goEditing];
--
これも上と同じで、幽霊が見えます。

みなさん。無駄なことをしないでくださいね。


[7613] Re3:StringGridと格闘中…結果報告返信 削除
2014/5/21 (水) 15:00:13 taki
続編です。
ErrSWを無限ループに入る前にTrueにすればいいことに気が…遅いわ!
それと、戻り先を積んだスタックが気になって実験してみました。

procedure TForm1.StringGrid1GetEditText(Sender: TObject; ACol, ARow: Integer;
  var Value: string);
begin
  beep;        // このイベントが発生したことを確認するため。本来不要
  wait1000;    // もし暴走した時に暴走を緩やかにするため。本来不要

  Listbox1.Items.Append('1');
  if ErrSW then exit;
//
  Listbox1.Items.Append('2');
  if ACol = 1 then begin
//----------------------------------------
    ErrSW := true;         // 先にTrueにする
    Listbox1.Items.Append('3');
    StringGrid1.Cells[1,ARow] := 'aaaaa';     // 以前は無限ループした。
    Listbox1.Items.Append('4');
//---------------------------------------
  end;
  Listbox1.Items.Append('5');
  ErrSW := false;
end;

結果
1,2,5,1,2,5,1,2,3,1,4,5,1,2,5と記録されていました。

1,2,3でイベントが発生し、戻り先をスタックに積んで再び1に来てexitした後、
積んだ戻り先へ帰ってきて4,5と制御が流れたようです。

という事で、無限ループは回避できました。スタックメモリもオーバーフロー
しなくて済みそうです。
しか〜し、2列目(Col=1)には'aaaaa'は表示されませんでした。
不思議なことに、Button等をクリックして一度フォーカスを外すと'aaaaa'と
表示されます。

StringGrid1.Cells[1,ARow] := 'aaaaa';の代わりにShowmessage()でも大丈夫
でした。


[7614] Re4:StringGridと格闘中…結果報告返信 削除
2014/5/21 (水) 17:42:51 taki
度々すみません。これらのコードを試す人はいないとは思いますが念のため。

ErrSW:boolean;はグローバル変数として定義してください。
そしてFormCreate手続き内でfalseにセットしてください。



[▼次のスレッド]
INCM/CMT
Cyclamen v3.82