WEB検索をしますと結構情報がヒットしますが、
解決に至ってませんので、よろしくお願いします。
Win32アプリケーションです。
WM_PAINTのタイミングでWindowに文字を描画してますが、
背景の塗りつぶしが原因でちらつきます。
WM_ERASEBKGNDメッセージをつぶせない仕様ですので、
よく用いられる方法で、ビットマップによるダブルバッファリングを行ったところ、
ちらつきが抑えられましたが、極端に遅くなってしまいました。
質問1
ビットマップに描画して画面に転送するという動作は
どうしたら早くできるでしょうか?
質問2
どんな方法でも結構ですので、画面のちらつきを抑える方法はないでしょうか?
どんなささいなことでもかまいませんので
お願いします。
不足している情報がありましたら、ご指摘ください。
補足させていただきます。
こちらの掲示版はなにか返答がなければ、もう本人は何もできませんので。
No.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でリージョンを削除して下さい。
より省メモリにする方法は色々と考える事ができますが、描画を見せない基本的な概念はこんな感じになると思います。
ウソがあるかもしれないので、自信なしです。
すいません、ありがとうございます。
書かれた内容と同じ処理をやっていたのですが、
なぜか極端に遅くなってしまっていたのです。
由一の違いはメモリDCに更新リージョンをセットしなかったことでした。
やってみたところ、かなりよくなりました。
またいろいろと問題が生じるかもしれませんが、
とりあえず様子見とします。
大変お世話になりました。
ありがとうございました。
No.5
- 回答日時:
WM_ERASEBKGND メッセージはつぶせませんが、ウィンドウの背景ブラシをなし (NULL) にすれば、WM_ERASEBKGND によるちらつきを抑えることができます。
また、テキストを書くときには ExtTextOut() などを使用して文字と背景色を一度に書いた方が良いと思います。
なお、背景色を無効化していますので、テキストがない領域については本来の背景色で塗りつぶす必要があることをお忘れなく。
ありがとうございます。
> なお、背景色を無効化していますので、テキストがない領域については本来の背景色で塗りつぶす必要があることをお忘れなく。
試したことがありますが、結局自分で塗りつぶすことになりますので、
ちらつきました。
またなにかありましたらお願いします。
結局正しくダブルバッファを使うしかないような
気もしてきました。。
No.4
- 回答日時:
#3です。
少々追加します。
ダブルバッファリングというのは、描画用と表示用の2枚のビットマップを交互に使用する事を指します。
WindowsのGDIでこういった事を必要とするケースは、WM_PAINTで表示用のビットマップを描画している最中に、別のスレッドが描画用のビットマップに描画する事がある場合です。それ以外ではビットマップは1枚で足りますので、ダブルバッファリングは不要です。
もし、バッファとなるビットマップを毎回作成しているのであれば、最初に1回だけ作成するようにすれば、多少は改善されるかもしれません。
度々ありがとうございます。
> もし、バッファとなるビットマップを毎回作成しているのであれば、最初に1回だけ作成するようにすれば、多少は改善されるかもしれません。
以前に試してましたが、変わりませんでした。
それと一回のみ作成だと毎回ビットマップをクリアする処理が必要になるので、それはそれで時間がかかりそうです。
また何かありましたらお願いします。
No.3
- 回答日時:
>WM_ERASEBKGNDメッセージをつぶせない仕様ですので、
これがある限り、どんな方法を使っても、ちらつきを抑える事は出来ません。
WM_ERASEBKGNDを受けとる必要があるのはわかりますが、何も描画しなければ受け取らなかったのと同じです。(文字を描画する部分だけ消さないという方法もありますが)
それすらも仕様だから出来ないという事なら、ちらつくのも仕様だとするしかないです。
>ちらつきが抑えられましたが、極端に遅くなってしまいました。
ちらつきが抑えられたように見えるのは、極端に遅くなったからではないでしょうか。
10倍くらい遅くなったのなら、やってはいけない事をやっているのだろうと思いますが、2倍くらい遅くなったのであれば、改善できない可能性はあります。
ありがとうございます。
> >WM_ERASEBKGNDメッセージをつぶせない仕様ですので、
> これがある限り、どんな方法を使っても、ちらつきを抑える事は出来ません。
確かにおっしゃるとおりです。
しかしファイルの内容をWindowに描画してますので、
スクロールなどによって文字が変わりますので、
一旦すべて消さないと全部重なって出て来てしまいます。
> 10倍くらい遅くなったのなら、やってはいけない事をやっているのだろうと思いますが、2倍くらい遅くなったのであれば、改善できない可能性はあります。
おかしいことをしているに違いないです。
ですが、どこがどうなのかが。。。
描画がロジックは全く同じで違いは描画先が
BeginPaintで取得してDCか
CreateCompatibleDCで作成したビットマップに関連付けられたDCかです。
同じロジックでも後者に対する描画は遅くなるということかもしれません。正しい知識があれば、判断ができますが、私では力不足です。知識を借りに来ました。
No.2
- 回答日時:
「ちらつく=なんども書かれている」で、
ダブルバッファリング(私はどんなものか知らない)が
ただ書き込み処理速度を遅くしただけなのでちらつきが減ったけど根本的な解決になっていない。
という安楽的な考えじゃ答えは出ませんね。
すみません、ギブです。
No.1
- 回答日時:
この回答への補足
ありがとうございます。
同じようなものですね。
ビットマップ作成
↓
ビットマップに描画
↓
ビットマップを画面にコピー
というだけの作業ですが、どこで遅くなったのが
よくわからないです。。。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- WordPress(ワードプレス) WordpressでYouTubeの埋め込みができない。 1 2022/10/26 01:08
- デザイン 小説雑誌に掲載するイラストの報酬について教えて下さい 4 2023/08/04 14:48
- カスタマイズ(車) (続き)初めてカーナビの取付にチャンレジします。アドバイスください。 3 2022/12/10 15:13
- Photoshop(フォトショップ) 【大至急】写真加工に強い方、お願いします。 現在、自作のブックカバーをプリンパさんに依頼しています。 6 2023/06/10 11:51
- その他(プログラミング・Web制作) 次に、楽天のアジャイル就活に参加して、1日で内定を獲得できる。私は大企業に就職できる? 2 2022/04/17 13:38
- Illustrator(イラストレーター) medibang paintで絵を描いて、A3やB3でコピーしたら線の画質が粗くなったのですが、解決 2 2023/04/04 06:48
- その他(プログラミング・Web制作) このWEB用語、WEB文章、意味が分かりますか? 理解できない人が多いようなんですが・・・ 7 2022/10/22 09:13
- 大学受験 担任が無理です 6 2022/10/18 23:21
- Excel(エクセル) エクセルのデータ整形について 3 2022/11/12 00:27
- その他(SNS・コミュニケーションサービス) 【至急】Microsoft teamsログインできないループ・・ 3 2023/05/17 13:17
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
FlexGridの一部のみ表示を更新...
-
[VB.net] DataGridViewの列ヘッ...
-
MFCでOnPaintのタイミング
-
Spreadで表全体を選択した場合...
-
pset関数について
-
C言語(dxlib)のDrawboxについ...
-
TextBoxに文字を書いても表示さ...
-
VC++プログラムをつかったBMP画...
-
VB.netでのライン描画方法がわ...
-
NVIDIAのシェーダーキャッシュ
-
楕円を描くプログラミング
-
VBAにGDI+を参照させる方法
-
ビットマップを表示させる(MFC)
-
UpdateData( FALSE); による文...
-
word
-
FPS処理について
-
C# ゲーム作成 FPSと描画...
-
InvalidateRectの使い方について
-
プシュボタンのテキストの色を...
-
StretchBlt関数について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
PCで「使用可能な場合はグラフ...
-
[VB.net] DataGridViewの列ヘッ...
-
UpdateData( FALSE); による文...
-
NVIDIAのシェーダーキャッシュ
-
VB6,リストボックスの特定行の...
-
TextBoxに文字を書いても表示さ...
-
word
-
MFCでOnPaintのタイミング
-
エクセルでガンチャートを作成...
-
MFCのタイマーのつかい方を教え...
-
InvalidateRectの使い方について
-
VC++プログラムをつかったBMP画...
-
CScrollViewの使用方法について
-
VB.netでのライン描画方法がわ...
-
CStaticコントロールの静的イメ...
-
Labelの文字をスクロールする際...
-
Form1 Load で実行されない。
-
VBAにGDI+を参照させる方法
-
C++にて、塗りつぶされた円を描...
-
GetGlyphOutline() ご利用経験...
おすすめ情報