カーソルの位置の行・列番号を表示するには?

解決


リッチエディット  2004-04-13 06:05:36  No: 8329

初心者です。どうか宜しくお願い致します。
リッチエディットでテキストエディタの作成に挑戦しています。
メモ帳の様に、現在のカーソルの位置の行番号と列番号をステータスバーに表示したいのですがどうすればよいか解りません。教えていただけないでしょうか。


_  2004-04-13 07:18:47  No: 8330

余談ですがエディタを作るならフリーの高機能なコンポを使ったほうがいいですよ


jok  2004-04-13 08:52:33  No: 8331

ApplicationEvents1 を置いてその OnIdle イベントハンドラを以下のようにします。

procedure TForm1.ApplicationEvents1Idle(Sender: TObject;
  var Done: Boolean);
var
  Line,CharNo:integer;
begin
  with RichEdit1 do begin
    Line := SendMessage(Handle,EM_LINEFROMCHAR,SelStart,0);
    CharNo := SendMessage(Handle,EM_LINEINDEX,Line,0);

    StatusBar1.SimpleText := Format('  %.4d 行  %.4d 列',
                                    [Line+1,SelStart-CharNo+1]);
  end;
end;


jok  2004-04-13 12:03:53  No: 8332

無駄なコードを実行しないように、少し改良しました。

type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    RichEdit1: TRichEdit;
    ApplicationEvents1: TApplicationEvents;
    procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
  public
    revSelStart:integer; // 手動で追加する
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ApplicationEvents1Idle(Sender: TObject;
  var Done: Boolean);
var
  Line,CharNo:integer;
begin
  if revSelStart <> RichEdit1.SelStart then
  with RichEdit1 do begin
    revSelStart := SelStart;
    Line := SendMessage(Handle,EM_LINEFROMCHAR,SelStart,0);
    CharNo := SendMessage(Handle,EM_LINEINDEX,Line,0);

    StatusBar1.Panels[0].Text := Format('  %.4d 行  %.4d 列',
                                    [Line+1,SelStart-CharNo+1]);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  revSelStart := -1;
end;


リッチエディット  2004-04-14 04:51:58  No: 8333

_さん、jokさんありがとうございます。
jokさん、コードまで書いていただきありがとうございます。
revSelStartを設けたのはどういうことなのでしょうか?


Muda?  2004-04-14 06:59:00  No: 8334

>revSelStartを設けたのはどういうことなのでしょうか?
試しにメンバー変数IdleCnt追加して、こないコードでマウス動かして
revSelStart変数あるなしの違い実感してや。

    ........
    inc(IdleCnt);
    StatusBar1.Panels[0].Text := Format('  %.4d 行  %.4d 列  Cnt=%d',
    [Line+1, SelStart-CharNo+1, IdleCnt]);
  end;


jok  2004-04-14 08:12:35  No: 8335

> revSelStartを設けたのはどういうことなのでしょうか?

詳しく説明するわけにはいかないのですが、Application.OnIdle イベントは
かなり頻繁に起こります。そのたびに表示を更新するのは無駄だと思いますので、
revSelStart に前回のキャレット位置を保存しておき、キャレット位置に変化が
あったときだけ、表示を更新するようにしているわけです。Muda? さんの指摘通り
のコードを実行してみると違いが分かりると思います。


リッチエディット  2004-04-15 05:09:41  No: 8336

Muda?さんのコードを実行してみました。
どちらもずっとCnt=1のままで違いがわかりません。


るるとん@K  2004-04-15 05:26:42  No: 8337

みえないところでかかる負担を少なくしているわけです


jok  2004-04-15 05:33:10  No: 8338

> どちらもずっとCnt=1のままで違いがわかりません。

これは

> 試しにメンバー変数IdleCnt追加して、

をしてなくて、ローカル変数にしてるんじゃないですか?

> キャレット位置に変化があったときだけ

の条件は、コードの中の

if revSelStart <> RichEdit1.SelStart then

の部分で判断しています。この判断をする前とした後でどのくらい回数が違うか
を見るといいのです。以下のようにします。

type
  TForm1 = class(TForm)
    StatusBar1: TStatusBar;
    RichEdit1: TRichEdit;
    ApplicationEvents1: TApplicationEvents;
    procedure ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
  public
    revSelStart:integer; // 手動で追加する
    IdleCnt1,IdleCnt2:integer; // これらも手動で追加する
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.ApplicationEvents1Idle(Sender: TObject;
  var Done: Boolean);
var
  Line,CharNo:integer;
begin
  inc(IdleCnt1);
  if revSelStart <> RichEdit1.SelStart then
  with RichEdit1 do begin
    revSelStart := SelStart;
    Line := SendMessage(Handle,EM_LINEFROMCHAR,SelStart,0);
    CharNo := SendMessage(Handle,EM_LINEINDEX,Line,0);
    Inc(IdleCnt2);
    StatusBar1.Panels[0].Text := Format('  %.4d 行  %.4d 列  OutIf: %d   InIf: %d',
                                    [Line+1,SelStart-CharNo+1,IdleCnt1,IdleCnt2]);
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  revSelStart := -1;
end;

これで、OutIf の回数が InIf の回数よりかなり多いことが分かるでしょう。


リッチエディット  2004-04-15 06:23:45  No: 8339

ローカルにしてました…

たいへんお手数をおかけ致しました。
有り難う御座いました。


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

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






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