RichEditなどでX座標を保存し復帰させるには?

解決


KEN  2007-01-26 23:17:10  No: 24607

DelphiページにC++Builderでヘルプするのは失礼だと思うのですが、m(_ _)m 

 RichEditなどのテキストでテキストの表示座標を保存し、復帰させたいのですが、
以下のコードではx座標でスクロールできませんでした。
コードが間違ってると思うのですがどう書けばよろしいでしょか。
よろしくお願いします。

  //スクロール座標保存
  scrollX = RichEdit1->Perform(EM_GETLINECOUNT,0,0);    //? ※横スクロール方法が不明。効果なし。
  scrollY = RichEdit1->Perform(EM_GETFIRSTVISIBLELINE,0,0);
  ※scrollXは常に0が入ってしまいます。

  //スクロール座標復帰
  RichEdit1->SelStart = 0;
  RichEdit1->Perform(EM_SCROLLCARET ,0,0);
  RichEdit1->Perform(EM_LINESCROLL,scrollX,srollY);


かふぇ  2007-01-30 18:34:50  No: 24608

scrollX に総行数が入っていますが、現在行数を取りたいのでしょうか?
その場合は
SendMessage (ハンドル, EM_LINEFROMCHAR, -1, 0);
としてください。

試していませんが、
SendMessage (ハンドル, EM_LINEINDEX, -1, 0);
で先頭行までのバイト数を取得して

RichEdit1->SelStart = 先頭行までのバイト数;
RichEdit1->SetFocus();

でいけると思います。

あっ、SendMessage() じゃなく Perform()使っても問題ないと思います。


KEN  2007-01-31 04:24:11  No: 24609

レスありがとうございます。

僕の説明不足で申し訳ありません。
縦にスクロールする場合は
以下のような感じで現在座標を取得してスクロールできます。

//テキストの見えてるテキスト先頭取得
scrollY = RichEdit1->Perform(EM_GETFIRSTVISIBLELINE,0,0);
//スクロール(相対のため座標を先頭にしてスクロール)
RichEdit1->Perform(EM_LINESCROLL,0,srollY);

横スクロールの場合は以下のようにsrollXと書かれた部分でスクロールできると
踏んでたのですがまったくスクロールできませんでした。

//スクロール(相対のため座標を先頭にしてスクロール)
RichEdit1->Perform(EM_LINESCROLL,srollX,srollY);

使用目的はテキストエディタで現在のスクロール座標を保存しておいて、
起動時に復帰させたいのです。
カーソル座標ではなくスクロール座標を保存できないかと探してるんですが
今のところ分からないです。


にしの  2007-01-31 06:35:01  No: 24610

こんな感じでどうでしょう。
Delphiですが。
# スクロールバーが表示されていないとAPIは失敗します

iv, ih: integer;//どっかに宣言

//スクロール位置を保存
procedure TForm1.Button1Click(Sender: TObject);
var
  si: TScrollInfo;
begin
  si.cbSize := SizeOf(TScrollInfo);
  si.fMask := SIF_POS;
  if GetScrollInfo(RichEdit1.Handle, SB_VERT, SI) Then
  begin
    iv := si.nPos;
    Memo1.Lines.Add('VERT:' + IntToStr(si.nPos));
  end;
  if GetScrollInfo(RichEdit1.Handle, SB_HORZ, SI) Then
  begin
    ih := si.nPos;
    Memo1.Lines.Add('HORZ:' + IntToStr(si.nPos));
  end;
end;

//スクロール位置を復帰
procedure TForm1.Button2Click(Sender: TObject);
var
  si: TScrollInfo;
begin
  si.cbSize := SizeOf(TScrollInfo);
  si.fMask := SIF_POS;

  si.nPos := iv;
  SetScrollInfo(RichEdit1.Handle, SB_VERT, SI, TRUE);

  si.nPos := ih;
  SetScrollInfo(RichEdit1.Handle, SB_HORZ, SI, TRUE);
end;


にしの  2007-01-31 06:38:23  No: 24611

追記。
スクロールバーだけで、内容が追従していませんでした。
上のソースは無視してください。


にしの  2007-01-31 06:59:14  No: 24612

これでできました。

//スクロール位置を保存
procedure TForm1.Button1Click(Sender: TObject);
var
  si: TScrollInfo;
begin
  si.cbSize := SizeOf(TScrollInfo);
  si.fMask := SIF_POS;
  if GetScrollInfo(RichEdit1.Handle, SB_VERT, SI) Then
  begin
    iv := si.nPos;
    Memo1.Lines.Add('VERT:' + IntToStr(si.nPos));
  end;
  if GetScrollInfo(RichEdit1.Handle, SB_HORZ, SI) Then
  begin
    ih := si.nPos;
    Memo1.Lines.Add('HORZ:' + IntToStr(si.nPos));
  end;
end;

//スクロール位置を復帰
procedure TForm1.Button2Click(Sender: TObject);
var
  Msg:TWMScroll;
begin
  Msg.Msg := WM_VSCROLL;
  Msg.Pos := iv;
  Msg.ScrollBar := 0;
  Msg.ScrollCode := SB_THUMBTRACK;
  RichEdit1.Dispatch(Msg);
  Msg.ScrollCode := SB_THUMBPOSITION;
  RichEdit1.Dispatch(Msg);
  Msg.ScrollCode := SB_ENDSCROLL;
  RichEdit1.Dispatch(Msg);

  Msg.Msg := WM_HSCROLL;
  Msg.Pos := ih;
  Msg.ScrollBar := 0;
  Msg.ScrollCode := SB_THUMBTRACK;
  RichEdit1.Dispatch(Msg);
  Msg.ScrollCode := SB_THUMBPOSITION;
  RichEdit1.Dispatch(Msg);
  Msg.ScrollCode := SB_ENDSCROLL;
  RichEdit1.Dispatch(Msg);
end;


KEN  2007-02-01 07:50:34  No: 24613

にしのさんのソースをさっそくテストしてみました。
ちゃんとDELPHIで。(笑う)
C++Builder6.0Professional
Delphi6.0Professional
両方持っておりますので。

問題なく動作していることを確認しました。m(__)m
以下のコードではスクロールでは無理なんですね。
SendMessage()でも試してみたのですが駄目でした。
>RichEdit1->Perform(EM_LINESCROLL,x,y);

C++BuilderよりDELPHIユーザーのほうが
多い気がするんでいつもDELPHIページ見てます。
かふぇさん、にしのさんどうもありがとうございました。
(^^)ゞ ぽりぽり


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

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






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