円でエンエンエン

 

パパママ地獄編

雪山に消えた一匹のワンワン の巻

 

ワンワンでーす

 

とりあえずいろいろやってパパママのアイデアをまとめた。SynthEditというソフトがあってそういう感じにしてみたいと思う。

 

http://www.aaa-int.or.jp/jfactory/projects/SynthEdit/

 

で、あーでもなくこうでもなくやってみたら、まあVISIOっぽい画面が完成した。

 

フォーカスしてると赤くなったりして、無駄にてがこんでいる。

四角がドラッグなどで動くが、ちらつきが気になったのでインターネットに言われるがままビユーで                        

this->InvalidateRect(NULL,FALSE);

したら、残像拳が三倍も、いや六倍近く残るようになった。(ちらつきはなくなったが)。そんで、メモリDCなどを使うなどの記述もあったが完全に私の頭はクリアされていて、空いた場所にはワンワンや、おかあさんと一緒、しましまのしまじろうののぶゆきおにいさん(通称ノブ)などが入っていた。うれしくなっちゃうナー、ワン。

ワンワンでーす

 

残像拳数十倍の図

 

この残像拳を消したいとせつに願うが、そもそもビユーとは何か、誰も教えてくれない。本場USAから出版されているチャオチェン先生作の「ヴィジアルCと(とっても)MFC」をひもといてみると。こんな図が書いてある。

・・・・・。

「物を覚えるにはまず人をおちょくるような立場でものを考えよ」とは確か先代の言葉だったが。それはここでも当てはめることができよう。そして、ここで、かなり昔に円でエンエンエンの連載中に、仕事で調べたからという理由で掲載されたビットマップとDC完全攻略マップがあったはずだ。

 

まったく何も思い出せない。

おぼろげながらDC(デヴァイスコンテキスト)という言葉は覚えていて、ウインドウがあったり、DIB・DDBがなんとなくあったりしているうちにビューだよ、ビュー。

ビュービュー。とりあえずチャオチェン師匠の文章でもひっぱってみるか。

 

In virtually all applications involving a View, it is used for displaying purposes. You can draw the display images, or you can write the display images. They all rely on their respective functions. We will begin by looking at how drawing in a View is done.

 

一瞬respectiveって死んでもお前をリスペクトする

 

かと思ったら個別のという意味のようだ。覚えておこう。チャオチェン師が言うところでは、万物は必ずViewにつながるとのことだ。

 

Associated with a CView class is the CDC class, or Device Context, which CView manages. When you generate an SDI application, the device context is inherently constructed for us, which is why the OnDraw() function has an incoming parameter of “CDC* pDC” a pointer to the device context.

 

実際CView の継承関係を見てみよう。

ようするにウインドウクラス(CWnd)のことを言ってるんだナ。MSDNには

Within the Microsoft Foundation Class Library, further classes are derived from CWnd to provide specific window types. Many of these classes, including CFrameWnd, CMDIFrameWnd, CMDIChildWnd, CView, and CDialog, are designed for further derivation. The control classes derived from CWnd, such as CButton, can be used directly or can be used for further derivation of classes.

For more information on using CWnd, see Frame Window Topics and Window Object Topics in Visual C++ Programmer's Guide.

でーとーんで

Most drawing in a framework application occurs in the view, whose OnDraw member function is called whenever the window’s contents must be drawn. If your window is a child of the view, you might delegate some of the view’s drawing to your child window by having OnDraw call one of your window’s member functions.

In any case, you will need a device context for drawing. You can use the stock pen, brush, and other graphic objects contained in the device context associated with your window. Or you can modify these objects to get the drawing effects you need. With your device context set up as you like, call member functions of class CDC (device-context class) to draw lines, shapes, and text; to use colors; and to work with a coordinate system.

でとーんで

When a view becomes invalid, Windows sends it a WM_PAINT message. The view's OnPaint handler function responds to the message by creating a device-context object of class CPaintDC and calls your view's OnDraw member function. You do not normally have to write an overriding OnPaint handler function.

A device context is a Windows data structure that contains information about the drawing attributes of a device such as a display or a printer. All drawing calls are made through a device-context object. For drawing on the screen, OnDraw is passed a CPaintDC object. For drawing on a printer, it is passed a CDC object set up for the current printer.

 

フムフム つまりこうか

 

 

だんだん思い出してきたよ。PainterってのがGDIのことなんだろう。しくみは大分思い出してきたよ。

 

ちらつきとはどういうことかフリッカー、そうだ、フリッカーだ。ソウルフリッカー!

http://www.codeproject.com/gdi/flickerfree.asp?df=100&forumid=55&exp=0&select=822717

Flicker Free Drawing In MFCという記事があった。

ここにあるサンプルではフリッカーモードオンとオフが試せるので、効果が絶大なのがわかる。は、はやくそのほうほうをおしえてくれ。

読んでいくとカプセル化されているのでOnDrawで使ってるCDCCmemDCにすれば良いようだ。以下の手順を踏めばよい。

あっというまになおった。

ほんとにぴたりとなおった。

つまりこうしたわけだな

一体なんでちらつかなくなるのか?実際俺も思い出しながらデバコンメモリーを使うという方法は実践したがちらつきを抑えることはできなかった(嗚咽をもらす)。つーか、なんか書いてあったかもしれないが、めんどうくさいのではしょったのでよけいにちらつきがひどくなった。

ということはOnEraseBkgnd(pDC);CViewに返さないというのが大事なことのようだ。それではOnEraseBkgndはそこで何をやっているのか。

http://techtips.belution.com/ja/vc/0003/

 なるほど、定説だ。しかしいまいちそれぞれのタイミングが良くわからん。

からトレースしてみたぃ。が、MFCでトレースするのがめんどうくさいようなので以下を参照にする。

http://homepage3.nifty.com/ysflight/mfcconsole/mfcconsolej.html

発生の順番はこうだ

InvalidateRect(trueの場合)

OnEraseBkgnd

OnDraw

UpdateWindow

OnMouseMove

 

InvalidateRect(falseの場合)

OnDraw

UpdateWindow

OnMouseMove

 

OnEraseBkgndあんまり関係ねえじゃねえか。

やっぱりデバコン

 

チャウシェスクー(終わり)

 

 

 

this->CreateCompatibleDC(pDC);

pDC->LPtoDP(&m_rect);

this->m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());

this->m_oldBitmap = this->SelectObject(&m_bitmap);

this->SetMapMode(pDC->GetMapMode());

this->SetWindowExt(pDC->GetWindowExt());

this->SetViewportExt(pDC->GetViewportExt());

pDC->DPtoLP(&m_rect);

this->SetWindowOrg(m_rect.left, m_rect.top);

this->FillSolidRect(m_rect, pDC->GetBkColor());

てなかんじだよと。なぜか完全を誇っていたデバコン図にCreateCompatibleBitmapが入っていなかった。図の一番右に書き加えるべきだった。あとはそんなに疑問に残るようなことはやってないと思う。FillSolidRectの速度が速いからちらつきがなくなるのかね。