• ベストアンサー

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); は書かなくてもいいですか?

質問者が選んだベストアンサー

  • ベストアンサー
  • akinori_s
  • ベストアンサー率60% (21/35)
回答No.2

基本的にWM_PAINTの場合はBeginPaintを使うほうがいい気がします。 というのはWM_PAINT時には再描画領域等の情報が設定されてきて BeginPaintを使うと必要のない領域には描画されないはずです。 GetDCを使用するとこの情報は取得できず、Window全体に対して描画されるので 再描画の必要のない領域まで描画することになってしまいます。 ちなみに繰り返しとありますが、実際に繰り返されてるのは確かめられたのでしょうか?

A__
質問者

お礼

BeginPaint では、窓の右に半分重なっていた別の窓が 消えた場合、窓の全てを再描画するのではなく、 窓の右半分だけを描画するということですね。 知りませんでした。ありがとうございます。 繰り返し については、窓のちらつきを見た感じで 予想したことです。

その他の回答 (3)

回答No.4

M_PAINTは無効化された(再描画が必要な)領域が在ると 送られてきますが、キューから取り除くには マウスやタイマのメッセージのように単にメッセージを 処理すると取り除かれるのではなく、無効化された(再描画が必要な) 領域が無くなったときに除かれます。 BeginPaint、EndPaintは無効化された領域を処理しますが、 GetDCは無効化された領域とは関係なしに動作しますので、 依然として無効化された(再描画が必要な)領域が残ったままとなり WM_PAINTがキューに存在し続けるわけです。 ReleaseDCの後にValidateRectで無効化された領域を消してやれば GetDCの方も描画が繰り返されると言うことは無くなりますが、 これはお勧めしません。

A__
質問者

お礼

hdc = GetDC(hWnd); TextOut(hdc,0,0,str,strlen(str)); ValidateRect(hWnd,NULL); ReleaseDC(hWnd,hdc); これでちらつく問題が解決しました。 窓が隠れていれば、常に UINT に WM_PAINT が入るんですね。 ありがとうございます。

  • alfeim
  • ベストアンサー率58% (114/195)
回答No.3

GetDC(),RelaseDC()のペアではメッセージキュー内のWM_PAINTメッセージが処理されず、無限にWM_PAINTが呼ばれつづけます。 そのためTextOutが呼ばれつづけちらつくのでしょう(ビデオカードのドライバによってはV-SYNCに同期して描画するためちらつかないものもあります)。 そのためWM_PAINTメッセージのハンドラではBeginPaint()、EndPaint()のペアを使う必要があります。尚、BeginPaint()、EndPaint(9を使う場合、ReleaseDC()する必要はありません。

A__
質問者

お礼

ちらつきは、  switch (msg){  case WM_PAINT: の中の GetDC( ),RelaseDC( ) のペアによって UINT に WM_PAINT が入るせいで case WM_PAINT が無限に繰り返していたからだったんですね。 ReleaseDC( ) が必要ないということもありがとうございます。

  • takebou
  • ベストアンサー率43% (27/62)
回答No.1

何の関数の中のcase文なんでしょうか? ReleaseDC() は自分で GetDC() を記述したのでなければやってはいけません。

A__
質問者

お礼

ありがとうございます。 上の例では ReleaseDC( ) を書いてはいけないんですね。