BCB:StringGridでgoEditingを操作すると不思議な動きをする

このQ&Aのポイント
  • C++ Builder5のStringGridでgoEditingを操作すると不思議な動きが発生します。
  • 修正不可のセットをした後、セルをスクロールバーで隠したり表示したりすると、修正不可セット直前のセルの内容が現れます。
  • 表示だけの問題であり、別のセルをクリックすると正しい内容に戻ります。回避する方法はありますか?
回答を見る
  • ベストアンサー

BCB:StringGridでgoEditingを操作すると不思議な動きをする

C++ Builder5で不思議な動きをしています。 StringGridで、OptionにgoEditingを操作し、修正不可のセットをしました。 StringGrid1->Options = StringGrid1->Options >> goEditing; その後、StringGridのどこかのセルをクリックして、そのセルをスクロールバー で隠したり表示したりすると、修正不可セット直前にカーソルのあったセルの 内容が現れてきます。 具体例を示すと、1行3列目にカーソルのある状態で、修正不可にセットします。 次に、5行5列目をクリックした後、スクロールバーでこのセルを見えない様に StringGridをスクロールします。 再度、5行5列目が見えるようにスクロールを戻すと、1行3列目に入っていた 内容(文字)が表示されているのです。 この時、別のセルをクリックすると、5行5列目には本来の内容(文字)が表示 されて来ます。 別のセルをクリックすると、正しい内容に戻りますので、表示だけの問題だと 思うのですが、不思議で困った現象です。 なんとか、これを回避する方法はないでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • KoHal
  • ベストアンサー率60% (110/181)
回答No.2

現象を確認しました。 goAlwaysShowEditorが原因です。 本来goAlwaysShowEditorはgoEditingが有効でなければ無視されるオプションですが、両者が有効であるときにgoEditingだけを動的に無効にするという状況を想定してないようです。 そのため、goEditingを無効にした直後はgoAlwaysShowEditorが判定されInpalceEditorが消されてないようです。VCLのソースを確認してないので断言できませんが、当たらずとも遠からずだと思います。 ですので対処法は「goEditingを切り替えるときはgoAlwaysShowEditorも同時に切り替える」で正解です。 なお、 //有効にする  StringGrid1->Options << goEditing << goAlwaysShowEditor; //無効にする  StringGrid1->Options >> goAlwaysShowEditor >> goEditing; でいけます。ストリーム演算子と同じ扱いが出来るようになってます。

Han1344
質問者

お礼

有難うございました。 >ですので対処法は「goEditingを切り替えるときはgoAlwaysShowEditorも同時に切り替える」で正解です。 そうだったんですね。 以後、このようにします。 C++の記述についてもご指導ありがとうごいました。

その他の回答 (1)

  • KoHal
  • ベストアンサー率60% (110/181)
回答No.1

追試してみました。 しかし、うちの環境(BCB6、BDS)では再現しませんでした。 BCB5に固有の問題かもしれません。 ご面倒でなければ、一度最低限の構成(フォーム上にStringGridとgoEditingを操作するためのコンポーネントのみ配置し、イベントハンドラもStringGridの初期化とgoEditingの操作のみにする)で、現象が発生する場合の設定、手順の詳細を補足してください。 現在BCB5が使える環境がないのでお役に立てるかどうかはわかりませんが。 ところで、 >StringGrid1->Options >> goEditing; でいいような。BCB5はちがったけっかな?

Han1344
質問者

補足

