使ってみよう! Windows Live SDK/API

第2回Live Search API+VSTO

前回に引き続いてLive Search APIについてです。今回はAPIを利用したアプリケーションを考えてみたいと思います。

Live Search APIを利用したアプリケーション

Windows Live Favoritesのアドインをインストールすると、Internet Explore上でテキストを選択した状態で右クリックした場合、コンテキストメニューに図1のようにLive Searchへのメニューアイテムが出ます。このようなメニューを発展させて右クリックした時点で検索結果が表示されるのはどうでしょうか。

残念ながらInternet Exploreでそれを実現するのは難しいので、VSTO(Visual Studio Tools for Office)を使ってMicrosoft Office Wordのコンテキストメニューに検索結果を表示させてみます。開発はVisual Studio 2008 Professional Editionを使い、言語にVisual Basicを選択します。

図1 Live Searchへのリンクが表示されたコンテキストメニュー
図1 Live Searchへのリンクが表示されたコンテキストメニュー

Wordテンプレートの作成

Word 2007テンプレートとして開発することにします。新しいプロジェクトウィンドウからWord 2007テンプレートを選択し、プロジェクトを作成します図2⁠。ここではプロジェクト名をLiveSearchWordTemplateにしました。

図2 新しいプロジェクト
図2 新しいプロジェクト

[OK]ボタンをクリックすると図3のようなウィンドウが表示されますが、特に変更する項目はありませんのでそのまま[OK]ボタンをクリックします。

図3 Visual Studio Tools for Office プロジェクトウィザード
図3 Visual Studio Tools for Office プロジェクトウィザード

プロジェクトにあるファイルThisDocument.vbにThisDocumentクラスが記述されています。この中にコードを記述していきます。

メソッドの作成と検索オプションの指定

まずはWebサイト検索部分から作成します。本連載1回目を参考にサービス参照の追加まで行ってください。名前空間のインポートも済ませます。

Imports LiveSearchWordTemplate.ServiceReference

検索一連の処理をするメソッドを作ります。引数が検索文字列、戻り値が検索結果として、メソッド名はSearchにしました。

Private Function Search(ByVal query As String) As Result()
End Function

このメソッドの中にSourceRequestオブジェクトを生成するコードを記述します。Webサイトから上位3件のタイトルとURLを取得するように指定しています。

Dim sourceRequest = New SourceRequest With { _
    .Source = SourceType.Web, _
    .Offset = 0, _
    .Count = 3, _
    .ResultFields = ResultFieldMask.Title Or _
                    ResultFieldMask.Url}

続いてSearchRequestオブジェクトを生成します。Queryプロパティにはメソッドの引数を指定します。

Dim searchRequest = New SearchRequest With { _
    .AppID = "取得したApplication ID", _
    .Query = query, _
    .CultureInfo = "ja-JP", _
    .Requests = New SourceRequest() {sourceRequest}, _
    .Flags = SearchFlags.None, _
    .SafeSearch = SafeSearchOptions. Strict}

前回に登場しなかったプロパティについて新たな2項目を説明します。

Flags

雑多な検索オプションを指定します。

DisableHostCollapsing

同じドメインのURLの結果は通常2つまでしか返ってきませんが、その制限を無効にします。

MarkQueryWords

結果のタイトルと説明に検索した単語が含まれている場合、単語の前後に特定のUTF-8文字が付加されます。主に検索単語の強調に使用することが多いと思います。次のコードでは単語の前後に<b>と</b>を挿入しています。

System.Text.RegularExpressions.Regex.Replace(result.Title, "\ue000(.+?)\ue001", "<b>$1</b>")
None

何も指定しません。これが規定値になります。

このほかにもFlagsプロパティには指定できる項目が用意されています。複数のオプションを指定する場合はOr演算子を使います。

SafeSearch

検索結果の制限レベルを指定します。

Strict

成人向けのテキストまたは画像が含まれる結果は除かれます。

Moderate

成人向けの画像が含まれる結果は除かれます。これが規定値になります。

Off

検索結果の制限を行いません。

最後にMSNSearchPortTypeClientオブジェクトのSearchメソッドを呼び出し、Resultオブジェクトを返します。

Dim service = New MSNSearchPortTypeClient
Dim searchResponse = service.Search(searchRequest)
service.Close()
Return searchResponse.Responses.Single.Results

コンテキストメニューへメニューアイテムの追加

