ATL で Office XP 用のスマート タグ DLL を作成する方法

この記事は、以前は次の ID で公開されていました: JP292596
この資料は、アーカイブされました。これは "現状のまま" で提供され、更新されることはありません。
概要
スマート タグは、Office XP で導入されたテクノロジで、Office ユーザーに Office ドキュメントとのより強力な対話機能を提供するものです。スマート タグとは、カスタム アクションが関連付けられていると認識される Office ドキュメント内のテキスト要素です。このような特殊なテキスト要素の一例として、Word 文書または Excel ブックに入力される電子メール アドレスがあります。電子メール アドレスがスマート タグとして認識されると、そのテキストに対して実行する 1 つまたは複数のアクションがユーザーに提示されます。電子メール アドレスに関連付けられるアクションとしては、その他の連絡先情報の参照や新しい電子メール メッセージの送信などが考えられます。

Office ドキュメントで使用する独自のスマート タグ Recognizer (認識) および Action (動作) ダイナミック リンク ライブラリ (DLL) を開発することにより、Office XP の機能を拡張できます。この資料では、Active Template Library (ATL) を使用してスマート タグ DLL を作成する方法と、作成したスマート タグ DLL が Office XP で認識され、使用できるようにするために必要なレジストリ設定について説明します。

: スマート タグをサポートしている Office XP アプリケーションは、Excel 2002 と Word 2002 のみです。ただし、この資料で提供される情報は、スマート タグ テクノロジを採用するあらゆるアプリケーション用のスマート タグの開発に適用できます。スマート タグ DLL は、ISmartTagRecognizer と ISmartTagAction の 2 つの特別なインターフェイスを実装した標準 COM (Component Object Model) DLL です。ISmartTagRecognizer インターフェイスは、ドキュメントに入力されたテキストをスマート タグとして認識します。ISmartTagAction インターフェイスは、ユーザーの要求に応じて特定のスマート タグ文字列に対してアクションを実行します。これらのインターフェイスが同じ DLL に実装されている必要はありません。1 つの Recognizer DLL と複数の Action DLL を使用して、単一のスマート タグ タイプでさまざまなアクションを実行できるように拡張することができます。

先頭に戻る

ATL でのスマート タグ DLL の作成手順