ありがとうございます。 今、テストプログラムを作って実験しています。 Optionでtrueと設定されているのは、次の項目です。 goFixedVertLine goFixedHorzLine goVertLine goHorzLine goRangeSelect goEditing goAlwaysShowEditor goThumbTracking Button2が、StringGrid修正不可の設定ボタンでして、 void __fastcall TForm1::Button2Click(TObject *Sender) { Button1->Enabled = true; Button2->Enabled = false; StringGrid1->Options >> goEditing; // <a> } と記述しています。( <a>の行はご指摘の通りでうまく出来そうです。) プログラムが起動すると、テストデータ用のファイルを読み込み、各セルに テキストを格納します。 この状態でプログラムは操作待ちになります。 矢印キーの操作をしてみると、この現象は、 「再描画されたセルのうち、最終的にカーソルのあるセルに現れる」 ということのようです。 従って、再描画されないセル(セル全体が見えている)をクリックしても 現象は現れません。 シロートの直感で、 StringGrid1->Options << goEditing; //認める StringGrid1->Options << goAlwaysShowEditor; と StringGrid1->Options >> goEditing; //認めない StringGrid1->Options >> goAlwaysShowEditor; の組み合わせをやってみたら、問題の現象は出なくなりました。 この違いが良く分かっていないのですが、原因が良く分からない場合、 これで逃げようかと思っています。

関連するQ&A

  • BCBのStringGridでデータ修正の許可制御をしたい

    Borland C++ Builder5 を使っています。 StringGridにデータを表示するのですが、そのデータの修正を許可する場合と 許可しない場合を動的(プログラム実行中)に切替したいと思っています。 (StringGridにキー入力が出来るようにしたり、出来ないようにしたりしたい、 という意味です。 ただし、マウスのクリックと、矢印キーでの移動は常に出来るようにしたいと 考えています。) OptionのgoEditing をセットしたり外したりすれば良いのでは、と考えたので すが、そのやり方が分かりません。 もしかしたらC++の基礎的な部分かも知れませんが、どなたかご指導をお願い します。

  • StringGridの内容をクリップボードにCOPYしたい

    Borland C++ Builder 5 を使っています。 StringGridの内容をクリップボードにCOPYするプログラムを作っています。 Excelに貼り付けるのが目的なので、Tab区切りのデータにしています。 下に示したソースで実現できましたが、非常に遅いのです。 100行とか200行ならアッという間なのですが、2,000行、3,000行となるとかなり待たされます。 時間を食っているのは(2)の部分のようです。 もう少しスマートに、短時間でCOPYしたいのですが、方法はないものでしょうか? ◆ソースの解説 StringGridの21列分を、行数だけクリップボードにCOPYします。 (1) StringGridの各行、各列をLOOPしてセルに格納されている文字列長の合計を求めます。 Tab区切りにするため、各セルごと1バイト加算します。 また、各行ごと改行を入れるため、これも1バイト加算します。 (2) 合計容量が計算できたら、メモリーを動的確保し、もう一度LOOPをしながら、文字列をCOPYします。 セルごとにTab、行ごとに改行も追加します。 (3) 最後にクリップボードをクリアしてCOPYします。 int cnt = StringGrid1->RowCount; int size = 0; //StringGridのサイズ(文字長)をカウントする ------ (1) for(i=0;i<cnt;i++){ for(k=0;k<21;k++){ size += strlen(StringGrid1->Cells[k][i].c_str()) + 1; } size++; } //メモリーを確保して、StringGridをCOPYする -------- (2) cb = new char[size]; strcpy(cb,""); for(i=0;i<cnt;i++){ for(k=0;k<21;k++){ strcat(cb,StringGrid1->Cells[k][i].c_str()); strcat(cb,"\t"); //Tab区切りの文字列にする } strcat(cb,"\n"); } Clipboard()->Clear(); // -------- (3) Clipboard()->AsText = cb; なお、サイズがintに収まるかというチェックとか、メモリーの解放をする、といったことも必要ですが、記述を省略しました。

  • StringGrid1で画面におさまりきらない行をForm2から遠隔スクロールするには?

    Form1のStringGrid1で、画面におさまりきらない行を、Form2から次のようなやり方で遠隔スクロールさせたいのですがうまくいきません。目的の矩形 StringGrid1.Cells[ col, row ] をちゃんとselect しているはずなんですが、その行の位置が画面表示行よりも下方にあるために、それが見えないのです。御教示いただければありがたいのですが。 procedure TForm2.Next1Click(Sender: TObject); var R : TGridRect; begin with R do begin Left := Form1.StringGrid1.Col; Top :=Form1.StringGrid1.Row+1; Right := Form1.StringGrid1.Col; Bottom := Form1.StringGrid1.Row+1; end; Form1.StringGrid1.Selection := R; end;

  • グリッドの動き

    以下の現象で困っています。 解決策をご存知の方いらっしゃいましたら教えてください。 1.スクロールバーのあるグリッド(画面では10行を表  示)で一番下までスクロールし、グリッドに表示され  ている下段の方の行をクリックし反転表示させます。 2.いったんグリッドからロストフォーカスし(グリッドの 行は反転表示のまま)今度はグリッドの上段の方の行を  クリックします。 以上のオペレーションをすると、最上部までスクロールし、2回目にクリックした行から最上部の行までが反転表示されます。 このような現象の原因もしくは解決策をご存知の方、 ぜひ教えてください。よろしくお願いします。

  • スクロールバーの幅

    Borland C++ Builder6でプログラムを作成しています。StringGridで行を増やしていくとスクロールバーが出てきますが、このスクロールバーの幅を取得することは可能なのでしょうか。可能ならば、どうすればいいのでしょうか。

  • EXCELで列単位でスクロールさせたい

    20列×1000行のセルがあります。4列ごとのデータを1まとめとしてスクロールさせたいのですが、4列×1000行毎にスクロールバーをつけて4列のみスクロールさせられるような事は可能でしょうか? よろしくお願いします。

  • Ecell セルにスクロールボタンを設定する方法

    あるセルにカーソルを持っていくと、右側にスクロールバーが現れ、スクロールバーの下向き矢印ボタンを押すと、あらかじめ範囲指定しておいたセルの内容が下方向にずらっと表示される。 というやり方をご存知の方はお教えください。

  • エクセルのセル操作

    エクセルについてです 1行1列セルの内容 1行2列セルの内容 1行3列セルの内容 これを・・ 1行1列セルの内容 2行1列セルの内容 3行1列セルの内容 横3つを縦3つに並べるにはどのようにすれば良いのですか?

  • 重複入力の回避のVBAをご教示ください

    6行目のセル(6行、C列)に顧客番号を入力し、F列以降に、セル(6行、C列)の顧客番号の内容を入力しています。   その入力時に、顧客番号の重複入力を避けるためのチェック及び対処処理をご教示お願い致します。     (1)・セル(6行、C列)に顧客番号を入力し、F列からH列に、セル(6行、C列)の顧客番号の内容を入力する。     (2)・セル(7行、C列)に顧客番号を入力し、F列からH列に、セル(7行、C列)の顧客番号の内容を入力する。       (イ)・セル(7行、C列)に顧客番号を入力し、エンターキーを押した時点でセル(6行、C列)の顧客番号と重複していなかチェックする           ●重複していない場合は、カーソルをセル(7行、F列)へ移動させる           ●重複している場合は、「同じ番号があります」とメッセージボックスを表示する。               メッセージボックスのキャンセルボタンをクリックするとセル(7行、C列)の重複番号が削除されカーソルはセル(7行、C列)へ     (3)・セル(8行、C列)に顧客番号を入力し、F列からH列に、セル(8行、C列)の顧客番号の内容を入力する。        (イ)・セル(8行、C列)に顧客番号を入力し、エンターキーを押した時点でセル(6行、C列)とセル(7行、C列)の顧客番号と重複していなかチェックする           ●重複していない場合は、カーソルをセル(8行、F列)へ移動させる           ●重複している場合は、「同じ番号があります」とメッセージボックスを表示する。               メッセージボックスのキャンセルボタンをクリックするとセル(8行、C列)の重複番号が削除されカーソルはセル(8行、C列)へ     (4)・セル(9行、C列)に顧客番号を入力し、F列からH列に、セル(9行、C列)の顧客番号の内容を入力する。        (イ)・セル(9行、C列)に顧客番号を入力し、エンターキーを押した時点で、セル(6行、C列)とセル(7行、C列)とセル(8行、C列)の顧客番号と重複していなかチェックする           ●重複していない場合は、カーソルをセル(9行、F列)へ移動させる           ●重複している場合は、「同じ番号があります」とメッセージボックスを表示する。               メッセージボックスのキャンセルボタンをクリックするとセル(9行、C列)の重複番号が削除されカーソルはセル(9行、C列)へ     (5)・(1)~(4)を1セットとお考え下さい           ●10行から13行の4行を1セットとして、セル位置は変わりますが、(1)~(4)の処理をしたい。           ●最終  702行から705行まで、(1)~(4)の処理をしたい。 宜しくお願い致します。

  • Excel で、セルにスクロールバーをつけたい

    セル内にたくさんの文字が入力されていると読みにくいですよね。 セルの高さを広げすぎると、シートのスクロールがしにくくなりますし、 数式バーにも内容が表示されて別のセルがクリックできなくなったりします。 ある程度高さを広げたセルに、上下のスクロールバーがつけられれば便利だと思うんですが・・・ 何か方法はあるんでしょうか。 また、セルにスクロールバーがつけられないのであれば、それに代わる方法がありましたらお願いします。

専門家に質問してみよう