連載 .NETでWindowsアプリを作ろう

第2回 サムネイル画像コントロールを作ろう

デジタルアドバンテージ 遠藤 孝信
2005/07/23
Page1 Page2 Page3 Page4

■Addメソッドによる画像の追加

 続いては、コントロールに画像を追加するためのAddメソッドについて見ていきます。アプリケーション本体側では、表示したビットマップ(Imageオブジェクト)をパラメータに指定して、このメソッドを呼び出します。

 Addメソッドでは、パラメータに渡されたビットマップから、サムネイル用に縮小(あるいは拡大)したビットマップを作成して、コレクションであるArrayListオブジェクト(imagesフィールド)に保存していきます。このメソッドの内容は次のようになっています。

public void Add(Image img) {
  Bitmap bmp;

  // サムネイルを作成してコレクションで保持
  if (img.Width > img.Height) {
    bmp = new Bitmap(img, baseSize, baseSize  * img.Height / img.Width);
  } else {
    bmp = new Bitmap(img, baseSize  * img.Width / img.Height, baseSize);
  }
  images.Add(bmp);
  updateRowsCols();

  // 追加されたサムネイルを表示
  using (Graphics g = this.CreateGraphics()) {
    drawOne(g, images.Count - 1, false);
  }
}
Public Sub Add(ByVal img As Image)
  Dim bmp As Bitmap

  ' サムネイルを作成してコレクションで保持
  If img.Width > img.Height Then
    bmp = New Bitmap(img, baseSize, baseSize * img.Height / img.Width)
  Else
    bmp = New Bitmap(img, baseSize * img.Width / img.Height, baseSize)
  End If
  images.Add(bmp)
  updateRowsCols()

  ' 追加されたサムネイルを表示
  Dim g As Graphics = Me.CreateGraphics()
  drawOne(g, images.Count - 1, False)
  g.Dispose()
End Sub
コントロールに画像の追加を行うAddメソッド(上:C#、下:VB.NET)

 baseSizeフィールドはサムネイルのサイズを示す定数であり、プログラムでは150(ピクセル)として宣言しています。この値をもっと大きくしておけば、サムネイルが拡大されたときにもきれいに表示できますが、その分、多くのメモリが必要となります。

 このメソッドの後半では、先ほども使用したdrawOneメソッドにより、いま追加されたサムネイルをその場で描画しています(そのインデックス番号は「images.Count - 1」となります)。

 ここでの描画は、OnPaintメソッドの場合と異なり、いうなれば強制的な描画となります。このような場合には、コントロールのCreateGraphicsメソッドを呼び出して、Graphicsオブジェクトを取得する必要があります。こうして得たGraphicsオブジェクトによる描画では、無効領域に関係なく好きな位置に描画できます。

■マウスのクリック時の処理

 最後に、マウスがクリックされたときの処理について見ておきます。この場合には、OnMouseDownメソッドが呼び出されます。OnMouseDownメソッドの内容は以下のようになっています。

protected override void OnMouseDown(MouseEventArgs e)
{
  int col = e.X / gridSize;
  int row = (e.Y - this.AutoScrollPosition.Y) / gridSize;

  int newSelected = row * cols + col;

  // サムネイルの存在しない場所がクリックされた場合
  if (newSelected > images.Count - 1)
  {
    return;
  }

  ……インデックス番号の更新(省略)……
  ……サムネイルの枠の書き換え(省略)……

  // インデックス変更後にイベント・ハンドラが呼び出されるようにする
  base.OnMouseDown(e); // ★(後述)
}
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)

  Dim col As Integer = e.X \ gridSize
  Dim row As Integer = (e.Y - Me.AutoScrollPosition.Y) \ gridSize

  Dim newSelected As Integer = row * cols + col

  ' サムネイルの存在しない場所がクリックされた場合
  If newSelected > images.Count - 1 Then
    Return
  End If

  ……インデックス番号の更新(省略)……
  ……サムネイルの枠の書き換え(省略)……

  ' インデックス変更後にイベント・ハンドラが呼び出されるようにする
  MyBase.OnMouseDown(e) ' ★(後述)
End Sub
マウスがクリックされたときに呼び出されるOnMouseDownメソッド(上:C#、下:VB.NET)
OnMouseDownメソッドは、前述のOnPaintメソッドと同じ要領でオーバーライドする。

 このメソッドでは、クリックされた座標を(e.X, e.Y)として得ることができますので、グリッドのサイズ(gridSize)とスクロール位置(AutoScrollPosition.Y)の値を使えば、クリックされたグリッドのインデックス番号が求まります。

 なお、基本クラスのOnMouseDownメソッドを呼び出している位置(★の部分)がメソッドの最後であることに注意してください。アプリケーション本体側でこのコントロールのMouseDownイベントに対してイベント・ハンドラを設定する場合、そのイベント・ハンドラが実行されるのは、この★部分による基本クラスのOnMouseDownメソッドを呼び出したときとなります。

アプリケーションのイベント・ハンドラが呼び出されるまでの流れ
基本クラスのOnMouseDownメソッドを呼び出すことで、このようなイベント処理の流れが実行される。
  オーバーライドしたOnMouseDownメソッドで基本クラスの同名のメソッドを呼び出す。
  MouseDownイベントのイベント・ハンドラとして登録されている、アプリケーション本体のメソッドを呼び出す。

 現在選択されているサムネイルのインデックス番号の更新は、イベント・ハンドラが実行される前に行っておく必要があるため、★部分の呼び出しはメソッドの最後になくてはなりません。

 さて次回では、いよいよアプリケーションの本体を作成していきます。アプリケーション本体では、前回作成したGoogle用プラグインを使って得られた検索結果の画像を取得し、それを今回作成したサムネイル画像コントロールに追加して表示します。お楽しみに。End of Article


 INDEX
  .NETでWindowsアプリを作ろう
  第2回 サムネイル画像コントロールを作ろう
    1.独自コントロールとして作成するサムネイル画像コントロール
    2.プロジェクトの作成とグリッドの設定
    3.OnPaintメソッドによるサムネイルの描画
  4.画像の追加とマウス・クリック時の処理
 
インデックス・ページヘ  「.NETでWindowsアプリを作ろう 」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間