画面リサイズ時のちらつきをなくす方法

このQ&Aのポイント
  • 画面リサイズ時に起こるちらつきを解消するための方法を探しています。
  • 現在、DIB描画部の下に表示しているタイトル文字列がリサイズ時に重なってしまう問題があります。
  • 背景の塗りつぶしを行うためにOnEraseBkgnd()をオーバーライドしていますが、新たに書き込んだ部分と重なってしまいます。
回答を見る
  • ベストアンサー

画面リサイズ時のちらつきをなくす方法

MFCです。 ワーカースレッドで取得したDIBを定期的に描画するプログラムを作っています。 DIB描画部の下にはタイトル的な文字列をTextOutしています。 リサイズ時にはDIBのサイズとタイトル文字列表示領域のサイズも変化させる必要があります。 現在、画面をリサイズするとちらつくという問題の対応に悩んでいます。 コンパチDCなどを使ってダブルバッファリングを行うというのはわかっているのですが、 そもそもリサイズ時にちらつくということは、背景が白(デフォルトのブラシ)で塗りつぶされてしまうのが原因だと思っているので、 OnEraseBkgnd()をオーバーライドして、return TRUE するようにしました。 ちらつかなくなったのですが、OnEraseBkgnd()でほかに何もしていないので、リサイズ前のDIBとタイトル文字列が残ってしまって、新たに書き込んだものと重なってしまいます。 OnEraseBkgnd()で背景をいったん塗りつぶせばいいのではないかと思っているのですが、私の考えは正しいでしょうか?

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

  • ベストアンサー
回答No.2

つまり WS_EX_COMPOSITED が使えない理由がある、ということでしょうか? そういう前提だとすると ・MFCのラッピングを使用し自分ではコーディングしない ・ソースコードが会社にあるので詳しく書くのは難しい となると、ちょっとお手上げです。 描画処理についても、ダブルバッファリングなので概要はそういう風になると思うのですが、正確なコード(と、もっと言うと会社側の提示してい る制限、目的とする環境など)が分からないと、なんとも言えません。 それでも推考してみると OnEraseBkgnd()でreturn TRUEとかInvalidateRect(FALSE)とか試していらっしゃるようなので (他にはウインドウクラス登録時にバックグラウンドをNULLにしたり、ウインドウクラスのスタイルからCS_HREDRAWやCS_VREDRAWを外してやるとかも色々考えられますが) >新たに書き込んだものと重なってしまいます という記述を見る限りそこはちゃんと対処出来てると思うのですが ダブルバッファが「本当にうまくいって」いますか? 概ね大丈夫ではないかと思うのですが、Vistaではどうなのか、というとVistaの抱える問題のごく一部しか私は把握していませんので、厳密に言うと完全には分かりません、が 普通に考えると「実際に『描画する側』のバッファ(表示されない裏画面)そのものに対して『背景を 塗りつぶしたうえに文字を書いて』やり」それを実際に見える方へコピーする、という方式にすれば 妥当に考えてOKと思います。 現状そういう風になっていますか?

real_neo
質問者

お礼

先に背景を塗りつぶしてその上に書きたいものを書くようにしたら、実現できました! ありがとうございました。

その他の回答 (1)

回答No.1

いざという時の拡張ウインドウスタイル WS_EX_COMPOSITED ではダメですか? ただいざというとき、なので 状況によっては使ってはダメな場合があるので ちょうど興味がありますから、それの使用が無理でしたら よろしければOSと サイズ変更時(WM_SIZE)の処理、描画処理、ウインドウ生成、ウインドウクラス登録のあたりのコードを教えてください。

real_neo
質問者

補足

早速の回答、ありがとうございます。 >よろしければOSと >サイズ変更時(WM_SIZE)の処理、描画処理、ウインドウ生成、ウインドウクラス登録のあたりのコードを教えてください。 OSはVistaです。 MFCのDocument-Viewの仕組みを使っていまして、ウィンドウ生成、ウィンドウクラス登録はMFCでラッピングされています(自分ではコーディングしない)が、 ソースコードが会社にありますので、詳しく書くのは難しいです^^; 文章にしますと、 ・WM_SIZE(OnSize)の処理 InvalidateRect(FALSE)でクライアント領域の無効化とステータスバーの内容更新だけです。 ・描画処理 1.DIBをいったんメモリDCへ書き込んだ後、実際の画面用のDCに書き込む。 2.タイトルも1.と同様にいったんメモリDCへ書き込んだ後、実際の画面用のDCに書き込む。 と、こんな感じです。 よく考えると、自分で背景を塗りつぶしてしまったら、システムが塗りつぶす色が違うだけで、塗りつぶし→描画の繰り返しで、結局ちらついてしまうような気がします。

