Delphi5Proを使用しております。
StringGridにてクリックを行った時にセルのフォーカスが移動しないようにするにはどうすればよろしいでしょうか。
ご教授いただければ幸いです。
OnSelectCellイベントで、CanSelect := False;
にすると、選択できなくなりますが・・・・
ただ、これだと、矢印キーによるセルの移動もできなくなりますね。
変な仕様のような気がするけれど、こんな感じなんでしょうか?
なお、一部しか見えていないセルをクリックするとスクロールするけれど、
スクロールしなくなります。
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;
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を保持するしか方法はありませんでしょうか?
ご助言頂けましたら助かります。
「グリッドはあくまで表示専用」ということでしたら、
TPanelの中にTStringGridを置いて、TPanelのEnabledをFalseにすればいいと思います。
通りすがり様からご教授いただいたソースを
下記のように一部変更したことで理想の結果が得られました。
たいへん勉強になりました。
どうもありがとうございます。
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様
プログラムで何とか制御しようかと模索していましたが
求めていた結果はまさにこれでした!
こんな使い方があるのですね。
勉強になりましたありがとうございます。
これで解決とさせていただきます。
皆様ありがとうございました。
ツイート | ![]() |