5

共通のコントロールをダブルバッファリングする方法はありますか?現在、サイズを変更するとちらつきます。多くの.....

編集:それが役立つ場合、それは一連のボタンコントロールといくつかの編集コントロールであり、すべてタブコントロールの上にあります。タブコントロールはそれ自体を再描画し、次にボタンはそれ自体を再描画します。ボタンを再描画すると、点滅します。

EDIT2:これが私が抱えている問題の例です:http: //billy-oneal.com/Lobfuscator.exe

4

8 に答える 8

4

トピックがかなり古いことは理解していますが、これはちらつきの問題で困っている人に関係があるかもしれません.

ビリーと同じように、タブを切り替えるときにポップアップする問題に遭遇しました。タブに配置されたコントロールが表示されたり非表示になったりするときにちらつきます。参考までに、ShowWindow関数を広範囲に使用して、コントロールを非表示および表示しています。

私は WS_EX_COMPOSITED を数時間いじっていましたが、非常に奇妙な結果が得られました。ダイアログはフルスクリーンで実行するように設計されており、現在のデスクトップ解像度に適応します。

これは、手動で作成したダイアログのレイアウトで、すべてのコントロールに対して CreateWindowEx 関数を呼び出します。

メイン ウィンドウ -- いくつかのコントロール -- タブ コントロール ---- その他のコントロール

インデントは親子関係を表します。タブ コントロールには、作成時に設定された WS_CHILD および WS_CLIPCHILDREN スタイルがあり、すべてのコントロールに WS_CHILD スタイル セットがあります。

最終的にトリックは次のようになりました

MainProc proc hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
    mov eax,uMsg
    cmp eax,WM_INITDIALOG
    je @WM_INITDIALOG
    ...

    invoke DefWindowProc,hWnd,uMsg,wParam,lParam
    ret

@WM_INITDIALOG:
    ...

    invoke GetWindowLong,hWnd,GWL_EXSTYLE
    or eax,WS_EX_COMPOSITED
    invoke SetWindowLong,hWnd,GWL_EXSTYLE,eax
    ...

MainProc endp

このビットはアセンブリ (MASM32) で記述されていますが、要点は理解できると思います。単純に、WM_INITDIALOG 中にメイン ウィンドウの EX_STYLE を取得し、それに WS_EX_COMPOSITED を追加します。

この特殊なケースでは、この方法は 32 ビット Windows XP SP3 と 64 ビット Windows 7 SP1 の両方で機能します。タブの子コントロールに WS_EX_COMPOSITED スタイルを追加する必要はありませんでした (私が使用する静的コントロールの一部には WS_EX_TRANSPARENT が設定されていますが、それは他の理由によるものです)。メッセージ。また、適度に強力な C2D マシンでパフォーマンスの問題も発生していません。

参考までに、これは私のメインです

Main proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
    LOCAL wc:WNDCLASSEX,msg:MSG

    mov wc.cbSize,sizeof WNDCLASSEX
    mov wc.style,CS_HREDRAW or CS_VREDRAW
    mov wc.lpfnWndProc,offset MainProc
    mov wc.cbClsExtra,NULL
    mov wc.cbWndExtra,DLGWINDOWEXTRA
    push hInst
    pop wc.hInstance
    mov wc.hbrBackground,COLOR_BTNFACE+1
    mov wc.lpszClassName,offset szClassName
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov wc.hIcon,eax
    mov wc.hIconSm,eax
    invoke LoadCursor,NULL,IDC_ARROW
    mov wc.hCursor,eax
    invoke RegisterClassEx,addr wc
    invoke CreateDialogParam,hInstance,IDD_MAIN,NULL,addr MainProc,NULL
    invoke ShowWindow,hWin,SW_SHOWNORMAL
    invoke UpdateWindow,hWin
    invoke LoadAccelerators,hInstance,IDD_ACC_TABLE
    mov hAcc,eax
    jmp @2
@1:
    invoke TranslateAccelerator,hWin,hAcc,addr msg
    test eax,eax
    jne @2
    invoke TranslateMessage,addr msg
    invoke DispatchMessage,addr msg
@2:
    invoke GetMessage,addr msg,NULL,0,0
    test eax,eax
    jne @1

    mov eax,msg.wParam
    ret

Main endp

