Visual Basic コントロールで IObjectSafety を実装する方法

概要

この資料では、Visual Basic のコントロールで IObjectSafety インターフェイスを実装して、スクリプトの実行や初期化を行ってもそのコントロールが安全であること示すマークを付ける方法について説明します。デフォルトでは、Visual Basic のコントロールに、スクリプトの実行および初期化が安全であることを示すマークを付けるには、レジストリ内のコンポーネント カテゴリのエントリを使用します。推奨されている方法は、IObjectSafety インターフェイスを実装する方法です。この資料には、Visual Basic のコントロールでこのインターフェイスを実装する際に必要なすべてのコードが含まれています。


コントロールが本当に安全な場合にのみ、安全であるというマークを付けるようにする必要があります。この資料では、スクリプトの実行や初期化を行っても安全であると、コントロールにマークを付ける方法を示したコードを紹介していますが、コントロールが安全であるというマークを付けること自体については詳しく記載していません。詳しい説明については、『Internet Client Software Development Kit (SDK)』に記載されています。「Component Development」の「Safe Initialization and Scripting for ActiveX Controls」を参照してください。

詳細

警告 : この資料には、VarPtr、VarPtrArray、VarPtrStringArray、StrPtr、ObjPtr 関数に関する記述があります。これらの関数については、Microsoft テクニカル サポートではサポートしていません。また、Visual Basic のドキュメントには記載されておらず、この「サポート技術情報」 (Microsoft Knowledge Base) の資料には現状ベースで掲載されています。マイクロソフトでは、これらの関数が Visual Basic の今後のリリースで使用できることは保障していません。
これらの関数の関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。

