|  |  | 
 
| 連載 .NETでWindowsアプリを作ろう第1回 Google画像検索アプリを作ろうデジタルアドバンテージ 遠藤 孝信2005/06/25
 |  | 
| 
 | 
Google用プラグインの作成
 Googleの下調べが終わり、必要なモジュールもそろったところで、実際にGoogle用プラグインをコーディングしていきましょう。
 ここではVS.NETをいったん閉じるか、あるいはもう1つVS.NETを起動して、まずGoogle用プラグインの新しいプロジェクト「WISGoogle」を作ります。プラグインとなるDLLファイルを作成するので、新しいプロジェクトではテンプレートとして「クラス ライブラリ」を選択します。
 プラグインは、先ほど作成したWebImageクラスとIWebImageインターフェイスに基づいてコーディングを行うため、プロジェクトの準備が出来たら、先ほど作成したDLLファイルをWISGoogleプロジェクトの参照設定に追加します。これはソリューション・エクスプローラでWISGoogleプロジェクト内にある[参照設定]を右クリックし、[参照の追加]で先ほど作成したWebImageLib.dllを指定します。
 さらにURLエンコーディング用のHttpUtilityクラス(System.Web名前空間)が含まれている.NETのコンポーネントである「System.Web.dll」も参照設定が必要となります(クラス・ライブラリ作成用のテンプレートでは、デフォルトではこのコンポーネントは参照設定されていません)。
 では、コードを書いていきましょう。クラス名はGoogleImageクラスとします。このクラスは自動作成されているファイル「Class1.cs」を「GoogleImage.cs」にリネームして記述します。
 GoogleImageクラスでは次の2つのフィールドによりオブジェクトの内部状態を管理します(VB.NET版では_hasNextと_currentPage)。
- hasNext:次のページが存在するかどうかを示すbool値
- currentPage:現在の検索結果ページのページ番号
 hasNextフィールドは1ページを取得したときに「次へ」のリンクがあればtrueに、なければfalseにセットされます。currentPgaeフィールドは、GetImagesメソッドにより取得対象となるページを示すものです。
 Web検索を行い、その結果をWebImageオブジェクトの配列として返すGetImagesメソッドの内部は大まかには次のようになります(全リストは冒頭で紹介したダウンロード用のプロジェクトか、リスト脚注にあるGoogleImage.csあるいはGoogleImage.vbを参照してください)。
| 
 
| static Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");string url = "http://images.google.co.jp/images?hl=ja&q={0}&start={1}&filter=0&safe=off";
 
 public WebImage[] GetImages(string query)
 {
 ArrayList images = new ArrayList();
 if (query != "")
 {
 string html = readPage(
 String.Format(url, System.Web.HttpUtility.UrlEncode(query, sjisEnc), currentPage * 20));
 
 ……略……
 文字列htmlを解析して必要なURLを切り出し、
 すべてArrayListコレクションに追加していく
 images.Add(new WebImage(small, large, page));
 ……略……
 
 // 「次へ」のリンク・テキストをチェック
 hasNext = html.IndexOf("<span class=b><b>次へ</b></span>") == -1 ? false : true;
 }
 // 配列に変換
 return (WebImage[])images.ToArray(typeof(WebImage));
 }
 |  
 
| Shared sjisEnc As Encoding = Encoding.GetEncoding("Shift_JIS")Dim url As String = "http://images.google.co.jp/images?hl=ja&q={0}&start={1}&filter=0&safe=off"
 
 Public Function GetImages(ByVal query As String) As WebImageLibVB.WebImage() Implements WebImageLibVB.IWebImage.GetImages
 Dim images As New ArrayList
 If query <> "" Then
 Dim html As String = readPage( _
 String.Format(url, System.Web.HttpUtility.UrlEncode(query, sjisEnc), _currentPage * 20))
 
 ……略……
 文字列htmlを解析して必要なURLを切り出し、
 すべてArrayListコレクションに追加していく
 images.Add(New WebImage(small, large, page))
 ……略……
 
 ' 「次へ」のリンク・テキストをチェック
 If html.IndexOf("<span class=b><b>次へ</b></span>") = -1 Then
 _hasNext = False
 Else
 _hasNext = True
 End If
 End If
 ' 配列に変換
 Return CType(images.ToArray(GetType(WebImage)), WebImage())
 End Function
 |  | 
 
| IWebImageインターフェイスのGetImagesメソッドの実装の概略(上:C#、下:VB.NET) | 
|  | 
|  | 
 readPageメソッドは、指定されたWebページを読み取ってHTMLデータを文字列として返します(これについては「.NET TIPS:WebClientクラスでWebページを取得するには?」を参照)。
 ここでは、readPageメソッドにより読み込んだ検索結果ページを解析し、必要なURLを切り出して、順にコレクションに追加していきます。そしてそれをWebImageクラスの配列に変換して返します。また、「次へ」のリンク文字列の有無をチェックしてhasNextフィールドを設定します。
 MoveNextメソッドでは、次のページがあればcurrentPageフィールドを1進め、なければ何もしません。GetImagesメソッドを呼び出して検索結果を取得し、次にこのメソッドを呼び出してfalseが返ってくれば、それ以上は検索結果がないことになります。
| 
 
| public bool MoveNext(){
 if (hasNext)
 {
 currentPage++;
 }
 return hasNext;
 }
 |  
 
| Public Function MoveNext() As Boolean Implements WebImageLibVB.IWebImage.MoveNextIf _hasNext Then
 _currentPage = _currentPage + 1
 End If
 Return _hasNext
 End Function
 |  | 
 
| IWebImageインターフェイスのMoveNextメソッドの実装(上:C#、下:VB.NET) | 
 Nameプロパティは、単にメイン・ウィンドウのコンボボックスに表示される表示名を返すだけです。
| 
 
| public string Name{
 get { return "Google"; }
 }
 |  
 
| Public ReadOnly Property Name() As String Implements WebImageLibVB.IWebImage.NameGet
 Return "Google"
 End Get
 End Property
 |  | 
 
| IWebImageインターフェイスのNameプロパティの実装(上:C#、下:VB.NET) | 
 Resetメソッドはオブジェクト内部の状態を初期化するメソッドです。このクラスのコンストラクタでは、このResetメソッドを呼び出してフィールドを初期化します。
| 
 
| public void Reset(){
 hasNext = false;
 currentPage = 0;
 }
 |  
 
| Public Sub Reset() Implements WebImageLibVB.IWebImage.Reset_hasNext = False
 _currentPage = 0
 End Sub
 |  | 
 
| IWebImageインターフェイスのResetメソッドの実装(上:C#、下:VB.NET) | 
 ほかのメソッドやプロパティについてはソース・コードを参照してください。WISGoogleプロジェクトをビルドするとGoogle用プラグインであるWISGoogle.dllが出来上がります。
■Google用プラグインのテスト
 以上で完成ですが、このままではつまらないので、次のような簡単なテスト・クラス(GoogleTestクラス)を追加して、実際に動かしてみましょう。このクラスはGoogleImageクラスと同じファイルに記述します。
| 
 
| public class GoogleTest{
 static void Main()
 {
 string query = "c#";
 IWebImage google = new GoogleImage();
 do
 {
 foreach (WebImage wi in google.GetImages(query))
 {
 Console.WriteLine(google.CurrentPage);
 Console.WriteLine(wi.SmallImageURL);
 Console.WriteLine(wi.LargeImageURL);
 Console.WriteLine(wi.DetailPageURL);
 }
 } while (google.MoveNext());
 }
 }
 |  
 
| Public Class GoogleTestShared Sub Main()
 Dim query As String = "c#"
 Dim google As New GoogleImage
 
 Do
 For Each wi As WebImage In google.GetImages(query)
 Console.WriteLine(google.CurrentPage)
 Console.WriteLine(wi.SmallImageURL)
 Console.WriteLine(wi.LargeImageURL)
 Console.WriteLine(wi.DetailPageURL)
 Next
 Loop Until google.MoveNext() = False
 End Sub
 End Class
 |  | 
 
| Google用プラグインをテストするためのコード(上:C#、下:VB.NET) | 
 そして、プロジェクトのプロパティを開き、次の画面のように「出力の種類」を、[クラス ライブラリ]から[Windowsアプリケーション]に一時的に変更します。そして実行すれば、このMainメソッドのWriteLineメソッドによる出力がVS.NET内の[出力]ウィンドウに表示されます。
 
|  | 
 
| プロジェクトのプロパティ(画面はC#の場合) | 
 
| コードにMainメソッドを追加し、「出力の種類」を[クラス ライブラリ]から[Windowsアプリケーション]に変更することによりEXEファイルが作成され、単体で実行できるようになる。またVS.NETでは、出力の種類を[Windowsアプリケーション]にすると、コンソール画面への出力はVS.NETの[出力]ウィンドウに出力される。 | 
 [出力]ウィンドウには画像やページのURLがだらだらと表示されれば成功です。各URLは、[CTRL]キーを押しながらマウスで左クリックすれば、VS.NET内に画像やページが表示され、それらが正しいリンク先となっているかを確認できます。
 
|  | 
 
| Google用プラグインのテスト実行結果 | 
 
| [出力]ウィンドウには画像やページのURLが表示されていく。この画面はその1つを[CTRL]キーを押しながらマウスで左クリックし、URLが示す画像を表示したところ。 | 
 今回はGoogle用プラグインを作成しましたが、同様の手順によりIWebImageインターフェイスを実装したクラスを作成すれば、別の検索サイトに対応したプラグインも作成可能です。このようにして作ったDLLファイルは、実行ファイルのみのzipファイルに含まれているWebImageSearch.exeのあるディレクトリにコピーすれば、アプリケーション(WebImageSearch.exe)から使えるようになるはずです。時間があったら試してみてください。
■
 さて次回は、拡大/縮小可能なサムネイル画像を並べて表示する、本アプリケーションのコアともいえる「サムネイル・ビューア・コントロール」を作成します。これはほかのアプリケーションでも流用できるように独立したコントロールにする予定です。お楽しみに。