Wordのコンテキストメニューに検索結果を示すメニューアイテムを追加する処理を書きます。最初にインポートの設定をしておきます。

Imports Microsoft.Office.Core

ThisDocumentクラスには、右クリックされたとき既定の処理をする前に発生するBeforeRightClickイベントがあるので、これを利用します。コードエディタの左上のドロップダウンリストから「⁠⁠ThisDocument イベント⁠⁠」を選択し、右上のドロップダウンリストから「BeforeRightClick」を選択すると次のようにイベントハンドラのコードがクラスに追加されます。

Private Sub ThisDocument_BeforeRightClick(ByVal sender As Object, ByVal e As Microsoft.Office.Tools.Word.ClickEventArgs) Handles Me.BeforeRightClick

End Sub

このイベントハンドラ内に処理を追加していきます。

文書で選択されているテキストはパラメータeにより取得できます。実際には、テキストが選択されていない状態でもカーソルの右側にある文字が1文字格納されています。そのため、選択文字列の先頭と末尾の空白を削除した後に2文字以上ある場合、検索することにします。

Dim text = e.Selection.Text
If text.Trim.Length < 2 Then
    Exit Sub
End If

Officeのメニューアイテムやツールバーのボタンなどのコントロール群はすべてCommandBarオブジェクトから成っています[1]⁠。

コンテキストメニューにメニューアイテムを追加するためには、コンテキストメニューを成すCommandBarオブジェクトを取得し、これが持つCommadBarControlコレクションに新たなメニューアイテムを追加します。そして、メニューアイテムのCommadBarButtonオブジェクトに適切な値を設定するという手順になります。

文書を右クリックしたとき表示される標準のコンテキストメニューのCommandBarsオブジェクトの取得は次のようになります。

Dim textCommandBar = Application.CommandBars("Text")

作成したSearchメソッドにより検索結果を取得し、結果件数分だけメニューアイテムを作成しコンテキストメニューに追加します。

Dim results = Search(text)
For Each result In results
    Dim commandBarButton As CommandBarButton
    commandBarButton = CType(textCommandBar.Controls.Add(MsoControlType.msoControlButton, , , , True), CommandBarButton)
    commandBarButton.Caption = result.Title
    commandBarButton.Tag = result.Url
    AddHandler commandBarButton.Click, AddressOf CommandBarButton_Click
Next

textCommandBar.Controls.Addメソッドの第1引数にMsoControlType.msoControlButtonを指定し、戻り値が追加されたCommandBarButtonオブジェクトになります。第4引数のTrueは一時的なコントロールであることを指定しています。

メニューアイテムのキャプションにはタイトルをそのまま表示し、URLを開くときに必要になるURLの文字列はTagプロパティを利用して記憶させておきます。また、AddHandlerステートメントを使いメニューアイテムのClickイベントをCommandBarButton_Clickプロシージャに関連付けています。プロシージャはこの後に作成します。

Clickイベントに関連付けるプロシージャは次のようになります。Ctrl.TagにはURLを入れてありますので、Process.Startメソッドを使用してURLに関連付いているアプリケーションを起動します。

Private Sub CommandBarButton_Click(ByVal Ctrl As Microsoft.Office.Core.CommandBarButton, ByRef CancelDefault As Boolean)
    System.Diagnostics.Process.Start(Ctrl.Tag)
End Sub

このまま実行すると右クリックするたびにメニューアイテムが追加されてしまいます。コンテキストメニューのCommandBarsオブジェクトを取得した後にResetメソッドを使い元の状態に戻しておきます。

textCommandBar.Reset()

実行と配布

以上のコードを以下にまとめましたので参考にしてください。例外処理も追加してあります。

ThisDocument.vbのダウンロード
ThisDocument.vbファイル

実行して図4のように選択したテキストの検索結果がメニューに表示されれば完成です。クリックするとそのWebサイトに移動します。いかがでしたでしょうか。

図4 実行結果
図4 実行結果

このテンプレートを配布する場合は、ソリューションエクスプローラでプロジェクト名を右クリックし、メニューの「発行」を選択します。すると、ウィザードによりセットアッププログラムsetup.exeの作成ができます[2]⁠。また、セットアッププログラムに含めるコンポーネントなどの設定はプロジェクトのプロパティの発行タブから可能です。

おすすめ記事

記事・ニュース一覧