fullerm
fullerm

Reputation: 468

How to move cursor position in Delphi StringGrid cell?

When you have a TStringGrid with the goEditing option set and a cell has several lines of text in it, when you go to edit that cell by clicking on it, the cursor will be at the very end of that text. How can you move the cursor to another position? My particular problem is that if the text has a carriage return at the end, the user thinks the cell is empty. I'd like to move the cursor before any carriage returns.

Upvotes: 1

Views: 3456

Answers (2)

Sam
Sam

Reputation: 2552

Assuming you are using the VCL, InplaceEditor is a property of TCustomGrid. It is of type TInplaceEdit which descents from TCustomEdit. You can move the cursor inside of it Just like a TEdit.

If you are using the automatic way of editing the content of the cell, you can use the following way to move the cursor. I have tested it and it works for me. (I am using Berlin in Windows 10)

unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids;

const
  WM_MY_MESSAGE = WM_USER + 1;

type
  TStringGridEx = class helper for TStringGrid
  public
    function GetInplaceEditor(): TInplaceEdit;
  end;

  TForm1 = class(TForm)
    aGrid: TStringGrid;
    procedure FormCreate(Sender: TObject);
    procedure aGridGetEditText(Sender: TObject; ACol, ARow: Integer; var Value: string);
  private
    procedure OnMyMessage(var Msg: TMessage); message WM_MY_MESSAGE;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.aGridGetEditText(Sender: TObject; ACol, ARow: Integer; var Value: string);
begin
  PostMessage(Handle, WM_MY_MESSAGE, 0, 0);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  y: Integer;
  x: Integer;
begin
  for y := 0 to aGrid.RowCount do
  begin
    for x := 0 to aGrid.ColCount do // fill the grid
      aGrid.Cells[x, y] := Format('Col %d, Row %d'#13#10, [x, y]);
  end;
end;

procedure TForm1.OnMyMessage(var Msg: TMessage);
var
  pInplaceEdit: TInplaceEdit;
begin
  pInplaceEdit := aGrid.GetInplaceEditor();
  if Assigned(pInplaceEdit) then
  begin
    pInplaceEdit.SelStart := pInplaceEdit.EditText.TrimRight.Length;
    pInplaceEdit.SelLength := 0;
  end;
end;

{ TStringGridEx }

function TStringGridEx.GetInplaceEditor: TInplaceEdit;
begin
  Result := InplaceEditor; // get access to InplaceEditor
end;

end.

Sam

Upvotes: 4

Remy Lebeau
Remy Lebeau

Reputation: 595782

Rather than trying to manipulate the editor's cursor, I would suggest trying to avoid storing trailing line breaks in the StringGrid to begin with. You can use the OnGetEditText event to trim off the trailing line breaks when the editor is activated, and the OnSetEditText event to trim them off when the user enters new text.

Upvotes: 4

Related Questions