OnVScroll と、行番号 – プログラミング – Home

通知
すべてクリア

[解決済] OnVScroll と、行番号


シルク法度
 シルク法度
(@シルク法度)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

CRichEditCtrl の OnVScroll をハンドルして、処理を行いたいと思っています。
OnVScroll をハンドルして、スクロールする前に、
スクロール先の行に対して処理をおこないたいのですが、
うまくいきません。
OnVScroll の引数 nPosは、なにを示しているのでしょうか?
行番号を示しているわけでもないようですし、
フォント縦サイズ*行数 を示しているような気もしますが、
そうでないときもあるようです。
よろしくおねがいします。


引用未解決
トピックタグ
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
 

>nPos
>スクロール バーのコードが SB_THUMBPOSITION または SB_THUMBTRACK の場合は、
>スクロール ボックスの現在位置を指定します。それ以外の場合は使いません。
>スクロール範囲の初期値によっては、nPos が負の値になることもあるので、
>必要に応じて int 型へキャストしなければいけません。

「Visual Studio 6.0 MSDN」にしっかりと解説が日本語で載ってますけど?

>発言される前に「使用上の注意」を必ずお読み下さい。
はどうなった

自分で調べる努力していないでしょう?


返信引用
シルク法度
 シルク法度
(@シルク法度)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

えーと。質問のしかたがまちがってたかもしれません。
OnVScroll でえられる、引数 nPos は、スクロールバーの
位置を示していますが、エディタの行には、一対一で対応はしていません。
過去ログにのってあるのは、あくまでもスクロールバーの位置
を操作する方法であって、エディタの指定行を操作する場合では
ないです。
MSDNもしらべましたが、具体的な方法はのっていませんでした。

しかし、今日、ふとひらめいて、その方法でうまくいったので
一応お知らせしておきます。

まず、エディタの行番号と、スクロールバーの位置nPos には
直接的な関連はありません。しかし、スクロールバーの
範囲と、エディタの行範囲は、一対一に対応しています。
そこで、スクロールバーの範囲を取得し、nPos との比をもとめ、
それを、エディタの最大行数に乗ずることで、nPos に関連する
行番号を間接的にもとめることができました。

スクロールバーの範囲と、エディタの最大行番号を求めるメソッドは
存在するので、上記の方法は可能となります。

というわけで、方法が判明しましたので、おしらせします。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

EM_CHARFROMPOS:座標から文字位置を求める
EM_LINEFROMCHAR:文字位置から行番号を求める

を組み合わせれば、たとえば、ウィンドウの一番上の行番号を求めるには、

CRichEditCtrl edit;
LPOINT pt = {0,0};
UINT charIndex = edit.SendMessage(EM_CHARFROMPOS,0,(LPARAM)&pt);
UINT lineIndex = edit.LineFromChar(charIndex);

RichEditは行ごとに高さを変えられるので、
比を使った方法は普遍的な手法ではありませんね。


返信引用
シルク法度
 シルク法度
(@シルク法度)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

返事,ありがとうございます.

>CRichEditCtrl edit;
>LPOINT pt = {0,0};
>UINT charIndex = edit.SendMessage(EM_CHARFROMPOS,0,(LPARAM)&pt);
>UINT lineIndex = edit.LineFromChar(charIndex);

表示画面の最初の行番号を求めるメソッドは,
CRichEditCtrl::GetVisibleFirstLine()を使えば簡単です.

私が知りたかったのは,座標から,行番号を求めたいのではなく,
OnVScroll() で渡される引数 nPos からエディタの行番号を
得る方法でした.

nPos は,クライアント座標値を示しているわけではないので,
上記の変換処理はつかえません.

>RichEditは行ごとに高さを変えられるので、
>比を使った方法は普遍的な手法ではありませんね。

私の提案した方法は,行数に比を乗じて.行番号を得るので,
各行のフォント高さには無関係です.
したがって,行高さに依存しない方法であるといえます.


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

失礼しました。
nPosの値についてまだはっきりしてませんでしたね。

nPosの値(スクロール位置)は、一番上からスクロールしたピクセル数です。
ピクセル数なので、各行の高さの影響を受けます。
そのため、行番号とは比例関係にありません(全ての行の高さが同じ場合を除く)。

nPosは現在のスクロール位置ですので、
それはつまり、現在表示されている行のことだと思い、
先の例を挙げました。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

横槍になりますが、そもそもCRichEditCtrlクラスは、
画面上のピクセル値またはそれに比例した値でスクロール管理をしているのか、
行数に比例した値でスクロール管理をしているのか、
どちらなんでしょう?

前者であれば、行数で割って出した係数は状況によっては無意味になりますし、
後者であれば、行数で割って出した係数で良いということになるんですけれど。


返信引用
シルク法度
 シルク法度
(@シルク法度)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

みなさん。いろいろとご意見ありがとうございます。

>nPosの値(スクロール位置)は、一番上からスクロールしたピクセル数です。
>ピクセル数なので、各行の高さの影響を受けます。
>そのため、行番号とは比例関係にありません(全ての行の高さが同じ場合を除く)。
 
 実は、私の方法で行を求めた場合、時々1行ほどずれることがありました。
行ごとに高さが違うのであれば、その理由も説明つきます。
でも、これを解決するのは難しそうですねえ~。。。
一行ごとに高さを求めて。。。。とかしてると時間がかかりますし。。。
行高さを一定にするやりかたを調べたと思います。

>横槍になりますが、そもそもCRichEditCtrlクラスは、
>画面上のピクセル値またはそれに比例した値でスクロール管理をしているのか、
>行数に比例した値でスクロール管理をしているのか、
>どちらなんでしょう?

 後者だとおもいます。その理由として、スクロールバーの矢印ボタンをおすと、
行単位でスクロールするからです。
しかし、OnVScroll() は、CWnd のメソッドなので、ピクセル値でしか
引数がこないようです。それがやっかいなんですよね~。。。


返信引用
シルク法度
 シルク法度
(@シルク法度)
ゲスト
結合: 23年前
投稿: 14
Topic starter  

>実は、私の方法で行を求めた場合、時々1行ほどずれることがありました。
>行ごとに高さが違うのであれば、その理由も説明つきます。
>でも、これを解決するのは難しそうですねえ~。。。
>一行ごとに高さを求めて。。。。とかしてると時間がかかりますし。。。
>行高さを一定にするやりかたを調べたと思います。

行がずれるのは、整数値で計算していたからでした。
実数値に変更し、四捨五入をしたところ、
きちんと正確な行番号が計算できたので、
おしらせしておきます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました