Gridのクリックを無効にするには

解決


delp好き  2012-08-21 08:35:05  No: 42807

Delphi5Proを使用しております。
StringGridにてクリックを行った時にセルのフォーカスが移動しないようにするにはどうすればよろしいでしょうか。
ご教授いただければ幸いです。


igy  2012-08-21 11:09:42  No: 42808

OnSelectCellイベントで、CanSelect := False;
にすると、選択できなくなりますが・・・・
ただ、これだと、矢印キーによるセルの移動もできなくなりますね。


通りすがり  2012-08-21 18:30:37  No: 42809

変な仕様のような気がするけれど、こんな感じなんでしょうか?
なお、一部しか見えていないセルをクリックするとスクロールするけれど、
スクロールしなくなります。

  TForm1 = class(TForm)
    StringGrid1: TStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FGridWindowProc: TWndMethod;
    procedure NewGridWindowProc(var Message: TMessage);
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FGridWindowProc := StringGrid1.WindowProc;
  StringGrid1.WindowProc := NewGridWindowProc;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  StringGrid1.WindowProc := FGridWindowProc;
end;

procedure TForm1.NewGridWindowProc(var Message: TMessage);
var
  cp: TPoint;
  gc: TGridCoord;
begin
  if Message.Msg = WM_LBUTTONDOWN then begin
    //画面上カーソル位置取得
    GetCursorPos(cp);
    //コントロール座標に変換
    cp := StringGrid1.ScreenToClient(cp);
    //カーソル位置のセルを取得
    StringGrid1.MouseToCell(cp.X, cp.Y, gc.X, gc.Y);
    //セルが取得できた場合マウスダウン処理を行わない
    if (gc.X < 0) or (gc.Y < 0) or
    //または選択中のセルと同じセルであれば編集できるように処理を行う
       ((gc.X = StringGrid1.Col) and (gc.Y = StringGrid1.Row)) then
      FGridWindowProc(Message)
  end
  else
    FGridWindowProc(Message);
end;


delp好き  2012-08-21 19:42:19  No: 42810

igy様、通りすがり様
お返事ありがとうございます。
かなり近い結果にはなったのですが
私の説明が不足しておりました申し訳ありません。
下記のような事をやりたいです。

procedure TForm1.FormCreate(Sender: TObject);
begin
    StringGrid1.Col := 0;
    StringGrid1.Row := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ColIdx, RowIdx: Integer;
begin
    RowIdx := StringGrid1.Row;
    ColIdx := StringGrid1.Col;
    StringGrid1.Cells[ColIdx, RowIdx] := 'A';
    if RowIdx < 5 then begin
        Inc(RowIdx);
    end else begin
        Inc(ColIdx);
        RowIdx := 0;
    end;
    StringGrid1.Row := RowIdx;
    StringGrid1.Col := ColIdx;
end;

グリッドへのINはボタンからのみで、グリッドはあくまで表示専用といった使い方がしたいです。
上記ソースにigy様、通りすがり様からご助言頂きましたものに加え
WM_MOUSEMOVEやWM_LBUTTONUPなども加えながら制御を試みましたが
どうもうまくいきません。
グローバル変数で ColとRowを保持するしか方法はありませんでしょうか?

ご助言頂けましたら助かります。


deldel  2012-08-21 20:24:03  No: 42811

「グリッドはあくまで表示専用」ということでしたら、
TPanelの中にTStringGridを置いて、TPanelのEnabledをFalseにすればいいと思います。


delp好き  2012-08-21 20:35:37  No: 42812

通りすがり様からご教授いただいたソースを
下記のように一部変更したことで理想の結果が得られました。
たいへん勉強になりました。
どうもありがとうございます。

procedure TForm1.FormCreate(Sender: TObject);
begin
    FGridWindowProc := StringGrid1.WindowProc;
    StringGrid1.WindowProc := NewGridWindowProc;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
    StringGrid1.WindowProc := FGridWindowProc;
end;

procedure TForm1.NewGridWindowProc(var Message: TMessage);
var
  cp: TPoint;
  gc: TGridCoord;
begin
    if (Message.Msg = WM_LBUTTONDOWN) or (Message.Msg = WM_LBUTTONUP) then begin
        GetCursorPos(cp);
        cp := StringGrid1.ScreenToClient(cp);
        StringGrid1.MouseToCell(cp.X, cp.Y, gc.X, gc.Y);
    end else begin
        FGridWindowProc(Message);
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  ColIdx, RowIdx: Integer;
begin
    RowIdx := StringGrid1.Row;
    ColIdx := StringGrid1.Col;
    StringGrid1.Cells[ColIdx, RowIdx] := 'A';
    if RowIdx < 5 then begin
        Inc(RowIdx);
    end else begin
        Inc(ColIdx);
        RowIdx := 0;
    end;
    StringGrid1.Row := RowIdx;
    StringGrid1.Col := ColIdx;
end;

-------ソースここまで-------

deldel様

プログラムで何とか制御しようかと模索していましたが
求めていた結果はまさにこれでした!
こんな使い方があるのですね。
勉強になりましたありがとうございます。

これで解決とさせていただきます。
皆様ありがとうございました。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加