2017-06-22 10 views
1

私はカスタム図面を行う2つのコントロールを持つwinformsアプリケーションを持っています。メインコントロールは道路の長い連続画像の小さな部分を示し、もう1つのコントロールは道路画像全体の水平に押しつぶされた表示を示します。 2番目のコントロールは最初のコントロールをナビゲートするために使用されます。概要のどこかをクリックすると、メインビューのその場所にスクロールできます。ここでの主なビューは、上部および概要にあるスクリーンショットは、底部にあります:両方のコントロールを無効にすると、1つのコントロールが別のコントロールよりも頻繁に再描画されるのはなぜですか?

screenshot of both controls

メインビューに示されている画像の位置を示す概要コントロールシアン線があります。 (このスクリーンショットでは、幅が左から1/3をわずかに超えています。)ユーザーは概要内のその行をクリックしてドラッグすると、メインビューがスクロールします。

私は、再描画について奇妙なことに気付きました。概要コントロールでシアンの線をドラッグすると、マウスの動きに応答して両方が無効になっていても、メインビューは概観よりずっと頻繁に再描画されます。キューに他のメッセージがないときにのみWM_PAINTメッセージが送信されることはわかっていますが、同時に両方が無効になっていると、あるコントロールが他のコントロールよりも頻繁に再描画される理由がわかりません。

実際、私はその最後の文章を入力していたので、私は理由を見つけたと思う。

各コントロールには独自のメッセージキューがあり、メインコントロールに入力関連のメッセージは受信されないため、メッセージキューはオーバービューよりも頻繁に空になります。すべてのマウスイベントを処理します。したがって、概要よりも頻繁にWM_PAINTメッセージを受信します。

この時点で、私は疑問を抱いています。「それは意味をなさないでしょうか?起こっていますか?」

+0

概観の「道路画像全体の水平潰れ表現」はどのように達成されていますか?ペイント()イベントで計算を行っているのですか、またはデータを繰り返してカスタムのラインをペイントするカスタムですか?私はそれがメインビューよりも概観を描くのに単に時間がかかることを推測している。 –

+0

@Idle_Mind、実際には、私は最近概要コントロールの描画を最適化して、最後のフルレンダーのビットマップを保持し、スクロール時にシアンラインを描画するだけのブリットを保持します。シーンが実際に変更されたときにのみビットマップが更新されます。これはまれであり、スクロール中にはまったく起こりません。しかし、メインビューよりオーバービューをレンダリングするのに時間がかかっても、同じ周波数で起こっていると、その効果は一般的な低迷になります。これは私が見ているものではありません。メインコントロールは、マウスイベントに追いついていますが、概要は表示されません。 – adv12

答えて

3

理論は健全ではなく、スレッドごとに1つのメッセージキューしかありません。 WM_PAINTがどのように生成されるかは、ほぼ確実です。これは、キューがで空の場合にのみ配信されます。。それはそれを「優先度の低い」メッセージにして、ユーザーの入力が常に最初になります。重要な点は、ペイントコードが遅いため、ユーザー入力が失われたり、メッセージキューが爆発したりするのを避けることです。

大体、Invalidate()を2回呼び出しました。一番下のウィンドウはペイントイベントを取得しますが、処理が完了するまでには処理待ちの別のマウスイベントがあります。したがって、第2のウィンドウはではなく、のペイントイベントを取得し、既に無効化されているウィンドウを無効にします。あなたがマウスを減速させたり、移動を止めるときにだけ、追いつくことができます。

タスクマネージャから見やすく、プログラムのUIスレッドが100%コアを記録していることがわかります。

とにかくペイントを強制することはできますが、Invalidate()ではなくUpdate()を呼び出す必要があります。あなたのプログラムはまだ100%コアを焼いていますが、ペイントをスキップする代わりにマウスに反応しにくくなります。それはメッセージキューを溢れさせる可能性があるので、危険に思えますが、そうではありません。 WM_MOUSEMOVEはメッセージキューに追加されません。 WM_PAINTと同様に、キューが空のときにのみ生成されます。あなたはまずそれを得るでしょう。

+0

私はこの説明を大部分は理解していると思いますが、メッセージキューが空のときは常にWM_PAINTを取得し、イベントが入ってくるのでそれを取得しないのは下位のものです。なぜそれは他の方法で決してですか?ドローイングだけ運がいい?コントロール階層内の相対的な順序について何か? – adv12

+0

"トップコントロール"ではなく、Windowsは "ペインターのアルゴリズム"とペイントを前後に使用します。ここで、「戻る」はZオーダーの最も低いものである。コントロールが互いに重なっていない場合、Zオーダーは常に明白ではなく、表示>他のウィンドウ>ドキュメントアウトラインツールウィンドウから表示されます。 「Bring to Front」および「Send to Back」デザイナーコマンドで変更されます。 –

+0

ええ、私は「スクリーンショットのトップコントロール」を意味していました。私はちょうど私のメインビューは常に成功裏に再描画し、私のオーバービューコントロールは常に新しいマウスイベントが来ているので、WM_PAINTを取得しないコントロールのように見えるコントロールのように思われることを意味しています。私がデザイナーでそれらをどのように配置したかの副産物であり、もし私がそれらを並べ替えるならば、私は異なった挙動を見るかもしれない。あれは正しいですか?もしそうなら、それは少し不安定に聞こえる、私はあなたの提案にUpdate()を使用したいかもしれない。 – adv12

関連する問題