OnDrawにTextOutやDrawTextで書いた文字列をスクロールさせたい – 固定ページ 2 – プログラミング – Home

通知
すべてクリア

[解決済] OnDrawにTextOutやDrawTextで書いた文字列をスクロールさせたい

固定ページ 2 / 3

わか
 わか
(@わか)
ゲスト
結合: 20年前
投稿: 17
Topic starter  

>シャノンさん
いえいえ、まだまだ未熟者なので参考になります。

>PATIOさん
つまりそれってOnUpdateのところに記述しておいて、OnDraw
のところにはUpdateAllViews(this)を記述して、OnUpdate
イベントを起こすというのは、考え方としては間違いではない
と思っていいのでしょうか?といってもそのOnUpdateが呼ばれ
ないんですが・・・。


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

順番としては、こうなると思います。
1. pDoc->UpdateAllViews(this); を呼ぶ(保持データが変化した事を通知)
2. 全ビューの OnUpdate() が呼ばれる
3. OnUpdate() で、Invalidate() 等を呼び出し、
画面の更新を指示する。(表示内容が変化したことを通知)
3. OnDraw() が呼ばれる

なので、OnDraw()の中で1や3が起こりうる操作をするのは、
あまり良くないでしょう。


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

いえ、そもそもOnDrawというのはユーザーがデータを追加したときに呼ばれるのではなくて
画面を更新したいときに呼ばれるものなのでそこでUpdateAllViewsが呼ばれるはずはない
のです。
もし能動的に増やしたり、減らしたりしたいのであれば、
メニューでもこさえてそこを選択されたら増やすとか、
マウスの右クリックで増やすとか、そういうオペレーションを入れるべきです。
ようは、データの増やしたり、減らしたりする操作をOnDrawの中から起動しようというのが
間違いだと思います。


返信引用
REE
 REE
(@REE)
ゲスト
結合: 24年前
投稿: 240
 

UpdateAllViewsは、ドキュメントが変更された時に、他のビューに表示を更新するように
通知するためのものです。

そのためドキュメントに対応するビューのうち、引数に指定していないビューのOnUpdate
が呼ばれます。
従って、UpdateAllViews(this); では、自身のOnUpdateは呼ばれません。
自身を含めたOnUpdateを呼びたいのであれば、引数にNULLを指定してください。


返信引用
わか
 わか
(@わか)
ゲスト
結合: 20年前
投稿: 17
Topic starter  

皆さんレスありがとうございます。
dairygoodsさん、PATIOさんがおっしゃるようにOnDrow内に書く
のは良くないというのは、私もなんとなくそんな気はします。

となると・・・

1.OnDrawでドキュメントにテキストを書いた→とりあえずOK
2.たくさん書いたからドキュメントの高さを増やしたい→どこで?
3.高さを増やしたからスクロール幅も増やしたい→どこで?

dairygoodsさんの言われるような、「順番」というのは、みなさん
どこで覚えてくるのでしょう。経験ですか?
(正直、まだデバッグ方法が良くわかっていないせいもあるが)

試しにREEさんのおっしゃるとおり、NULLを指定したら、確かに
OnUpdateイベントが起きました。
でも、これやっちゃだめなんですよねぇ。。。


返信引用
REE
 REE
(@REE)
ゲスト
結合: 24年前
投稿: 240
 

>1.OnDrawでドキュメントにテキストを書いた→とりあえずOK

OnDrawは、ドキュメントの内容を表示するのが役割ですので、
ここで、ドキュメントの変更はしないで下さい。

>2.たくさん書いたからドキュメントの高さを増やしたい→どこで?
>3.高さを増やしたからスクロール幅も増やしたい→どこで?

ドキュメントの高さやスクロール幅を変えるのは、ドキュメントの変更をしたときです。

>試しにREEさんのおっしゃるとおり、NULLを指定したら、確かに
>OnUpdateイベントが起きました。
>でも、これやっちゃだめなんですよねぇ。。。

はい、やらないほうが良いです。


返信引用
わか
 わか
(@わか)
ゲスト
結合: 20年前
投稿: 17
Topic starter  

>REEさん

ますますわからなくなってきてしまいました。
何か私勘違いしてますか?

>OnDrawは、ドキュメントの内容を表示するのが役割ですので、
>ここで、ドキュメントの変更はしないで下さい。

いろんなサイト、参考書をみると全てOnDrawにTextOutを書いて
います。これってホントはやっちゃいけないんですか?
「内容を表示」するというのはどういう意味なのでしょう?
TextOutは「ドキュメントの変更」を指しているのですか?

>ドキュメントの高さやスクロール幅を変えるのは、ドキュメントの変更をしたときです。

私、ドキュメントの変更の意味がわかっていないみたいです。


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 22年前
投稿: 830
 

正直 Document-View が何ぞや、あたりからはじめてもらうほうがよさげな気がします。
Scribble とか(Doc-View 入門的には良いけど他の部分が古杉ですが)

Document っつーのは単なるデータです。
HTML をご存知なら例えば <iostream> という文字列を考えましょう。
View っつーのはそれを表示する手段。
先ほどの Document に対して Text-View なるものを用意すると <iostream> と表示。
同じ Document を Html-View なるもので表示すると <iostream> と表示。
# 表示するように view を作る、ってこと。

TextOut は画面にデータを表示する関数です。
表示する際にどのような形式を用いるかを View は決めます。
OnDraw は「描画しなさい」って通知なので View は既存の Doc を自分の形式で表示します。
OnDraw の度に Doc の内容が変わるあるいは変えるっつーのは設計がヘン。

