度々、お世話になっております。
さっそく質問ですが、
Invalidateの再描写の動きを知りたいのです。。。
例えば、マウスクリックのときに再描写したいと思い、
void CXXXXXView::OnLButtonDown(UINT nFlgs,CPoint point)
{
Invalidate(FALSE);
}
とやると、このOnButtonDown関数を抜けてから、OnDraw関数にいくのでしょうか?
実は今、2つの絵を同時に処理したくて、
2回再描写しようと、以下のようにプログラムを組んでいるのですが、、、
void CXXXXXView::OnLButtonDown(UINT nFlgs,CPoint point)
{
・・・・・・
//On_Drawにある絵を描く関数に渡す引数(位置とBITMAPID)の設定//
Invalidate(FALSE);
//On_Drawにある絵を描く関数に渡す引数(位置とBITMAPID)の設定//
Invalidate(FALSE);
・・・・・・
}
2回目の再描写しか機能していないのか・・・よくわからないんですけど、
2つ目しか絵がかけません。
それで、1つ目と2つ目の間に、MessageBoxなどで適当な処理を加えると、
何かしらのワンクッションが置かれるらしく、2つとも絵が出てきます。
どういう動きでこうなってしまうのかわからないので、教えてください。
それと、再描写のInvalidateの引数について、もう1つ質問があります。
今、FALSEにして前に描いた絵を消さないようにしているのですが、
最小化して元に戻したりすると、前に描いていた絵が消えてしまいます。。。
どうすれば、前の絵を消さずに、再描写できるのでしょうか?
『ららら』の過去ログで、”Invaliate(FALSE)の使い道は?”みたいなやつで、
FALSEじゃなくてもいいっていうのを見たことがあったんですが、
詳しい書き方がなかったので、こちらも教えていただきたいです。
長くなりましたが、よろしくお願いします。
Invalidate() はウィンドウズにメッセージを「ポスト(Post)」します。
ポストされたメッセージに対応するハンドラは、現在実行中のハンドラや
先にポストされていたメッセージに対応するハンドラの実行終了を待って、
実行されます。
OnLButtonDown() で Invalidate() を呼び出すと WM_PAINT がポストされ、
まだ他にポストされたメッセージが無ければ OnLButtonDown() の終了後、
OnEraseBkgnd()、OnDraw() と連続して呼び出されます。
この「ポスト」して順番を待つ、で都合が悪いときには、
Invalidate() の直後に UpdateWindow() を呼ぶことで、即再描画されます。
モーモーさん、今晩は
>Invalidateの再描写の動きを知りたいのです。。。
msdn ライブラリーでお調べになればわかる事ですが
CWnd::Invalidate() は更新領域を(Windows に)通知するだけです
Windows は通知を受けた更新領域を記録し、適切な時期に WM_PAINT をそのウィンドーに
送ります。その結果 CWnd::OnDraw() が動きます
CWnd::Invlidate(BOOL bErase) の仮引数 bErase の件ですが、次回の WM_PAINT で
更新領域内の背景を背景色で塗るかどうかを指示するものです(TURE なら塗る)
TRUE にしていると一々全体を(Invalidate なので全体になる)背景色で塗りつぶしてから
CWnd::OnDraw() で描画を行うので、今まで在った絵が(背景色で塗るので)一瞬消えて再び
現れる事になってちらつくように感じる事があります
>最小化して元に戻したりすると、前に描いていた絵が消えてしまいます。。。
>どうすれば、前の絵を消さずに、再描写できるのでしょうか?
CXXXXXView::OnDraw() での処理に問題があるのではないでしょうか
CXXXXXView::OnLButtonDown() での処理を見ているとそう感じざるを得ません
返事が遅くなって申し訳ありません。
nさん、島さん、レスありがとうございます。
nさんのおっしゃっているようにUpdateWindow()を追加することで、
2回続けて再描写することはできました。
しかし、最小化して元に戻したときは全てがクリアさています。。。
島さんのおっしゃるように、On_Drawの基本的な描き方がなってないのかもしれません。。。
すみませんが、ソースを書いてみましたので、
なにかおかしなところがあれば、ご指摘ください。
よろしくお願いします。
On_Draw(CDC* pDC)
{
・・・・・
if(click == on){ //click は、クリックしているかというフラグ
PicDraw(pDC,SITEN.x,SITEN.y,P_ID);
click = OFF;
}
PicDraw(CDC *pDC,int px,int py,UINT pID)
{
CDC myDC;
CBitmap myBMP;
BITMAP bmpInfo;
myBMP.LoadBitmap(pID);
myBMP.GetObject(sizeof(bmpInfo),&bmpInfo);
int pH = bmpInfo.bmHeight;
int pW = bmpInfo.bmWidth;
myDC.CreateompatibleDC(pDC);
CBitmap* oldBMP = myDC.SelectObject(&myBMP);
pDC->BitBlt(px,py,pW,pH,&myDC,0,0,SRCCOPY);
myDC.Select(&myBMP);
}
一瞬で判るようなコードの問題が何故お判りにならないのかが不思議です
OnDraw() では click が on でなければ描画しない上に、描画後には
click を OFF にするのですから、最小化から元の戻る場合や、他のウィンドーが上に
かさねっていたのがなくなって隠れていた部分を再描画する場合や、では当然 click は
on 以外の値ですから何も描画できません
すみません。。。ありがとうございます。
実は、ソフト起動時にもOn_Drawで初期描写(?)するため、
そのときには、PicDrawの引数が何も設定されてないので、起動すると同時にエラーとなり
落ちてしまいます。
それを、回避しようとして、単純にクリックしたときにフラグを立てただけなのです。。。
すみませんが、どういうふうに実装すれば、オープン時の描写は、うまくいくでしょうか?
いろいろ調べて、OnEraseBkgnd()を使えばInvalidate(true)でも、
いけそうということがわかったのですが。。。。
どうしでも、On_Drawの書き出し(?)が、思いつきません。
もう少しお力をお借りしたく、すみませんが助言お願いします。
SITEN か P_ID かの初期値が有得ない値であれば十分判定可能なのではないでしょうか?
ところで On_Draw() はどのクラスにも属さない函数なのですか?
後、Invalidate() と 再描画との関連についてはお判りになったのでしょうか?
MSDN ライブラリーでお調べになりましたか?
知識が無さ過ぎてすみません。
”函数”ってなんですか?
Invalidateについては、MSDNで調べて見ました。
まだ、なんとなく理解した。。。というところでしょうか。
ご迷惑かけてすみません。
>”函数”ってなんですか?
関数でしょ。
前から気になってたんですが、初心者も見るこういうところでは
一般的な用語使った方がいいと思いますよ > 島さん
>初心者も見るこういうところでは一般的な用語使った方がいいと思いますよ
成る程、そういう意見もあるでしょう(でも函数の方が関数よりも由緒正しいのですよ)
今後は最低限一度は函数(関数)と併用表記するように心掛けます
心掛けるだけ? 仕方ないから、関数とも書いてやるよって感じに取れる…
函数の方が由緒正しいんでしょうけど、初心者も見る掲示板という場において、しかも、
初心者かもしれない人を相手に、由緒正しいのを書くのと、一般的で初心者でも理解できるの
を書くのと、どちらが良いと考えているのでしょうか。
上のカキコからは、前者が良いと考えているんでしょうけども。
>”函数”ってなんですか?
辞書を調べれば一発!
>> ”函数”ってなんですか?
> 辞書を調べれば一発!
まったくだ。訊くまでもないこと。
辞書まで誰かに引いてもらおうってか?
モーモーさんの質問には、答えないのですか??
> モーモーさんの質問には、答えないのですか??
島さんからの質問への、モーモーさんの応答を待っています。