以下の手順では、Microsoft Network (MSN) Messenger のメンバを認識し、認識されたメンバに電子メールまたはインスタント メッセージを送信できるようにする、簡単なスマート タグ DLL を作成します。このサンプルを使用するには、MSN Messenger が必要です。MSN Messenger がインストールされていない場合は、次の MSN Web サイトから入手できます。
  1. Visual C++ で、新しい ATL COM AppWizard プロジェクトを作成し、MessengerSmartTag という名前を付けます。
  2. [OK] をクリックして ATL COM ウィザードを起動します。表示されるダイアログ ボックスで、[ダイナミック リンク ライブラリ] が選択されていることを確認し、[終了] をクリックします。[OK] をクリックしてプロジェクトを作成します。
  3. Recognizer クラスを作成するには、[挿入] メニューの [ATL オブジェクトの新規作成] をクリックします。[シンプル オブジェクト] をクリックし、[次へ] をクリックします。短い名前として、[ショート ネーム] ボックスに Recognizer と入力し、[OK] をクリックします。
  4. Action クラスを作成するには、手順 3. と同様の手順を実行し、短い名前として Action と入力します。
  5. ClassView を開き、MessengerSmartTag クラスを展開します。CRecognizer クラスを右クリックし、[インターフェイスのインプリメント] をクリックします。警告のダイアログ ボックスが表示されたら、[OK] をクリックします。[参照] をクリックし、Microsoft Smart Tags 1.0 Type Library を選択します。[ISmartTagRecognizer] インターフェイスおよび [ISmartTagRecognizer2] インターフェイスを選択し、[OK] をクリックします。

    : Microsoft Smart Tags 1.0 Type Library のデフォルトの場所は C:\Program Files\Common Files\Microsoft Shared\Smart Tag\Mstag.tlb です。
  6. ClassView で、CAction クラスを右クリックし、[インターフェイスのインプリメント] をクリックします。警告のダイアログ ボックスが表示されたら [OK] をクリックします。[参照] をクリックし、Microsoft Smart Tags 1.0 Type Library を選択します。[ISmartTagAction] インターフェイスおよび [ISmartTagAction2] インターフェイスを選択し、[OK] をクリックします。
  7. Recognizer.h ファイルを開き、クラスの内容を以下のコードに置き換えます。
    ///////////////////////////////////////////////////////////////////////////// // CRecognizer#include "Resource.h"#import "C:\Program Files\Common Files\Microsoft Shared\Smart Tag\MSTAG.TLB" raw_interfaces_only, raw_native_types, no_namespace, named_guids class ATL_NO_VTABLE CRecognizer :    public CComObjectRootEx<CComSingleThreadModel>,   public CComCoClass<CRecognizer, &CLSID_Recognizer>,   public IDispatchImpl<IRecognizer, &IID_IRecognizer, &LIBID_MESSENGERSMARTTAGLib>,   public IDispatchImpl<ISmartTagRecognizer, &IID_ISmartTagRecognizer, &LIBID_SmartTagLib>,   public IDispatchImpl<ISmartTagRecognizer2, &IID_ISmartTagRecognizer2, &LIBID_SmartTagLib>{public:    CRecognizer();    ~CRecognizer();DECLARE_REGISTRY_RESOURCEID(IDR_RECOGNIZER)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CRecognizer)    COM_INTERFACE_ENTRY(IRecognizer)//Removed -- COM_INTERFACE_ENTRY(IDispatch)    COM_INTERFACE_ENTRY2(IDispatch, IRecognizer)    COM_INTERFACE_ENTRY(ISmartTagRecognizer)    COM_INTERFACE_ENTRY(ISmartTagRecognizer2)END_COM_MAP()// IRecognizerpublic:// ISmartTagRecognizer    STDMETHOD(get_ProgId)(BSTR * ProgId);    STDMETHOD(get_Name)(INT LocaleID, BSTR * Name);    STDMETHOD(get_Desc)(INT LocaleID, BSTR * Desc);    STDMETHOD(get_SmartTagCount)(INT * Count);    STDMETHOD(get_SmartTagName)(INT SmartTagID, BSTR * Name);    STDMETHOD(get_SmartTagDownloadURL)(INT SmartTagID, BSTR * DownloadURL);    STDMETHOD(Recognize)(BSTR Text, IF_TYPE DataType, INT LocaleID,                  ISmartTagRecognizerSite * RecognizerSite);private:    long lCount;    SAFEARRAY *psa;// ISmartTagRecognizer2    STDMETHOD(Recognize2)(BSTR Text, IF_TYPE DataType, INT LocaleID, ISmartTagRecognizerSite2 * RecognizerSite2, BSTR ApplicationName, ISmartTagTokenList * TokenList)    {        return E_NOTIMPL;    }    STDMETHOD(get_PropertyPage)(INT SmartTagID, INT LocaleID, VARIANT_BOOL * HasPropPage)    {        if (HasPropPage == NULL)            return E_POINTER;		            return E_NOTIMPL;    }    STDMETHOD(DisplayPropertyPage)(INT SmartTagID, INT LocaleID)    {        return E_NOTIMPL;    }    STDMETHOD(SmartTagInitialize)(BSTR ApplicationName)    {        return E_NOTIMPL;    }};					
  8. Recognizer.cpp ファイルを開き、ファイルの末尾に以下のコードを追加します。
    CRecognizer::CRecognizer(){    Messenger::IMsgrObject2Ptr oMsgrObj = NULL;    Messenger::IMsgrUsersPtr oUsers = NULL;    Messenger::IMsgrUserPtr oUser = NULL;    SAFEARRAYBOUND rgsaBound[1];    long rgIndices[1];		    HRESULT hr;		    // Create an instance of Instant Messenger.    oMsgrObj.CreateInstance("Messenger.MsgrObject");    // Get the list of contacts    oUsers = oMsgrObj->GetList(Messenger::MLIST_CONTACT);    // Store the number of contacts you have.    lCount = oUsers->GetCount();    rgsaBound[0].lLbound = 0;    rgsaBound[0].cElements = lCount;    // Create a SAFEARRAY to hold the list of contacts.    psa = SafeArrayCreate(VT_VARIANT, 1, rgsaBound);    // Loop through all contacts.    for (long l=0; l<lCount-1; l++)    {        rgIndices[0] = l;	        // Set the specific user.        oUser = oUsers->Item(l);        // Convert the Friendly Name to lower case        // and store it in a VARIANT.        _variant_t v = _wcslwr(oUser->GetFriendlyName());        // Put the VARIANT into the SAFEARRAY.       hr = SafeArrayPutElement(psa, rgIndices, &v);    }}CRecognizer::~CRecognizer(){    // Destroy the SAFEARRAY.    SafeArrayDestroy(psa);}HRESULT CRecognizer::get_ProgId(BSTR * ProgId){    // Set the ProgID of the Recognizer interface.    *ProgId = SysAllocString(L"MessengerSmartTag.Recognizer");    return S_OK;}HRESULT CRecognizer::get_Name(INT LocaleID, BSTR * Name){    // Set a short title about the recognizer.    *Name = SysAllocString(L"Microsoft Messenger Contacts Visual C++ Recognizer");    return S_OK;}HRESULT CRecognizer::get_Desc(INT LocaleID, BSTR * Desc){    // Set a long description of the recognizer.    *Desc = SysAllocString(L"Microsoft Messenger recognizes your Instant Messenger Contacts");    return S_OK;}HRESULT CRecognizer::get_SmartTagCount(INT * Count){    // Set the number of Smart Tags that are supported.    *Count = 1;    return S_OK;}HRESULT CRecognizer::get_SmartTagName(INT SmartTagID, BSTR * Name){    // This method is called the same number of times as you    // return in SmartTagCount. This method sets a unique name    // for the Smart Tag.    *Name = SysAllocString(L"microsoft/messenger#contacts");    return S_OK;}HRESULT CRecognizer::get_SmartTagDownloadURL(INT SmartTagID, BSTR * DownloadURL){    // Set the URL that gets embedded in documents.    *DownloadURL = NULL;    return S_OK;}HRESULT CRecognizer::Recognize(BSTR Text, IF_TYPE DataType, INT LocaleID,       ISmartTagRecognizerSite * RecognizerSite){    // The Recognize method is called and passed a text value.    // You should recognize strings in the text and set up the actions.    WCHAR *pch, *strText = _wcslwr(Text);    ISmartTagProperties  *pSmartTagProp = NULL;    long rgIndices[1];    HRESULT hr;    // Look through all contacts    for (long l = 0; l<lCount; l++)    {        rgIndices[0] = l;        // Get the contact name.        _variant_t v;        hr = SafeArrayGetElement(psa,rgIndices,&v);        // Convert the VARIANT to a BSTR.        _bstr_t bstrContact = v;        // Loop through the string looking for contacts.        for (pch = strText; (pch = wcsstr(pch, bstrContact))!=NULL; pch++)        {                // Create a new property bag.            hr = RecognizerSite->GetNewPropertyBag(&pSmartTagProp);            if (SUCCEEDED(hr)) {                // Commit the Smart Tag to the property bag.		                                hr = RecognizerSite->CommitSmartTag(                      _bstr_t("microsoft/messenger#contacts"),                      pch - strText+1, wcslen(bstrContact),                      pSmartTagProp);                                if (pSmartTagProp != NULL)                    pSmartTagProp->Release();            }        }    }    return S_OK;}					
  9. Action.h ファイルを開き、クラスの内容を以下のコードに置き換えます。
    ///////////////////////////////////////////////////////////////////////////// // CAction#include "Resource.h"#import "C:\Program Files\Common Files\Microsoft Shared\Smart Tag\MSTAG.TLB" raw_interfaces_only, raw_native_types, no_namespace, named_guids class ATL_NO_VTABLE CAction :    public CComObjectRootEx<CComSingleThreadModel>,   public CComCoClass<CAction, &CLSID_Action>,   public IDispatchImpl<IAction, &IID_IAction, &LIBID_MESSENGERSMARTTAGLib>,   public IDispatchImpl<ISmartTagAction, &IID_ISmartTagAction, &LIBID_SmartTagLib>,   public IDispatchImpl<ISmartTagAction2, &IID_ISmartTagAction2, &LIBID_SmartTagLib>{public:   CAction(){}DECLARE_REGISTRY_RESOURCEID(IDR_ACTION)DECLARE_PROTECT_FINAL_CONSTRUCT()BEGIN_COM_MAP(CAction)    COM_INTERFACE_ENTRY(IAction)//Removed -- COM_INTERFACE_ENTRY(IDispatch)    COM_INTERFACE_ENTRY2(IDispatch, IAction)    COM_INTERFACE_ENTRY(ISmartTagAction)    COM_INTERFACE_ENTRY(ISmartTagAction2)END_COM_MAP()// IActionpublic:// ISmartTagAction    STDMETHOD(get_ProgId)(BSTR * ProgId);    STDMETHOD(get_Name)(INT LocaleID, BSTR * Name);    STDMETHOD(get_Desc)(INT LocaleID, BSTR * Desc);    STDMETHOD(get_SmartTagCount)(INT * Count);    STDMETHOD(get_SmartTagName)(INT SmartTagID, BSTR * Name);    STDMETHOD(get_SmartTagCaption)(INT SmartTagID, INT LocaleID,                  BSTR * Caption);    STDMETHOD(get_VerbCount)(BSTR SmartTagName, INT * Count);    STDMETHOD(get_VerbID)(BSTR SmartTagName, INT VerbIndex, INT * VerbID);    STDMETHOD(get_VerbCaptionFromID)(INT VerbID, BSTR ApplicationName,                  INT LocaleID, BSTR * Caption);    STDMETHOD(get_VerbNameFromID)(INT VerbID, BSTR * Name);    STDMETHOD(InvokeVerb)(INT VerbID, BSTR ApplicationName,                  IDispatch * Target, ISmartTagProperties * Properties,                  BSTR Text, BSTR Xml);// ISmartTagAction2    STDMETHOD(get_VerbCaptionFromID2)(INT VerbID, BSTR ApplicationName, INT LocaleID, ISmartTagProperties * Properties, BSTR Text, BSTR Xml, IDispatch * Target, BSTR * Caption)    {        if (Caption == NULL)            return E_POINTER;        return E_NOTIMPL;    }    STDMETHOD(InvokeVerb2)(INT VerbID, BSTR ApplicationName, IDispatch * Target, ISmartTagProperties * Properties, BSTR Text, BSTR Xml, INT LocaleID)    {        return E_NOTIMPL;    }    STDMETHOD(get_IsCaptionDynamic)(INT VerbID, BSTR ApplicationName, INT LocaleID, VARIANT_BOOL * Dynamic)    {        if (Dynamic == NULL)            return E_POINTER;        return E_NOTIMPL;    }    STDMETHOD(get_ShowSmartTagIndicator)(INT VerbID, BSTR ApplicationName, INT LocaleID, VARIANT_BOOL * Visible)    {        if (Visible == NULL)            return E_POINTER;        return E_NOTIMPL;    }    STDMETHOD(SmartTagInitialize)(BSTR ApplicationName)    {        return E_NOTIMPL;    }};					
  10. Action.cpp ファイルを開き、ファイルの末尾に以下のコードを追加します。
    HRESULT CAction::get_ProgId(BSTR * ProgId){   // Set the ProgID of the Action interface.   *ProgId = SysAllocString(L"MessengerSmartTag.Action");   return S_OK;}HRESULT CAction::get_Name(INT LocaleID, BSTR * Name){   // Set a short name describing the Action.   *Name = SysAllocString(L"Messenger Smart Tag");   return S_OK;}HRESULT CAction::get_Desc(INT LocaleID, BSTR * Desc){   // Set a long description describing the action.   *Desc = SysAllocString(L"Provides actions for the Messenger Smart Tag");   return S_OK;}HRESULT CAction::get_SmartTagCount(INT * Count){    // Set the number of smart tags this action supports.    *Count = 1;    return S_OK;}HRESULT CAction::get_SmartTagName(INT SmartTagID, BSTR * Name){    // This method is called the same number of times as you    // return in SmartTagCount. This method sets a unique name    // for the smart tag.    *Name = SysAllocString(L"microsoft/messenger#contacts");    return S_OK;}HRESULT CAction::get_SmartTagCaption(INT SmartTagID, INT LocaleID, BSTR * Caption){    // This caption is displayed on the menu for the smart tag.    *Caption = SysAllocString(L"Messenger Smart Tag");    return S_OK;}HRESULT CAction::get_VerbCount(BSTR SmartTagName, INT * Count){    // Return the number of verbs we support.    if (wcsstr(SmartTagName,L"microsoft/messenger#contacts") != 0) {        *Count = 2;    }    return S_OK;}HRESULT CAction::get_VerbID(BSTR SmartTagName, INT VerbIndex, INT * VerbID){    // Return a unique ID for each verb we support.    *VerbID = VerbIndex;    return S_OK;}HRESULT CAction::get_VerbCaptionFromID(INT VerbID, BSTR ApplicationName,                     INT LocaleID, BSTR * Caption){    // Set a caption for each verb. This caption is displayed    // on the Smart Tag menu.    switch (VerbID) {      case 1:        *Caption = SysAllocString(L"Send this contact an Instant Message");        break;      case 2:        *Caption = SysAllocString(L"Send email to this contact");        break;      default:        *Caption = NULL;        break;    }    return S_OK;}HRESULT CAction::get_VerbNameFromID(INT VerbID, BSTR * Name){    // Set a string name for each verb.    switch (VerbID) {      case 1:        *Name = SysAllocString(L"SendInstantMessage");        break;      case 2:        *Name = SysAllocString(L"SendEmail");        break;    }    return S_OK;}HRESULT CAction::InvokeVerb(INT VerbID, BSTR ApplicationName,      IDispatch * Target, ISmartTagProperties * Properties,      BSTR Text, BSTR Xml){    // This method is called when a user invokes a verb    // from the Smart Tag menu.    Messenger::IMessengerApp2Ptr oMessenger = NULL;    Messenger::IMsgrObject2Ptr oMsgrObj = NULL;    Messenger::IMsgrUsersPtr oUsers = NULL;    Messenger::IMsgrUserPtr oUser = NULL;    _variant_t v;		    // Create an instance of Instant Messenger.    oMessenger.CreateInstance("Messenger.MessengerApp");    oMsgrObj.CreateInstance("Messenger.MsgrObject");    // Get a list of contacts.    oUsers = oMsgrObj->GetList(Messenger::MLIST_CONTACT);    // Loop through all contacts.    for (long l=0; l<(oUsers->GetCount()-1); l++)    {        // Get a specific contact.        oUser = oUsers->Item(l);        // Check to see if the contact is the correct one.	if (wcscmp(_wcslwr(oUser->GetFriendlyName()),_wcslwr(Text)) == 0)        {            switch (VerbID) {              case 1:                // The user wants to display the Instant Message                // box to send the contact a message.                v = oUser.GetInterfacePtr();					                oMessenger->LaunchIMUI(v);                break;              case 2:                // Shell the "mailto" protocol to start the                // user's mail program and create a new message.                _bstr_t bstrTemp = "mailto:";                bstrTemp += oUser->GetEmailAddress();				                                ShellExecute(0,"open",bstrTemp,NULL,NULL,1);                break;            }        }    }    return S_OK;}					
  11. Stdafx.h ファイルを開き、#include <atlcom.h> という行の後に以下の行を追加します。
    #import "C:\Program Files\Messenger\msmsgs.exe"						
    : Msmsgs.exe ファイルのパスは、インストールされている MSN Messenger の場所に変更します。MSN Messenger のデフォルトの場所は C:\Program Files\Messenger です。
  12. F7 キーを押して DLL を作成します。
先頭に戻る

スマート タグ DLL の登録手順

スマート タグ DLL を使用するには、この DLL をシステムに登録する必要があります。通常の COM 登録は、プロジェクトをコンパイルするか、DLL 名を指定して Regsvr32.exe を呼び出すと、実行されます。Office アプリケーションで DLL がスマート タグ DLL として認識されるためには、通常の COM 登録以外に、いくつかのレジストリ エントリを追加する必要があります。この操作を行うには、以下の手順を実行します。
  1. コマンド ラインから Regedit.exe を起動します。
  2. HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Smart Tag\Actions に、MessengerSmartTag.Action という名前の新しいサブキーを追加します。
  3. HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Smart Tag\Recognizers に、MessengerSmartTag.Recognize という名前の新しいサブキーを追加します。
  4. レジストリ エディタを終了します。
先頭に戻る

スマート タグ DLL のテスト手順

スマート タグには、マクロと同じセキュリティ モデルが適用されます。アプリケーションのセキュリティ設定が [高] に設定されている場合は、スマート タグ DLL にデジタル署名されていないと、その DLL は読み込まれません (VBA マクロと同様です)。デジタル署名の詳細については、「関連情報」を参照してください。

Word でカスタムのスマート タグ Recognizer/Action DLL をテストするには、以下の手順を実行します。
  1. MSN Messenger を起動し、サインインします。

    : このスマート タグ サンプルでは、MSN Messenger にサインインしている必要があります。MSN Messenger にサインインしていないと、カスタム DLL は読み込まれますが、連絡先は認識されません。
  2. Word 2002 を起動します。[ツール] メニューの [マクロ] をポイントし、[セキュリティ] をクリックします。マクロのセキュリティを [中] に設定し、[OK] をクリックします。変更前のマクロのセキュリティが [高] に設定されていた場合は、Word を再起動します。
  3. 新しい文書に、連絡先の登録名 (John Smith など) を入力し、Enter キーを押します。登録名の下に薄い線が表示され、スマート タグとして認識されたことが示されます。登録名の上にマウスを移動すると、スマート タグの動作ボタンが表示されます。
  4. スマート タグの動作ボタンをクリックし、ドロップダウン メニューからいずれかのカスタム動作項目を選択します。新しい文書から連絡先に、電子メールまたはインスタント メッセージを送信できます。
Excel 2002 でも、同様の手順を使用してスマート タグ DLL をテストできます。

先頭に戻る

トラブルシューティング

ユーザー設定のスマート タグの動作に問題がある場合は、まずユーザー設定のスマート タグが読み込まれていることを確認します。Word または Excel で、[ツール] メニューの [オート コレクトのオプション] をクリックし、[スマート タグ] タブをクリックし、[語句にスマート タグを付ける] チェック ボックスがオンになっていること、および、該当するスマート タグ DLL が表示されて有効になっていることを確認します。スマート タグが表示されていない場合は、正しく登録されていない可能性があります。

カスタムの Recognizer クラスまたは Action クラスの実行が問題の原因である場合は、Visual C++ DLL と同様にスマート タグ DLL をデバッグできます。Recognizer クラスのコンストラクタにブレークポイントを設定します。F5 キーを押してアプリケーションをデバッグすると、ダイアログ ボックスが表示され、デバッグ セッションの実行可能ファイルを確認するメッセージが表示されます。Winword.exe または Excel.exe を選択します。Excel または Word が起動してスマート タグが読み込まれると、ブレークポイントでコードが停止し、コードを 1 つずつ実行してデバッグすることができます。

先頭に戻る

関連情報

上記のインターフェイスに関するドキュメントおよびこれらが定義されているタイプ ライブラリは、スマート タグ SDK (Software Development Kit) に含まれています。スマート タグ SDK をまだインストールしていない場合は、スマート タグ サンプルの作成手順に進む前に、スマート タグ SDK をインストールしてください。スマート タグ SDK は、Microsoft Office XP Developer (MOD) CD-ROM または Microsoft Developer Network (MSDN) Web サイトから入手できます。
ユーザー設定のスマート タグ Recognizer/Action DLL の作成の詳細については、スマート タグ SDK に含まれているスマート タグ開発ヘルプ ファイルを参照してください。

デジタル署名の関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
247257 [INFO] .cab ファイルを署名する手順
ProgID の代わりに CLSID を使用してスマート タグ DLL を登録する方法の関連情報については、以下の「サポート技術情報」 (Microsoft Knowledge Base) を参照してください。
294422 [MODXP] スマート タグをオンまたはオフにしても Status フラグが更新されない

先頭に戻る
smart tag sdk factoid
プロパティ

文書番号:292596 - 最終更新日: 02/24/2014 15:31:24 - リビジョン: 10.0

Microsoft Excel 2002 Standard Edition, Microsoft Word 2002, Microsoft Visual C++ 6.0 Professional Edition

  • kbnosurvey kbarchive kbhowto kbhowtomaster KB292596
フィードバック