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

第3回 画像検索ツール本体をマルチスレッドで作ろう

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

アプリケーションの画面設計

 まずStatusBarコントロールをフォームに配置します。アプリケーションでは、ステータスバーにより現在選択されているサムネイル画像が置かれているWebページのURLを表示するようにしています。

 次にPanelコントロールを配置し、そのDockプロパティを「Top」にして上側にドッキングさせます。さらに、サムネイル画像コントロールをフォームの中央にドラッグ&ドロップし、Dockプロパティを「Fill」に設定します。

StatusBar、Panel、サムネイル画像コントロールを配置したフォーム

 Panelコントロール上には、検索キーワード入力用のTextBoxコントロール(名前:textBoxKeyword)、[検索開始]ボタン(名前:buttonStart)、[停止]ボタン(名前:buttonStop)を配置し、さらにサムネイル画像拡大/縮小用のTrackBarコントロールも配置します(TextBoxとButton以外はデフォルトの名前のまま使います)。

Panel上に配置したTextBox、Button(2つ)、TrackBarコントロール

 配置したTrackBarコントロールは、常に横幅いっぱいに表示されるように、プロパティウィンドウでAnchorプロパティを「Top, Left, Right」に設定しておきます。

 最後に、フォームのAcceptButtonプロパティを「buttonStart」に、CancelButtonプロパティを「buttonStop」に設定します。こうしておくと[Enter]キー/[ESC]キーで検索を開始/停止できるようになり便利です。

 以上で画面の設計は完了です。

アプリケーション本体のコーディング

 それではいよいよコーディングに入っていきましょう。

 今回の実装で最終的に出来上がるプロジェクトのソース・ファイルを以下に用意しました。

 これにはアプリケーションのビルドに必要なすべてのプロジェクトが含まれており、zipファイルを展開し、WebImageSearchフォルダにあるWebImageSearch.slnを開けばアプリケーションをビルドして実行できるようになっています。

 今回でコードを追加・修正しているファイルは、WebImageSearchプロジェクトのForm1.cs(Form1.vb)のみです。このファイルは以下のリンクからも参照できるようにしました。

 以降はポイントとなる部分のみをかいつまんで説明していきますので、詳しくはこれらを参照してください。

■フィールドの宣言と初期化

 まずは、フォーム(Form1.cs/Form1.vb)で必要となるフィールドを宣言し、初期化しておきます。

bool working = false;   // 実行中を示すフラグ
int numFound = 0;       // 検索結果件数
string keyword = "";    // 入力された検索キーワード
string appName = "Web画像検索";
IWebImage google = new GoogleImage();
ArrayList webImages = ArrayList.Synchronized(new ArrayList());
Dim working As Boolean = False ' 実行中を示すフラグ
Dim numFound As Integer = 0    ' 検索結果件数
Dim keyword As String = ""     ' 入力された検索キーワード
Dim AppName As String = "Web画像検索"
Dim google As IWebImage = New GoogleImage
Dim webImages As ArrayList = ArrayList.Synchronized(New ArrayList)
フォームにおけるフィールドの宣言と初期化(上:C#、下:VB.NET)

 変数workingは検索が実行中かどうかを示すフラグです。[検索開始]ボタンがクリックされればtrueに設定し、[停止]ボタンがクリックされればfalseに設定します。検索処理中には、この変数がtrueになれば検索を中断します。

 変数keywordには、テキストボックスに入力された検索キーワードがコピーされます。検索キーワードは検索スレッドで実際に検索を行うときに必要となりますが、後述するように、検索スレッドではテキストボックスに入力された文字列を直接読み出すことはできないため、このフィールドを経由して入力された検索キーワードを取得します。

 コレクションである変数webImagesには、検索により見つかった画像(WebImageオブジェクト)をどんどん追加していきます。先ほどのテストのように、サムネイル画像を表示するだけならWebImageオブジェクトを保存しておく必要はありませんが、サムネイル画像がクリックされたときに、その元画像や元画像のページをブラウザで表示できるようにするために、表示中の画像についてはそのWebImageオブジェクトをコレクションに保持しておきます。

 このコレクションは検索スレッドで項目を追加しながら、UIスレッドではその読み出しを行う場合があるので、追加と読み出しの処理は排他制御にしておく必要があります(=コレクションはスレッド・セーフでなければならない)。ArrayListクラスのSynchronizedメソッドを使ってラッパー・オブジェクトを作成しているのはこのためです*

* Synchronizedメソッドについては「.NET TIPS:スレッド・セーフなコレクション・オブジェクトを作成するには?を参照してください。

■フォームのロード時の処理

 次に、フォームのロード時に行ういくつかの初期設定をフォームのLoadイベント・ハンドラに記述します。

private void Form1_Load(object sender, System.EventArgs e)
{
  // トラックバーのプロパティ設定
  trackBar1.Minimum = 15;
  trackBar1.Maximum = thumbViewer1.ClientSize.Width;
  trackBar1.TickFrequency = 10;

  // サムネイルの初期サイズを取りあえず100に設定
  trackBar1.Value = 100;
  thumbViewer1.ThumbnailSize = 100;

  readyToStart();

  this.Text = appName;
}
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  ' トラックバーのプロパティ設定
  TrackBar1.Minimum = 15
  TrackBar1.Maximum = ThumbViewer1.ClientSize.Width
  TrackBar1.TickFrequency = 10

  ' サムネイルの初期サイズを取りあえず100に設定
  TrackBar1.Value = 100
  ThumbViewer1.ThumbnailSize = 100

  readyToStart()

  this.Text = AppName
End Sub
フォームのロード時に実行されるLoadイベント・ハンドラ(上:C#、下:VB.NET)

 トラックバーについては、最大値(Maximumプロパティ)をサムネイル画像コントロールの幅に設定しています。これによりトラックバーのつまみを一番右端に移動させると、画面いっぱいにサムネイル画像が表示されるようにしています。

 readyToStartメソッドは、テキストボックスにフォーカスを設定し、入力されている文字を選択状態にしたり、検索の開始時に無効化した[検索開始]ボタンを有効化したりするなど、検索開始の準備を行うためのメソッドです。これらの処理はここ以外にも、検索が完了したときや[停止]ボタンがクリックされたときにも行うため、このメソッドにまとめています。


 INDEX
  .NETでWindowsアプリを作ろう
  第3回 画像検索ツール本体をマルチスレッドで作ろう
    1.Google用プラグイン・プロジェクトの追加とテスト
    2.サムネイル画像コントロールの登録とテスト
  3.アプリケーションの画面設計とコーディング
    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 記事ランキング

本日 月間