関連するQ&A

  • MFC ビットマップ描画で残像が残る

    MFCです。 ワーカースレッドで取得したDIBを定期的に描画するプログラムを作っています。 ダブルバッファリングで実現しているのですが、画面リサイズを繰り返すと、再描画の後に、拡大して発生した新しいクライアント領域に古い画像が残ってしまいます。 SelectObject()で選択したコンパチDCのビットマップを選択前のものに戻してなかったのですが、これが原因なんでしょうか?

  • 画像のリサイズ

    ブログを始めたので、タイトルの背景に写真を貼り付けようとしています。貼り付けたい画像サイズは「縦205×横770」です。  ただ、手持ちのデジカメには、このサイズを指定して撮影する機能がありません。すでに撮影した写真でもいいのでリサイズしたいのですが、かなり特殊な横長サイズなのでリサイズの方法が分からず困っています。  また、すでに撮影した画像を編集でリサイズしてみたのですが、横に潰れたようになり、うまくいきません。 「205×770」サイズの写真を手に入れる方法や画像サイズをこのサイズにリサイズできる無料ソフトがあれば、教えてください。 芸能人などのブログを見ていると、キレイに写真が貼り付けられているのですがどうやっているのでしょう? http://ameblo.jp/emiri/

  • 大きいサイズの画面の更新とキーカラー付の画像表示

    SXGAとかUXGAぐらいの大きいサイズの画面で、背景の前をキャラクターが動き回るプログラムを作ろうとしています。キャラクターはキーカラーをつけてスプライトのように、 1背景をバックバッファに転送 2キャラクターをキーカラーを抜きつつ転送 3バックバッファを描画 という風に処理しています。 この場合、バックバッファを描画するときが結局大きい画像を転送することになるので処理が遅くなってしまいます。 質問したいことは、このやり方が正しいかということで、ゲームとかで大きいサイズの画面を扱う一般的な方法をご存知でしたらアドバイスをお願いします。 あと追加で、DirectGraphicsを使っているのですが、IDirect3DTexture9とかだと読み込める画像のサイズが正方形で2の累乗になってしまうと思うのですが、320x240とかの変形のサイズの画像をキーカラー付で描画できる方法をご存知でしたら教えていただけるとありがたいです。

  • VC++2010 リサイズの謎・・

    VC++2010 リサイズについてなんですが、 あるエディットボックスに文字列を表示させていたんですが、 ↓↓↓↓↓↓↓↓↓↓ r,r49 r,s,58 r,s,100 ウィンドウ全体のサイズを少しでも変えると(リサイズすると) ↓↓↓↓↓↓↓↓↓↓ r,r,49 r,s,58 r,s,100 で表示されてしまい、今まで表示されて改行されていたのが横ぞろいになって困っています。 どうすればリサイズしても前のまま(改行されるやつ)にできますか? よろしくお願いします。

  • パネルに描画した文字列のスクロール方法

    下記は単純にスレッドを使い右から左へ文字列をスクロールさせたロジックです。スレッド開始後2秒後にスクロールが0.5秒単位に行われ、文字列が全てスクロールされたら先頭に戻り同じ事を繰り返します。 |----------------------------------------| |Stringが←へ移動               |-----------------------------------------| /********************************************** public void run(){ FontMetrics fontM = this.getFontMetrics(Font); int Len = fontM.stringWidth(Title) + 10; int movePoint = 0; try { threadScroll.sleep(2000); while (threadScroll != null) { threadScroll.sleep(500); moveTitleX -= 1; if (movePoint > Len) { moveTitleX = posiTitleX; movePoint = 0; repaint(); threadScroll.sleep(threadSleep); } else { movePoint = movePoint + 1; repaint(); } } } catch (InterruptedException ie) {} } /************************************************ 上記の場合、文字列を描画する位置をただ-1しているだけなのですが、移動する範囲を指定したいのです。 パネルの長さが100として、10の位置から90の位置までを 描画した文字列がスクロールするという事を行いたいのですがわかりません。もちろん文字列の先頭が10の位置までいったら先頭から消えていくようにしたいのです。全部消えたらまた最初からというぐあいに。 |------------------------------------| |  10                      90  | |------------------------------------| 教えてください。お願いします。

    • ベストアンサー
    • Java
  • Java 15パズルを作ったのですが・・・

    こんにちは。 趣味でプログラミングをしているものです。 さっそくですが質問させていただきます。 Javaで15パズルを、eclipseをしろうとなりに使って 作ってみたのですが、 以下のURLにソースコードの全文を 載せてありますので、 (判定、完成させたときの何らかのイベントは  まだできたいない途中のものですが・・・) http://www.eonet.ne.jp/~mycabinet よろしければ、500*500のピース用、背景用の jpg画像を用意していただき、 imageという名前のフォルダに格納して 実行して動作を試していただきたいのですが・・・ その上で、いくつか質問させていただきたいのです。 (1) JPanelを継承したクラスにswing のTimerクラスを 持たせ、ピースの移動をアニメーションのように 描画させようとしたのですが、 動くことは動くのですが、 簡単に言えばダブルバッファリングが必要なように 描画されてしまいます。 (2) BlankPieceクラスの描画は スーパークラスの抽象メソッドを オーバーライドして何もしないように すれば、背景の画像が描画される、 と思ったのですが、 グレーの通常のパネルのようなものが 描画されてしまいます。 以上の点をどのように修正すれば よいのでしょうか? また、修正できたとして、 それをアプレットにするには、 どのようにすればよいのでしょうか? ご存知の方よろしければ、教えていただけないでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • 画面の更新とスレッド

    ボタンを押すと、テキストボックスに10msごとに文字列を追加する関数実行するプログラムを作成したのですが、実行している間プログラムの画面の操作を受け付けなくなってしまいます。 そこで、 http://msdn.microsoft.com/ja-jp/library/ms171728(VS.80).aspx を参考にして、メインスレッド以外のスレッドからテキストボックスに書き込むようにしました。 しかし、このようにしても、 Application::DoEvents(); を、forの中で実行して強制的に画面を再描画させないと、インターフェイスへの操作を一切受け付けなくなってしまいます。 Windowsフォームの描画は、いったいどの様なタイミングで行われているのでしょうか? また、このようなインターフェイスの操作を受け付けなくなることを回避するには、 Application::DoEvents(); 以外には良い方法は無いのでしょうか?

  • PHPのGD系の関数で描画した文字列の下に下線を引きたい

    PHPのGD系の関数で描画した文字列の下に下線を引きたい PHPのGD系の文字列関数がありますよね? (例:日本語が扱えるやつだとImageTTFTextとか) これで文字列の長さに揃えてリンクっぽく見せるために 下線を引きたいのですが、良い手法が思いつきません。 文字数をstrlenでカウントしてフォントのサイズ/2を掛けたら 文字列の長さになるかなーと思って試しましたが、 これだとaとあの文字の横幅が違うようにずれが出ます。 あるフォントである文字列描画関数を使ったときに文字列の横幅が 調べられるような手法があれば、その長さに応じた下線が引けるのですが、 そうした手法はないでしょうか?

    • ベストアンサー
    • PHP
  • Visual Web Developerで描画

    こんばんは Visual Web Developerを初めて間もない者です。 Imageに文字列を描画したいと思っています。 例えば Textboxに入力した文字列をButtonイベントで取得して Imageで表示している画像上に描画 のような感じです。 その他の制約としましては、 ・画像サイズに合わせて文字列が折り返して描画されること どなたかご教授お願いいたします。 開発環境 ・Window XP Home Edition ・VWD 2010 Express(ASP.NET Webサイト C#)

  • 複数行の文字列描画

    BorlandC++Builder6を使用しています。 Memoに入力した文字列をPaintBoxに描画したいと考えています。 Editに入力したものをtextoutでPaintBox上の指定した位置に出力することはできました。 次は,Memoを利用して同じことを行いたいと考えています。 しかし,複数行の出力ができません。 複数行をCanvas上に一回で出力することはできないのでしょうか? Memo以外を利用したらできるのでしょうか? 全く分からないので誰か教えて下さい。

専門家に質問してみよう