Have an amazing solution built in RAD Studio? Let us know. Looking for discounts? Visit our Special Offers page!
C++DelphiRAD Studio

RAD Studio 11で追加されたTWinControlのLockDrawingメソッド

vcl110_lockdrawing-1878353

RAD Studio 11でVCLライブラリに新しく追加された機能の1つとして、TWinControlクラスに追加された2つのメソッド (LockDrawingとUnlockDrawing) を使用して、WindowsのWM_SETREDRAWメッセージを簡単に処理できるようになったことが挙げられます。

まずはWindowsのAPIについて説明しましょう。WM_SETREDRAWというウィンドウメッセージは、”ウィンドウの変更を再描画することを許可、あるいはウィンドウの変更を再描画しない”といったウィンドウの描画を抑制する目的で、SendMessage関数を使用してウィンドウへメッセージを送信します。

例えば、TreeViewやListViewなどのWindowコモンコントロールでは、たとえ追加/削除するアイテムが1つだけでも都度 再描画が行われます。さらに処理の余計なオーバーヘッドにも繋がります。WM_SETREDRAWメッセージによって、再描画が必要となる一連の操作を一旦保留し、最後に再描画を実行することができます。これによって、コントロールのちらつきを防止し、処理を高速化することができます。もちろんロックを解除し、RedrawWindow関数を呼び出して強制的に再描画することは重要です。

RAD Studio 11では、VCLライブラリであるTWinControlクラスの2つの新しいメソッド「LockDrawing」と「UnlockDrawing」を追加し、適切なパラメータでWM_SETREDRAWメッセージを送信します。また、「ロックカウントロジック」を実装しているため、同じコントロールを2回ロックした場合、描画を再開するには2回ロックを解除する必要があります。 さらに、UnlockDrawingは自動的にRedrawWindowAPIを呼び出します。

では、どのようなケースで使用するのでしょうか?ここでは、簡単なデモによって二つのシナリオを紹介します。またRadek Cervinka氏のブログはとても素晴らしいので併せてご参照ください。

1つ目のシナリオは、TListBoxコンポーネントに対してアイテムを追加するケースです。VCLでは、RAD Studioの従来のバージョンから文字列リストの更新を一時的に保留することで再描画を回避する独自の仕組みを提供してきました。この機能はRAD Studio 11でも利用可能ですが、さらに別の選択肢としてLockDrawing/UnlockDrawingによるUIの再描画をロックする機能も新しく提供しています。今後はこの2つのコーディングスタイルが利用できます。

var
  I: Integer;
begin
  ListBox1.Items.BeginUpdate;
  try
    for I := 1 to 10000 do
      ListBox1.Items.Add('Line ' + I.ToString);
  finally
      ListBox1.Items.EndUpdate;
  end;
 
var
  I: Integer;
begin
  ListBox1.LockDrawing;
  try
    for I := 1 to 10000 do
      ListBox1.Items.Add('Line ' + I.ToString);
  finally
    ListBox1.UnlockDrawing;
  end;

なお、上記2つのコーディングスタイルのどちらの方法を利用しても、使用しないケースに比べて、パフォーマンスは目に見えるほど顕著に向上します。

二つ目のシナリオは、コンポーネントへの一連の変更によって再描画が発生するケースです。これは単純な例でシミュレートするのは簡単ではありませんが、以下のようなコードで意図的にフリッカーを引き起こす方法があります。

var
  I: Integer;
begin
  Panel1.LockDrawing;
  try
    for I := 1 to 10000 do
    begin
      Panel1.Color := clBlue;
      Panel1.Repaint;
      Panel1.Color := clRed;
      Panel1.Repaint;
    end;
  finally
    Panel1.UnlockDrawing;
  end;

上記のコードは非常に極端な例ですが、Lock/Unlock 呼び出しでチラつきは発生せず、UI をロックしないとかなりひどい結果になります。静止画のスクリーンショットでは、チラつきが発生するレンダリングは伝わりませんが、以下の図はデモプログラムを実行したフォーム画面です。

vcl110_lockdrawing-1878353
RAD Studio 13.2 Florence Now Available! Kai 1.1.1 Now Available! What's Coming in RAD Studio 13.2 Florence

Reduce development time and get to market faster with RAD Studio, Delphi, or C++Builder.
Design. Code. Compile. Deploy.

Start Free Trial   Upgrade Today

   Free Delphi Community Edition   Free C++Builder Community Edition

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

IN THE ARTICLES