- ベストアンサー
TextOut( ) を BeginPaint( ) と GetDC( )
LRESULT CALLBACK の case WM_PAINT: で、 hdc = BeginPaint(hWnd, &ps); TextOut(hdc,0,0,str,strlen(str)); EndPaint(hWnd, &ps); ↑問題無し。↓文字がちらつく。 hdc = GetDC(hWnd); TextOut(hdc,0,0,str,strlen(str)); ReleaseDC(hWnd,hdc); ちらつきの原因は、高速で TextOut( ) が繰り返されるから だと思いました。 どうして TextOut( ) が繰り返されるんですか? 上の方法の場合は、 ReleaseDC(hWnd,hdc); は書かなくてもいいですか?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
基本的にWM_PAINTの場合はBeginPaintを使うほうがいい気がします。 というのはWM_PAINT時には再描画領域等の情報が設定されてきて BeginPaintを使うと必要のない領域には描画されないはずです。 GetDCを使用するとこの情報は取得できず、Window全体に対して描画されるので 再描画の必要のない領域まで描画することになってしまいます。 ちなみに繰り返しとありますが、実際に繰り返されてるのは確かめられたのでしょうか?
その他の回答 (3)
- bug_master
- ベストアンサー率52% (10/19)
M_PAINTは無効化された(再描画が必要な)領域が在ると 送られてきますが、キューから取り除くには マウスやタイマのメッセージのように単にメッセージを 処理すると取り除かれるのではなく、無効化された(再描画が必要な) 領域が無くなったときに除かれます。 BeginPaint、EndPaintは無効化された領域を処理しますが、 GetDCは無効化された領域とは関係なしに動作しますので、 依然として無効化された(再描画が必要な)領域が残ったままとなり WM_PAINTがキューに存在し続けるわけです。 ReleaseDCの後にValidateRectで無効化された領域を消してやれば GetDCの方も描画が繰り返されると言うことは無くなりますが、 これはお勧めしません。
お礼
hdc = GetDC(hWnd); TextOut(hdc,0,0,str,strlen(str)); ValidateRect(hWnd,NULL); ReleaseDC(hWnd,hdc); これでちらつく問題が解決しました。 窓が隠れていれば、常に UINT に WM_PAINT が入るんですね。 ありがとうございます。
- alfeim
- ベストアンサー率58% (114/195)
GetDC(),RelaseDC()のペアではメッセージキュー内のWM_PAINTメッセージが処理されず、無限にWM_PAINTが呼ばれつづけます。 そのためTextOutが呼ばれつづけちらつくのでしょう(ビデオカードのドライバによってはV-SYNCに同期して描画するためちらつかないものもあります)。 そのためWM_PAINTメッセージのハンドラではBeginPaint()、EndPaint()のペアを使う必要があります。尚、BeginPaint()、EndPaint(9を使う場合、ReleaseDC()する必要はありません。
お礼
ちらつきは、 switch (msg){ case WM_PAINT: の中の GetDC( ),RelaseDC( ) のペアによって UINT に WM_PAINT が入るせいで case WM_PAINT が無限に繰り返していたからだったんですね。 ReleaseDC( ) が必要ないということもありがとうございます。
- takebou
- ベストアンサー率43% (27/62)
何の関数の中のcase文なんでしょうか? ReleaseDC() は自分で GetDC() を記述したのでなければやってはいけません。
お礼
ありがとうございます。 上の例では ReleaseDC( ) を書いてはいけないんですね。
お礼
BeginPaint では、窓の右に半分重なっていた別の窓が 消えた場合、窓の全てを再描画するのではなく、 窓の右半分だけを描画するということですね。 知りませんでした。ありがとうございます。 繰り返し については、窓のちらつきを見た感じで 予想したことです。