Doc の変更ってのは先の文字列が #include &lt;iostream&gt; に変わったとか。
すると表示されるべき幅が変わるはずです。
ScrollSize を変更する必要は、そんなときだけ生じるはず。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 23年前
投稿: 1301
 

>>試しにREEさんのおっしゃるとおり、NULLを指定したら、確かに
>>OnUpdateイベントが起きました。
>>でも、これやっちゃだめなんですよねぇ。。。
>
> はい、やらないほうが良いです。

え? なんで? 他のViewまでre-drawしちゃうから?


返信引用
るーた
 るーた
(@るーた)
ゲスト
結合: 21年前
投稿: 10
 

「ドキュメントの変更」を描画領域の変更と置き換えて考えてみてください。


返信引用
たいちう
 たいちう
(@たいちう)
ゲスト
結合: 23年前
投稿: 662
 

> え? なんで? 他のViewまでre-drawしちゃうから?

OnDraw でやってはダメなんだという話でしょう。
NULL だろうと this だろうと。

# 掲示板での説明では限界があると思いますので、参考書を紹介します。
# 回答者とわかさんの努力によって今回の問題が解決した後でも役に立つと思います。
# 『Inside Visual C++ version5―Microsoft Visual C++ Ver.5標準教科書』

http://www.amazon.co.jp/exec/obidos/ASIN/4756121748/qid=1108516441/ref=sr_8_xs_a
p_i1_xgl/249-2911650-4016320


返信引用
REE
 REE
(@REE)
ゲスト
結合: 24年前
投稿: 240
 

>「ドキュメントの変更」を描画領域の変更と置き換えて考えてみてください。

いやこれは却って誤解を招きそうです。

描画領域の変更は、むしろビューの変更です。
描画内容の変更ならいいですが・・

>> はい、やらないほうが良いです。
>え? なんで? 他のViewまでre-drawしちゃうから?

これに関しては、たいちうさんのフォロー通りの意味です。


返信引用
わか
 わか
(@わか)
ゲスト
結合: 20年前
投稿: 17
Topic starter  

みなさん長い間お付き合いいただき、ありがとうございます。
私のためを思って、答えを自分で導き出せるように遠まわしに回答して
いただいたりしていただいたようですが、あまり時間もなくなってきて
しまったため、今回のところはもう降参です。

ズバリ教えてください。

1.デフォルトで表示したいテキストを書く場所(TextOut)
2.1に対してスクロール幅を計算および、設定する場所(SetScrollSizes)
3.ウィンドウのサイズを変更したときに2を再計算、再設定する場所
4.ResizeParentToFit(TRUE);を書く場所

私の回答は
1.OnDraw
2.OnInitialUpdateとOnUpdate
3.2と同様
4.OnUpdate

ですが、これではうまくいきませんでした。
どういう結果になるかというと、
1.垂直スクロールバーの計算はうまくいっているように
  見えるが、ツマミを一番下までもってくると、最後の
  行が表示されていない。
2.スクロールすると残像が残る。
3.一番下までスクロールしたあと、ウィンドウの位置を
  変えると、一番上の行が表示される。(スクロールバー
  のツマミは一番下にきたまま)

どうぞ宜しくお願いいたします。


返信引用
REE
 REE
(@REE)
ゲスト
結合: 24年前
投稿: 240
 

>1.デフォルトで表示したいテキストを書く場所(TextOut)
>2.1に対してスクロール幅を計算および、設定する場所(SetScrollSizes)
>3.ウィンドウのサイズを変更したときに2を再計算、再設定する場所
>4.ResizeParentToFit(TRUE);を書く場所

>私の回答は
>1.OnDraw

これでOKです

>2.OnInitialUpdateとOnUpdate

これもOKでしょう

>3.2と同様

これは、一般的には不要ですが、
もし書くとしたら、WM_SIZEのハンドラであるOnSizeです。

>4.OnUpdate

これもOKですね

ちなみに、OnDrawで使っているNowTopって何のための変数ですか?
普通にスクロールすればいいのであれば、この様な変数は不要です。
高速化が必要な場合を除いてOnDrawでは現在のスクロール位置とは無関係に描画すればよ
いです。


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

> 私のためを思って、答えを自分で導き出せるように遠まわしに回答して
> いただいたりしていただいたようですが

というより、どこで躓いているか見えないので、
一般的な仕組みを理解してもらい、
間違いor勘違いを自力で見つけてもらうしかないのです。

> 2.1に対してスクロール幅を計算および、設定する場所(SetScrollSizes)
> 3.ウィンドウのサイズを変更したときに2を再計算、再設定する場所

この表現がちょっと気になります。

SetScrollSizes は、スクロール等考慮せず、
自分の描きたい絵が 何×何 ピクセルかを指定するだけです。
スクロールバーの設定は、MFCが勝手に計算してくれます。

画面サイズの変更によって、表示する内容が変化しないのであれば、
SetScrollSizes を呼び出す必要はありません。

そして、
OnDrawでは、たとえば、SetScrollSizes で 1000x1000 を指定したなら、
(0, 0) - (1000, 1000) の領域に好きなように描くだけです。

#印刷もする場合は、論理単位(mmなど)を使わないと
#画面と紙のサイズが合いませんが。

> 4.ResizeParentToFit(TRUE);を書く場所

ResizeParentToFit() は、ビュー自身のサイズにあわせて、
メインウィンドウのサイズを変更する機能です。
ウィンドウサイズは、大抵、ユーザーが自由に決めますし、
さらに、何か変更するたびにウィンドウサイズが変化しては、
使いづらいでしょう。

多分、呼び出し自体不要だと思います。
どうしても必要なら、OnInitialUpdateでしょう。


返信引用
固定ページ 2 / 3

返信する

投稿者名

投稿者メールアドレス

タイトル *

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