アプリ版:「スタンプのみでお礼する」機能のリリースについて

WEB検索をしますと結構情報がヒットしますが、
解決に至ってませんので、よろしくお願いします。

Win32アプリケーションです。
WM_PAINTのタイミングでWindowに文字を描画してますが、
背景の塗りつぶしが原因でちらつきます。
WM_ERASEBKGNDメッセージをつぶせない仕様ですので、
よく用いられる方法で、ビットマップによるダブルバッファリングを行ったところ、
ちらつきが抑えられましたが、極端に遅くなってしまいました。

質問1
ビットマップに描画して画面に転送するという動作は
どうしたら早くできるでしょうか?

質問2
どんな方法でも結構ですので、画面のちらつきを抑える方法はないでしょうか?

どんなささいなことでもかまいませんので
お願いします。

不足している情報がありましたら、ご指摘ください。
補足させていただきます。
こちらの掲示版はなにか返答がなければ、もう本人は何もできませんので。

A 回答 (6件)

>スクロールなどによって文字が変わりますので、


>一旦すべて消さないと全部重なって出て来てしまいます。

バッファが不要という意味ではありません。
もの凄く極端ではありますが、例を示します。

CreateCompatibleDCでメモリDCを作成、CreateCompatibleBitmap でデスクトップと同じ大きさのビットマップを作成しメモリDCにSelectObjectしておきます。
このビットマップがバッファとなり、全ての描画は一度ここに行う事とします。

WM_ERASEBKGNDでは何もしないで下さい。

WM_PAINTは、BeginPaintを行う前に、
CreateRectRgn(0, 0, 0, 0); と空のリージョンを作り、GetUpdateRgnで更新領域を取得します。その後にBeginPaintします。

取得した更新領域を、メモリDCにSelectObjectして下さい。

WM_ERASEBKGNDで行っていた処理を先に行い、その後に文字等を普通に描画します。リージョンがSelectされているので、更新された領域以外には描画されません。この事は通常の描画と同じです。

メモリDCをクライアントにBitBltすれば描画は全て終わりです。ウィンドウの更新領域以外は転送されませんので、更新領域が小さい時は短時間で終了します。

最後にSelectObjectでメモリDCのリージョンを戻し、DeleteObjectでリージョンを削除して下さい。

より省メモリにする方法は色々と考える事ができますが、描画を見せない基本的な概念はこんな感じになると思います。

ウソがあるかもしれないので、自信なしです。
    • good
    • 0
この回答へのお礼

すいません、ありがとうございます。

書かれた内容と同じ処理をやっていたのですが、
なぜか極端に遅くなってしまっていたのです。
由一の違いはメモリDCに更新リージョンをセットしなかったことでした。
やってみたところ、かなりよくなりました。
またいろいろと問題が生じるかもしれませんが、
とりあえず様子見とします。

大変お世話になりました。
ありがとうございました。

お礼日時:2005/11/16 00:19

WM_ERASEBKGND メッセージはつぶせませんが、ウィンドウの背景ブラシをなし (NULL) にすれば、WM_ERASEBKGND によるちらつきを抑えることができます。


また、テキストを書くときには ExtTextOut() などを使用して文字と背景色を一度に書いた方が良いと思います。
なお、背景色を無効化していますので、テキストがない領域については本来の背景色で塗りつぶす必要があることをお忘れなく。
    • good
    • 0
この回答へのお礼

ありがとうございます。

> なお、背景色を無効化していますので、テキストがない領域については本来の背景色で塗りつぶす必要があることをお忘れなく。

試したことがありますが、結局自分で塗りつぶすことになりますので、
ちらつきました。
またなにかありましたらお願いします。

結局正しくダブルバッファを使うしかないような
気もしてきました。。

お礼日時:2005/11/15 23:30

#3です。


少々追加します。

ダブルバッファリングというのは、描画用と表示用の2枚のビットマップを交互に使用する事を指します。
WindowsのGDIでこういった事を必要とするケースは、WM_PAINTで表示用のビットマップを描画している最中に、別のスレッドが描画用のビットマップに描画する事がある場合です。それ以外ではビットマップは1枚で足りますので、ダブルバッファリングは不要です。

もし、バッファとなるビットマップを毎回作成しているのであれば、最初に1回だけ作成するようにすれば、多少は改善されるかもしれません。
    • good
    • 0
この回答へのお礼

度々ありがとうございます。

> もし、バッファとなるビットマップを毎回作成しているのであれば、最初に1回だけ作成するようにすれば、多少は改善されるかもしれません。

以前に試してましたが、変わりませんでした。
それと一回のみ作成だと毎回ビットマップをクリアする処理が必要になるので、それはそれで時間がかかりそうです。
また何かありましたらお願いします。

お礼日時:2005/11/15 23:24

>WM_ERASEBKGNDメッセージをつぶせない仕様ですので、



これがある限り、どんな方法を使っても、ちらつきを抑える事は出来ません。
WM_ERASEBKGNDを受けとる必要があるのはわかりますが、何も描画しなければ受け取らなかったのと同じです。(文字を描画する部分だけ消さないという方法もありますが)
それすらも仕様だから出来ないという事なら、ちらつくのも仕様だとするしかないです。

>ちらつきが抑えられましたが、極端に遅くなってしまいました。

ちらつきが抑えられたように見えるのは、極端に遅くなったからではないでしょうか。

10倍くらい遅くなったのなら、やってはいけない事をやっているのだろうと思いますが、2倍くらい遅くなったのであれば、改善できない可能性はあります。
    • good
    • 0
この回答へのお礼

ありがとうございます。

> >WM_ERASEBKGNDメッセージをつぶせない仕様ですので、

> これがある限り、どんな方法を使っても、ちらつきを抑える事は出来ません。

確かにおっしゃるとおりです。

しかしファイルの内容をWindowに描画してますので、
スクロールなどによって文字が変わりますので、
一旦すべて消さないと全部重なって出て来てしまいます。

> 10倍くらい遅くなったのなら、やってはいけない事をやっているのだろうと思いますが、2倍くらい遅くなったのであれば、改善できない可能性はあります。

おかしいことをしているに違いないです。
ですが、どこがどうなのかが。。。

描画がロジックは全く同じで違いは描画先が
BeginPaintで取得してDCか
CreateCompatibleDCで作成したビットマップに関連付けられたDCかです。
同じロジックでも後者に対する描画は遅くなるということかもしれません。正しい知識があれば、判断ができますが、私では力不足です。知識を借りに来ました。

お礼日時:2005/11/15 22:38

「ちらつく=なんども書かれている」で、


ダブルバッファリング(私はどんなものか知らない)が
ただ書き込み処理速度を遅くしただけなのでちらつきが減ったけど根本的な解決になっていない。
という安楽的な考えじゃ答えは出ませんね。
すみません、ギブです。
    • good
    • 0

こういったものが私は苦手なんですが、


これと似たようなものですかね?

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=1780918

この回答への補足

ありがとうございます。

同じようなものですね。

ビットマップ作成

ビットマップに描画

ビットマップを画面にコピー

というだけの作業ですが、どこで遅くなったのが
よくわからないです。。。

補足日時:2005/11/15 20:17
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!