199824 Visual Basic で変数のアドレスを取得する方法
以下の手順では、簡単な Visual Basic コントロールを作成し、スクリプトの実行および初期化を行っても安全であるとマークする方法について説明します。

  1. この例で作成するすべてのファイルを保存できる新しいフォルダを作成します。
  2. Visual Basic 6.0 の CD-ROM から、OLE Automation Type Library Generator を入手します。CD-ROM の \Common\Tools\VB\Unsupprt\Typlib\ フォルダにある 4 つのファイルすべてを上記のプロジェクト フォルダにコピーしてください。

    : Visual Basic 5.0 の場合は、\VB5.0\Tools\Unsupprt\Typlib\ フォルダにあるすべてのファイルをコピーします。
  3. 次のテキストをメモ帳にコピーし、そのファイルを Objsafe.odl という名前でプロジェクト フォルダに保存します。
          [
    uuid(C67830E0-D11D-11cf-BD80-00AA00575603),
    helpstring("VB IObjectSafety Interface"),
    version(1.0)
    ]
    library IObjectSafetyTLB
    {
    importlib("stdole2.tlb");
    [
    uuid(CB5BDC81-93C1-11cf-8F20-00805F2CD064),
    helpstring("IObjectSafety Interface"),
    odl
    ]
    interface IObjectSafety:IUnknown {
    [helpstring("GetInterfaceSafetyOptions")]
    HRESULT GetInterfaceSafetyOptions(
    [in] long riid,
    [in] long *pdwSupportedOptions,
    [in] long *pdwEnabledOptions);

    [helpstring("SetInterfaceSafetyOptions")]
    HRESULT SetInterfaceSafetyOptions(
    [in] long riid,
    [in] long dwOptionsSetMask,
    [in] long dwEnabledOptions);
    }
    }
  4. コマンド プロンプトで、CD <path> コマンドを使用してプロジェクト フォルダに移動し、次のコマンドを入力して .tlb ファイルを生成します。
    MKTYPLIB objsafe.odl /tlb objsafe.tlb
  5. Visual Basic で、ActiveX コントロールのプロジェクトを作成します。[プロパティ] の一覧で、プロジェクトの名前を [IObjSafety] に、コントロールの名前を [DemoCtl] にそれぞれ変更します。コントロールの上に cmdTest という名前で CommandButton を配置します。cmdTest の Click イベントに、MsgBox "Test" ステートメントを追加します。
  6. [プロジェクト] メニューの [参照設定] をクリックして、先に作成した Objsafe.tlb を表示し、追加します。
  7. 次のコードを持つ新しいモジュールをプロジェクトに追加し、モジュールの名前を basSafeCtl とします。
          Option Explicit

    Public Const IID_IDispatch = "{00020400-0000-0000-C000-000000000046}"
    Public Const IID_IPersistStorage = _
    "{0000010A-0000-0000-C000-000000000046}"
    Public Const IID_IPersistStream = _
    "{00000109-0000-0000-C000-000000000046}"
    Public Const IID_IPersistPropertyBag = _
    "{37D84F60-42CB-11CE-8135-00AA004BB851}"

    Public Const INTERFACESAFE_FOR_UNTRUSTED_CALLER = &H1
    Public Const INTERFACESAFE_FOR_UNTRUSTED_DATA = &H2
    Public Const E_NOINTERFACE = &H80004002
    Public Const E_FAIL = &H80004005
    Public Const MAX_GUIDLEN = 40

    Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    (pDest As Any, pSource As Any, ByVal ByteLen As Long)
    Public Declare Function StringFromGUID2 Lib "ole32.dll" (rguid As _
    Any, ByVal lpstrClsId As Long, ByVal cbMax As Integer) As Long

    Public Type udtGUID
    Data1 As Long
    Data2 As Integer
    Data3 As Integer
    Data4(7) As Byte
    End Type

    Public m_fSafeForScripting As Boolean
    Public m_fSafeForInitializing As Boolean

    Sub Main()
    m_fSafeForScripting = True
    m_fSafeForInitializing = True
    End Sub
  8. プロジェクト プロパティで、[スタートアップの設定] を [Sub Main] に変更して、上記の Sub Main が実行されるようにします。m_fSafeForScripting と m_fSafeForInitializing の各変数を使用して、スクリプトの実行や変数の初期化を行っても安全であることを示す値を指定します。
  9. コントロールのコード ウィンドウを開きます。コードの宣言セクション (Option Explicit の直後か先頭) に、次のコードの行を追加します。
    Implements IObjectSafety
  10. 次の 2 つのプロシージャをコントロールのコードにコピーします。
          Private Sub IObjectSafety_GetInterfaceSafetyOptions(ByVal riid As _
    Long, pdwSupportedOptions As Long, pdwEnabledOptions As Long)

    Dim Rc As Long
    Dim rClsId As udtGUID
    Dim IID As String
    Dim bIID() As Byte

    pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER Or _
    INTERFACESAFE_FOR_UNTRUSTED_DATA

    If (riid <> 0) Then
    CopyMemory rClsId, ByVal riid, Len(rClsId)

    bIID = String$(MAX_GUIDLEN, 0)
    Rc = StringFromGUID2(rClsId, VarPtr(bIID(0)), MAX_GUIDLEN)
    Rc = InStr(1, bIID, vbNullChar) - 1
    IID = Left$(UCase(bIID), Rc)

    Select Case IID
    Case IID_IDispatch
    pdwEnabledOptions = IIf(m_fSafeForScripting, _
    INTERFACESAFE_FOR_UNTRUSTED_CALLER, 0)
    Exit Sub
    Case IID_IPersistStorage, IID_IPersistStream, _
    IID_IPersistPropertyBag
    pdwEnabledOptions = IIf(m_fSafeForInitializing, _
    INTERFACESAFE_FOR_UNTRUSTED_DATA, 0)
    Exit Sub
    Case Else
    Err.Raise E_NOINTERFACE
    Exit Sub
    End Select
    End If
    End Sub

    Private Sub IObjectSafety_SetInterfaceSafetyOptions(ByVal riid As _
    Long, ByVal dwOptionsSetMask As Long, ByVal dwEnabledOptions As Long)
    Dim Rc As Long
    Dim rClsId As udtGUID
    Dim IID As String
    Dim bIID() As Byte

    If (riid <> 0) Then
    CopyMemory rClsId, ByVal riid, Len(rClsId)

    bIID = String$(MAX_GUIDLEN, 0)
    Rc = StringFromGUID2(rClsId, VarPtr(bIID(0)), MAX_GUIDLEN)
    Rc = InStr(1, bIID, vbNullChar) - 1
    IID = Left$(UCase(bIID), Rc)

    Select Case IID
    Case IID_IDispatch
    If ((dwEnabledOptions And dwOptionsSetMask) <> _
    INTERFACESAFE_FOR_UNTRUSTED_CALLER) Then
    Err.Raise E_FAIL
    Exit Sub
    Else
    If Not m_fSafeForScripting Then
    Err.Raise E_FAIL
    End If
    Exit Sub
    End If

    Case IID_IPersistStorage, IID_IPersistStream, _
    IID_IPersistPropertyBag
    If ((dwEnabledOptions And dwOptionsSetMask) <> _
    INTERFACESAFE_FOR_UNTRUSTED_DATA) Then
    Err.Raise E_FAIL
    Exit Sub
    Else
    If Not m_fSafeForInitializing Then
    Err.Raise E_FAIL
    End If
    Exit Sub
    End If

    Case Else
    Err.Raise E_NOINTERFACE
    Exit Sub
    End Select
    End If
    End Sub
  11. [ファイル] メニューで、プロジェクトとファイルを保存します。プロジェクトから OCX ファイルを作成します。これで、コントロールに IObjectSafety インターフェイスが実装されます。テストするには、コントロールを .htm ファイルに挿入してください。

関連情報

MkTypLib.exe は、以前、Microsoft Visual Studio 6.0 に付属の『Platform Software Development Kit (SDK)』に含まれていた古いツールです。Visual Studio 6.0 に付属する Platform SDK をインストールする方法の関連情報については、次のマイクロソフト Web サイトを参照してください。
現在の Platform SDK には、MkTypLib.exe ツールは含まれていません。Type Library Compiler (MkTypLib.exe) が付属するマイクロソフト製品の情報については、次の Microsoft DLL ヘルプ データベースにアクセスして、ファイル名 MkTypLib.exe を検索してください。
MkTypLib を実行する方法については、次のマイクロソフト Web サイトを参照してください。
関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。

161873 スクリプトおよび初期化を実行しても安全として MFC コントロールにマークする方法
143258 タイプ ライブラリで定数および DLL の宣言を行う方法
131105 [SAMPLE] [TYPEBLD] ICreateTypeLib および ICreateTypeInfo を使用する方法
IObjectSafety インターフェイスの関連情報については、次のマイクロソフト Web サイトを参照してください。
ActiveX コントロールの安全な初期化とスクリプティングの関連情報については、次のマイクロソフト Web サイトを参照してください。
Microsoft Internet Explorer 用の Web ベース ソリューションの開発に関する詳細については、以下のマイクロソフト Web サイトを参照してください。
プロパティ

文書番号:182598 - 最終更新日: 2006/08/31 - リビジョン: 1

フィードバック