次の方法で共有


ステップ 7 ハンズオン: SuspendLayout メソッドを使ったパフォーマンスの向上

Windows フォームにおけるパフォーマンスの向上 (コントロール編)


目標 複数の画像を表示するWindows フォームアプリケーションの作成
使用技術
  • Visual Basic .NET
取り上げるトピックス
  • SuspendLayout メソッドを使ったときの画像表示方法の違いをアプリケーションで確認する
前提知識
目次
備考 画像はできる限り大きいもののほうがパフォーマンスの違いが分かりやすいですが、多き画像はメモリを使用しますので十分注意してください。
サンプルアプリケーションの
完成品ダウンロード
Improve_performance_Winform.zip (zip 形式 / 355 KB)

ピクチャーボックス コントロールパフォーマンステストアプリケーションの作成

では、ピクチャーボックスを複数持ったアプリケーションでの SuspendLayout メソッドを使ったときの表示方法の違いを確認するためのテストアプリケーションを作成してみます。

Visual Studio .NET 2003 を起動して、以下の設定で新規にプロジェクトを作成します。

 

プロジェクトの種類 プロジェクトテンプレート プロジェクト名
[Visual Basicプロジェクト] [Windowsアプリケーション] SuspendLayoutTest

ツールボックスから Picture Control を5つフォームに配置し、以下のようにプロパティを設定します。尚、画像はC:\Windows\Web\Wallpaper 等から自由に選択してください。

コントロールID プロパティ名 設定値
PicrureBox1 Anchor [Top], [Bottom], [Left]
SizeMode [StrechImage]
BorderStyle [Fixed3D]
Image 任意
PicrureBox2 Anchor [Top], [Left], [Right]
SizeMode [StrechImage]
BorderStyle [Fixed3D]
Image 任意
PicrureBox3 Anchor [Top], [Bottom], [Right]
SizeMode [StrechImage]
BorderStyle [Fixed3D]
Image 任意
PicrureBox4 Anchor [Bottom], [Left] , [Right]
SizeMode [StrechImage]
BorderStyle [Fixed3D]
Image 任意
PicrureBox4 Anchor [Top], [Bottom], [Left], [Right]
SizeMode [StrechImage]
BorderStyle [Fixed3D]
Image 任意

 

アプリケーションを実行して選択した画像がフォームに表示されていることを確認します。

PictureBox5 をダブルクリックして、Form1.vb のコードを表示します。Public Class Form1 Inherits System.Windows.Forms.Form に続けて以下のコードを追加します。

Dim bMode As Boolean = False

この変数はアプリケーション全体で、現在通常描画モード (False) にあるか、もしくは SuspendLayout モードでの描画モード (True) にあるかを示すためのフラグになります。

PicreuBox5_Clicke イベントプロシージャに以下のコードを実装します。

Private Sub PictureBox5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles PictureBox5.Click
    bMode = Not bMode
    If bMode Then
        Me.BackColor = Color.Gold
        Me.Text = "Suspend Layout Mode"
    Else
        Me.BackColor = Color.White
        Me.Text = "Normal Layout Mode"
    End If
End Sub

ここでは、PictureBox5がクリックされたときに描画モードが切り替わるようにしました。描画モードが変わるとフォームの背景色とタイトルが変更されます。ただしあくまで描画モードのフラグの変更のみです。

システムがアイドルになった際の再描画処理の為のイベントハンドラを実装します。上記のメソッドの下に以下のコードを実装します。

Private Sub AppIdle(ByVal sender As Object, ByVal e As System.EventArgs)
    Me.ResumeLayout()
End Sub

SuspendLayoutモードの場合、システムがアイドル (他の処理が完了した状態) になったら、画像の描画処理を行います。システムのアイドル状態はメッセージとしてくるため、そこから起動されるイベントとして実装します。そのため Sender オブジェクトと、EventArgs オブジェクトを引数としてつけておきます。ここで、ResulmeLayoutを行うと保留になっていた描画処理が再開されます。

最後にコード上部のドロップダウンリストボックスから、「(Form1 events)」を選んで続けて右のドロップダウンリストボックスから、「Resize」を選択します。

これは本来のWindows Form が持つサイズ変更の機能に独自の機能を足すための処理になります。ここにSuspendLayout の処理とシステムがアイドルになった際に処理を行うためのイベントハンドラを実装します。

Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) _
Handles MyBase.Resize
    'ここから下を実装する
    If bMode Then
          Me.SuspendLayout()
          AddHandler Application.Idle, AddressOf AppIdle
    End If
  'ここまで
End Sub

フラグがTrueつまり、SuspendLayout モードの時には、SuspendLayout を実行して描画処理を行わないようにします。また、システムがアイドルになったときにはメッセージを受信して前の Step で実装したメソッドを実行するようにイベントハンドラを追加します。 Application.Idle がこのアプリケーションがアイドル状態になったときにのイベントとなります。

以上で、実装は完了です。では実際にビルトしてパフォーマンスのテストをしてみましょう。「ビルト」メニューから「ソリューションのビルト」を実行してアプリケーションをビルトします。問題がなければ、「デバッグ」メニューから「デバッグ無しで開始」を実行します。

では、実際に動きを確認してみます。
はじめは通常のモードです。フォームの大きさを変更するとそれに合わせて画像の大きさも変化し、フォームの変化に合わせて逐次拡大縮小した画像を表示しています。最近の PC は CPU の性能がよいためそれほどちらつきや処理の遅延は無いかもしれませんが、サイズ変更の速度を早くすると、画像のちらつきが発生します。

続けて、SuspendLayout メソッドを使った処理を確認します。真ん中の画像をダブルクリックすると背景がオレンジ色になり、タイトルが Suspend Layout Mode に変化します。この状態で先ほどと同様にフォームの大きさを変更してみましょう。先ほどはフォームの変化に合わせて逐次大きさを変えていた画像が、今度はフォームのサイズが変わっても画像の大きさは変わりません。更に書き換え処理が発生していないこともわかるでしょう。リサイズが終了すると始めて画像が書き直されます。画像の変形・書き直しが無いため、リサイズを早くしてもパフォーマンスの低下や、画像のちらつきなどは発生しません。

環境によってはほとんどパフォーマンスに違いが無いかもしれませんが、画像の数 (コントロールの数) が多い場合や、使用環境のグラフィックの処理性能が低い場合には、パフォーマンスの違いを実感できることでしょう。

ただし、この手法は画像の変形・描画処理がリアルタイムで行われないため、アプリケーションによっては適さない場合があります。アプリケーションの要求しように合わせて使い分けることが必要です。


 

ページのトップへ