memoの行数を知る方法を教えてください。

解決


AS  2018-03-02 21:29:59  No: 49027

今、英語を喋らせるのに熱中しています。
英語の教科書を打ち込んで、memoに表示させて、見える範囲を喋らせるプログラムを組んでいます。
最初の行は、
gyo:=GetScrollPos(memo1.Handle,SB_VERT);
を使って分かるのですが、表示されている行数を示す関数が分かりません。
GyoE:=Gyo+trunc((memo1.Height-23)/20);
で、何とかなったのですが、fontを変えると数字が変わると思いますので、
ここで、質問させていただきます。

memoの行数を知る方法を教えてください。

よろしくお願いします。


通りすがり  2018-03-02 21:53:58  No: 49028

Lines.Count ということではなく?


KONNOYA  2018-03-03 00:09:12  No: 49029

TMemoコンポーネントで表示されている「見た目」の「総行数」「行番号」を取得したい。という事でしょうか?

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class( TForm )
    Memo1: TMemo;
    procedure FormCreate( Sender : TObject );
  private
    { Private 宣言 }
    MemoProc : TWndMethod;
    procedure OnMemoScroll( var Msg : TMessage );  
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate( Sender : TObject );

begin     
  //
  MemoProc         := Memo1.WindowProc;
  Memo1.WindowProc := OnMemoScroll;
end;

procedure TForm1.OnMemoScroll( var Msg : TMessage );

var       
  ScrollInfo : TScrollInfo;

begin   
  MemoProc( Msg );

  case Msg.Msg of
  CN_COMMAND :
    if Msg.WParamHi = EN_VSCROLL then 
    begin 
      // TMemoのスクロール情報取得
      FillChar( ScrollInfo, SizeOF( ScrollInfo ), 0 );
      ScrollInfo.cbSize  := SizeOf( ScrollInfo );
      ScrollInfo.fMask   := SIF_RANGE or SIF_PAGE or SIF_POS;

      if GetScrollInfo( Memo1.Handle, SB_VERT, ScrollInfo ) then
      begin
        // TMemoコンポーネントでの見た目の行数(行番号)を表示
        Caption := '行数 = '   + IntToStr( ScrollInfo.nPage ) + ' / ' +
                   '行番号 = ' + IntToStr( ScrollInfo.nPos  ) + '〜' + IntToStr( ScrollInfo.nPos + ScrollInfo.nPage - 1 );
      end;
    end;
  end;
end;

end.

TMemoコンポーネントのフォントの大きさが変わっても正しく取得できます。
勘違いしていましたらすみません。


AS  2018-03-04 15:32:23  No: 49030

通りすがりさん、ありがとうございます。

KONNOYAさん、ありがとうございます。
やりたいことは、これでいいのですが、ちょっと。

上下の向きの記号を押せば、正しく動き、目的の数字は得られるのですが、
真ん中の棒?を動かすと、反応しませんよね。

これは何とかなりませんか?

*昨夜は飲めない酒をちょっと飲んだので、掲示板を見ていませんでした。
  遅くなって、すみません。


KONNOYA  2018-03-04 20:31:14  No: 49031

そうですよね、ただもっと言えば、
TMemoコンポーネントが生成された時は表示されないのか?とか、
TMemoコンポーネントのサイズが変更された時も表示が更新されないのか?とか、
色々有ります。

下記コードはその対策を施したコードです。

unit Unit1;

interface

uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, StdCtrls; 

type
  TForm1 = class( TForm )
    Memo1: TMemo;
    procedure FormCreate( Sender : TObject );
  private
    { Private 宣言 }
    MemoProc : TWndMethod;
    procedure OnMemoScroll( var Msg : TMessage );
    procedure DrawScrollInfo;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate( Sender : TObject );

begin
  //
  MemoProc         := Memo1.WindowProc;
  Memo1.WindowProc := OnMemoScroll;
end;

procedure TForm1.OnMemoScroll( var Msg : TMessage );

begin
  MemoProc( Msg );

  case Msg.Msg of
  WM_CREATE  :
    DrawScrollInfo;
  WM_SIZE    :
    DrawScrollInfo;
  CN_COMMAND :
    if Msg.WParamHi = EN_VSCROLL then DrawScrollInfo;
  WM_VSCROLL :
    DrawScrollInfo;
  end;
end;

procedure TForm1.DrawScrollInfo;

var
  ScrollInfo : TScrollInfo;

begin
  // TMemoのスクロール情報取得
  FillChar( ScrollInfo, SizeOF( ScrollInfo ), 0 );
  ScrollInfo.cbSize  := SizeOf( ScrollInfo );
  ScrollInfo.fMask   := SIF_RANGE or SIF_PAGE or SIF_POS;

  if GetScrollInfo( Memo1.Handle, SB_VERT, ScrollInfo ) then
  begin
    // TMemoコンポーネントでの見た目の行数(行番号)を表示
    Caption := '行数 = '   + IntToStr( ScrollInfo.nPage ) + ' / ' +
               '行番号 = ' + IntToStr( ScrollInfo.nPos  ) + '〜' + IntToStr( ScrollInfo.nPos + ScrollInfo.nPage - 1 );
  end;
end;

end.

AS様のご指摘の様に、スクロールバーのつまみを動かしても表示が更新されない!というのは事前にわかっていました。
> 見える範囲を喋らせるプログラムを組んでいます。
という事を仰られていたので、ボタンか何かのトリガで「見た目」の行数や行番号が判れば良いのかと思って投稿していました。

Windowsでは、様々な入力方法があるので、それに対応するにはどうすれば良いのか?を記述してあげないといけません。


AS  2018-03-04 23:40:33  No: 49032

KONNOYA様、ありがとうございました。
朝から「ドラえもん」を見に行っていたので、返事が遅くなりました。
帰りの車の中で、十分な情報はもらっているなと思い、
帰ったらそく作ってみて、お礼を言うつもりでしたが、
先に投稿していただいていました。

私のように分からない人がこの掲示板を見たら役立つと思いますので、
無駄にはならないと思っています。

実際には下記のようなプログラムになりました。
ありがとうございました

procedure TForm1.Label5Click(Sender: TObject);
var
  i:integer;
  GyoS,GyoE:integer;
  ScrollInfo : TScrollInfo;
begin
  FillChar( ScrollInfo, SizeOF( ScrollInfo ), 0 );
  ScrollInfo.cbSize  := SizeOf( ScrollInfo );
  ScrollInfo.fMask   := SIF_RANGE or SIF_PAGE or SIF_POS;
  if GetScrollInfo( Memo1.Handle, SB_VERT, ScrollInfo ) then
  begin
    GyoS:=GetScrollPos(memo1.Handle,SB_VERT);
    GyoE:=GyoS+ScrollInfo.nPage-1;
 end;
 for I :=GyoS to GyoE do
 begin
   FileCut(3,Memo1.lines[i]);
   SpeaktoMe(CutF[1]);
   application.processMessages;
 end
end;


AS  2018-03-04 23:47:25  No: 49033

解決のチェックをしていませんでした。

ありがとうございました。


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








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