ここでも特別なことは何もありません。「ダイアログ コントロール グレー」を背景色として設定し、CS_*REDRAW スタイルを使用していますが、これらはこの状況に影響を与えていないようです。メインウィンドウを作成するために使用した「空の」ダイアログテンプレートはこれです

IDD_MAIN DIALOGEX 0,0,318,177
FONT 8,"MS Sans Serif",0,0,0
CLASS "DLGCLASS"
STYLE 0x90800000
EXSTYLE 0x00000008
BEGIN
END

うまくいけば、これは答えを探している人々の時間を節約するかもしれません. 少し長くなりましたが、できるだけ詳しく説明したいと思います。

よろしく。

于 2012-12-13T16:41:26.103 に答える
4

使い方WS_EX_COMPOSITEDWS_EX_TRANSPARENTスタイルを見てください。それらはダブルバッファリングを提供しますが、WM_PAINT は子コントロールを下から上に描画するため、基になるビットマップの描画が完了すると呼び出されます。そのため、ウィンドウ プロシージャでのみペイントできます。私は過去にそれを使用しており、かなりうまく機能しています。

最上位ウィンドウ (コンテナー) を拡張スタイル WS_EX_COMPOSITED に設定し、子ウィンドウを WS_EX_TRANSPARENT に設定します。また、次のように定義することを忘れないでください。

#define WINVER 0x501 

合成されたスタイルについては、CreateWindowExを参照してください。これにより、子ウィンドウでピクセルごとの透過性を実現することもできます。

アップデート

WM_PRINTCLIENT を使用してクライアント領域を DC 上のビットマップに転送し、すべてのクライアント領域をまとめてブリットするのはどうですか?

http://blogs.msdn.com/larryosterman/archive/2008/08/27/larry-s-new-favorite-windows-message-wm-printclient.aspx

于 2009-12-08T15:19:34.253 に答える
2

Larry Osterman は最近、このテーマについてブログを書いています。興味深い詳細が見つかるかもしれません。

于 2009-12-08T02:38:29.223 に答える
0

WTL::CDoubleBufferImplそのためにミックスインを使用します。GDI+を使って絵を描くこともできます。ちらつきゼロ。

使用法は非常に簡単です。パブリックから継承しWTL::CDoubleBufferImpl<YourClass>、ATLメッセージマップにチェーンします。

于 2009-12-11T13:21:38.197 に答える
0

何をしているのか正確にはわかりませんが、これには MFC または Win32 C のいずれかを使用していると思います。

おそらく、WM_SIZE メッセージでサイズ変更を行いたいでしょう。コントロールのサイズをどこで変更しているのかはわかりませんが、サイズ変更中にそれを行っていると思います。そのため、ちらつきが発生しています。

また、私は考えていますが、わかりません。おそらく SetWindowPos 関数を使用でき、uFlags には SWP_NOREDRAW があります。これが一般的なコントロールでどれほどうまく機能するかはわかりませんが。

于 2009-12-03T20:16:02.043 に答える
0

確かに、

少し前に、誰かが私の投稿の 1 つにこれに対する回答を投稿しました。それをチェックしてください: ここ

そして、彼の素晴らしさに賛成票を投じてください。

コードは C# です。簡単な翻訳があることを願っています。

于 2009-12-03T19:42:24.190 に答える
0

WS_EX_TRANSPARENT を使用していませんか? これにより、下にあるウィンドウがコントロールの前に描画され、下部のウィンドウが消去されるとちらつきが発生します。

于 2009-12-08T02:55:44.150 に答える
0

最初にメモリ デバイス コンテキスト MemDC を作成できます。すべてを MemDC に描画し、ウィンドウが WM_PAINT メッセージを受け取るか無効化されたら、ビット ブリッティングによって MemDC を実際の DC にコピーします。

数年前に Herbert Schildt の著書 (Windows 98 Programming from the Ground Up) でテクニックを読んだことを覚えています。このように、メモリ DC を実際の DC にブリットすると、すべての再描画が高速になります。しかし、1 つの大きな落とし穴は、使用するメモリ DC の大きさです。しかし、彼はそれを行う方法を示しました。Osborne McGraw Hill によって発行されたその本のすべての章のコード ダウンロードがあります。

これがお役に立てば幸いです。よろしくお願いします、トム。

于 2009-12-07T01:49:36.013 に答える