0

まず、問題の症状を説明しましょう。次に、追加の事実を示し、質問を説明します。

症状

カスタム Windows コントロールを作成しました。コントロールは、WM_PAINTメッセージに応答して自分自身を描画します。また、追跡ツールチップ(つまりTOOLTIPS_CLASS、コモン コントロールの追跡機能)も使用します。

コントロールの上にマウスをドラッグすると、ツールチップがマウスにうまく追従します。問題は、その後に灰色の筋が残ることです。このストリークの再描画にはかなりの時間がかかります。添付の​​画像からわかるように、コントロールが再描画される前に PRNTSCRN を押してスクリーンショットを撮ることができました。

グレーに注意

(さらに奇妙なのは、WM_PAINTハンドラーが 1 回も実行されていないように見えることです。ただし、ツールチップを追跡させるコードが にWM_MOUSEMOVEあり、明らかに完全に応答していることに注意してください。)

事実

  • Win32 ライブラリを使用するバニラ C を想定してください。
  • WM_PAINTハンドラーは実際には非常に高速です。コントロールには、クライアント領域全体を再描画する必要がある多くの機能があり、これはユーザーにはわかりません。
    • 実際、一部の機能では、クライアント領域全体を 15 ~ 24 fps で再描画するアニメーションが実行されます。
    • また、かなり効率的で、特定の再描画で更新長方形よりも多くを再描画することはありません。
  • WM_ERASEBKGNDハンドラーは何もせず、単に 1 を返します 。
    • 背景を消すことはなく、ただ塗りつぶすだけです。
  • ウィンドウには、次のスタイル ビットが設定されています。
    • ws:WS_CHILD | WS_VISIBLE
    • 元:WS_EX_COMPOSITED
    • cs:CS_DBLCLKS
  • 親ウィンドウは、次のスタイル ビットが設定されたトップレベル ウィンドウです。
    • ws:WS_TILEDWINDOW | WS_CLIPSIBLINGS | WS_VISIBLE
    • 元:WS_EX_WINDOWEDGE
    • cs:CS_REDRAW | CS_DBLCLKS
  • コントロールのウィンドウ クラスの背景ブラシはGetStockObject(NULL_BRUSH).
  • 同じ種類の「トレイル」を引き起こすことがわかった他の唯一の方法は、別のトップレベル ウィンドウをコントロール上にドラッグすることです。ドラッグされた最上位ウィンドウによって一時的に隠されている領域には、同じ痕跡が残ります。
  • コントロールのウィンドウ クラスにCS_SAVEBITSスタイルを指定しても、違いはないようです。私はまだ遅い再描画の同じ知覚可能な痕跡を取得します.

質問

  1. 特に設定した場合、なぜ灰色になるのCS_SAVEBITSですか?
  2. 灰色をなくすにはどうすればよいですか?
    • UpdateWindow()ツールチップを移動するたび に呼び出す必要がありますか?
      • しかし、これは他のトップレベル ウィンドウが私のコントロールの上にドラッグされるという問題を解決しません。
    • ヘルプ!
4

1 に答える 1

1

WS_CLIPCHILDREN親ウィンドウにスタイルビットを追加すると、この問題はなくなりました。

なんらかの理由で、ウィンドウが部分的に隠され、その後表示されると、OS はメッセージに対して非常に寛大であり、WM_ERASEBKGNDメッセージに対して非常にけちWM_PAINTです。何が起こっていたかというと、親のWM_ERASEBKGNDハンドラーが私のコントロールを超えて消去していたということです。追加するWS_CLIPCHILDRENと、親ウィンドウはその消去をクリップします。

おかしなことに、このソリューションはメッセージを単に無視する私のコントロールでは機能しましたが、スタイル style を持つ標準コントロールでは機能WM_ERASEBKGNDしませんでした。これは、同じ寛大な政策によるものだと思います。標準のボタン コントロールはおそらく、そのメッセージを処理する際にバックグラウンドを忠実に消去し、無駄にメッセージを待ちます。BUTTONBS_GROUPBOXWM_ERASEBKGNDWM_PAINT

于 2013-06-11T23:14:44.110 に答える