> 「BeginPaint/EndPaintはどんな時にどう使うのか?」とか、
これらはWin32APIのひとつですから、使い方はSDKのルールです。
WM_PAINT (MFCでいえばOnPaintにマップされる)の中で使います。
> 「なんで他の関数内で描画するときはCClientDCを使うのに、
> OnPaintの中ではCPaintDCを使うのか?」とか、
BeginPaint以外にも、GetDCやGetWindowDC、CreateDC, CreateCompatibleDCなど、
用途に応じた複数のAPIがあり、それぞれに機能が違うため、
それらをラップしているMFCにおいても使うものが変わるのです。
先にあげられてるリンク先から参照できるCWnd::BeginPaintの仕様です。
http://msdn.microsoft.com/ja-jp/library/xyfxza1c.aspx
「BeginPaint メンバ関数を呼び出すのは、WM_PAINT メッセージに応答するときだけです。」
と書いてあります。更新フラグやカレットの操作などもするので、
WM_PAINTではこれを使うべきだし、これを呼ばねばならないのです。
> 「いったいどっちが正しい順番なんだろう?」って、疑問に思っています。
「どっちが正しい順番」という疑問はそもそも解決不能かと。
どちらでもいいか、どの順番にするかは、前後の命令によるものであって、
常に正しい順番なんてものはないわけで。
参考書の記述がバグってない限りはどちらも正しい記述でしょうし、
その参考書の記述の妥当性は、個々の処理やAPIについてMSDNなどで確認し、
何をやっているか正しく理解した上で、初めて判断できうるものです。
仕様確認(MSDN)や、動作の理解なしに引用で書いてると、今後もはまると思いますよ。
まぁ、MFCってのは多分、本質的にWin32を知らないと使いこなせないものだと思ってます。
「知ってる人が多少楽するためのもの」であって、Win32を調べずにまともなものが書けたら
よほど運がいいか、センスがいいか…単に問題に気づけないだけか、と思います。
> 「OnEraseBkgnd」のpDCに描画しても、うまくいきました。
> ただし、その場合はデフォルトのコードの「return CDialog::OnEraseBkgnd(pDC);」
を
> コメントアウトして「return TRUE;」としないと、描画しても消えてしまうようで
す。
自前で背景を消去したときはTRUEを返す必要がある。
デフォルトではウィンドウクラスに登録した背景ブラシで塗り潰される。
MSDNライブラリでOnEraseBkgndのページを見るとそんなことが書いてあります。
http://msdn.microsoft.com/ja-jp/library/a0a52fkz.aspx
余談ですが、ゲームソフトのように常にクライアント領域全体を使って描画するとき
はウィンドウクラスの背景ブラシをNULLにしOnEraseBkgnd(WM_ERASEBKGND)でTRUEを返す
だけにすると無意味な背景消去処理を省けるので若干高速化できたりします。
みなさん、本当にありがとうございました。
しくみをちゃんと理解してないのに、「できるはず」と思っていたのは
自惚れだったと実感しました。
せっかくアドバイスいただいたのに、きちんと理解できないことがあったりして、
本当にすみませんでした。
にもかかわらず根気よくアドバイスいただき、本当に感謝しております。
今まで、「なんとかうまくいってるから大丈夫」と思って
そのまま作り続けていたのですが、
もしかしたら問題ばかりの危険なコードだらけかもしれませんので、
どのみち勉強は必ず行うようにします。
> 余談ですが、ゲームソフトのように常にクライアント領域全体を使って
> 描画するときはウィンドウクラスの背景ブラシをNULLにし
> OnEraseBkgnd(WM_ERASEBKGND)でTRUEを返すだけにすると
> 無意味な背景消去処理を省けるので若干高速化できたりします。
ありがとうございます。
今まで、OnPaint以外のところで描画するとき、
Invalidate関数を使うとなぜかチラつきが発生していたので
「CClientDC myDC(this);」で作成したmyDCに描画してたのですが、
その方法を試したらチラつきが発生しなくなりました。