再描画が不十分
kanryu さん
山本です。 ご指摘ありがとうございます。
調査したところ原因が特定できましたので、修正いたしました。 修正リビジョンは 205 で、リリース 1.4 に含めます。 ご迷惑をおかけして申し訳ありません。
後ろに原因などを記しておきます。 どうでも良い場合は、読み飛ばしてください。 それでは今後ともよろしくお願いします。
以下、原因などの説明です。
AzukiControl では .NET の Control クラスのウィンドウプロシージャを 上書きして描画イベント処理を乗っ取っています。 具体的には WM_PAINT を受け取ったら BeginPaint、描画、EndPaint と処理しています(Win32API的に普通な流れ)。 しかし、この後で「特に害は無い」と思って Control クラスのウィンドウプロシージャに処理を流していました。 これがまずかったようです。
憶測ですが、Control クラスの描画処理でも BeginPaint を実行していると予想できます。 すると Azuki 独自処理が BeginPaint を呼んでから Control クラスの描画処理内で BeginPaint が呼ばれるまでの間に再描画が必要な領域が出てくると、 その再描画領域 (update region) が捨てられることになります。 ウィンドウの上で他のウィンドウをドラッグすると猛烈な勢いで 再描画領域が更新されていきますから、 この条件を満たすケースがあっても不思議ではないと思います。
憶測が正しいかどうかは分かりませんが、Control クラスの描画処理を実行しないようにしたら現象が起こらなくなりました。
最後になりますが、今回の修正では kanryu さんの「他のControl」という言葉がヒントになりました。ありがとうございます。
憶測ですが、Control クラスの描画処理でも BeginPaint を実行していると予想できます。
おそらく、背景用のブラシで埋めるくらいの極単純な動作をしてるんでしょう。(Azukiの場合はNullブラシですね?)
仮に呼ぶとしたらAzukiのオーナードローよりも前にControl.BeginPaint()を呼び出す手順でしょうか。
Azukiの描画部のソースコードを見る限りでは全領域を描画してしまっているので、おっしゃるとおり不要かもしれません。
Subversionで手元のソースツリーを更新し、動作チェックをしたところ、こちらでも描画の不具合が修正されていることを確認しました。 修正お疲れさまです。
Azukiをフォームに配置して表示していると、他のウィンドウがかぶさった後で十分な再描画が行われず、他のウィンドウの表示の残滓がそのままAzukiのクライアント領域に残ったままになります。
他のControlでは同様の問題は発生しないことから、明らかにAzukiの実装上の問題です。