この記事では、MFC ActiveX コントロールをスクリプトと初期化に安全としてマークする方法について説明します。
元の製品バージョン: MFC ActiveX コントロール
元の KB 番号: 161873
まとめ
既定では、MFC ActiveX コントロールはスクリプトの安全と初期化に安全としてマークされません。 これは、Internet Explorer でコントロールが実行され、セキュリティ レベルが中または高に設定されている場合に明らかになります。 これらのモードのいずれかで、コントロールのデータが安全ではないか、スクリプトが使用してもコントロールが安全ではない可能性があることを示す警告が表示されることがあります。
これらのエラーを排除するためにコントロールで使用できるメソッドは 2 つあります。 1 つ目は、 IObjectSafety
インターフェイスを実装するコントロールを含み、インターネット ブラウザーのコンテキストで動作を変更し、実行すると安全になるコントロールに役立ちます。 2 つ目は、コントロールの DllRegisterServer
関数を変更して、レジストリ内のコントロールセーフをマークすることです。 この記事では、これらのメソッドの 2 つ目について説明します。 IObjectSafety
インターフェイスを実装する最初のメソッドについては、インターネット クライアント SDK で説明します。
コントロールは、実際には安全な場合にのみ安全としてマークする必要があることに注意してください。 この説明については、インターネット クライアント SDK のドキュメントを参照してください。 「コンポーネント開発」セクションの「ActiveX コントロールの Safe の初期化とスクリプト 」を参照してください。
Note
この記事では、ダウンロードに安全なコントロールをマークする方法については説明しません。 コードのダウンロードとコード署名の詳細については、インターネット クライアント SDK を参照してください。
詳細
MFC ActiveX コントロールをスクリプトの安全なコントロールとしてマークし、初期化しても安全な状態にするには、次の手順に従います。
次の cathelp.h ファイルとcathelp.cpp ファイルをプロジェクトに追加して、
CreateComponentCategory
およびRegisterCLSIDInCategory
ヘルパー関数を実装します。Cathelp.h
#include "comcat.h" // Helper function to create a component category and associated // description HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription); // Helper function to register a CLSID as belonging to a component // category HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid);
Cathelp.cpp
#include "comcat.h" // Helper function to create a component category and associated // description HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription) { ICatRegister* pcr = NULL ; HRESULT hr = S_OK ; hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); if (FAILED(hr)) return hr; // Make sure the HKCR\Component Categories\{..catid...} // key is registered CATEGORYINFO catinfo; catinfo.catid = catid; catinfo.lcid = 0x0409 ; // english // Make sure the provided description is not too long. // Only copy the first 127 characters if it is int len = wcslen(catDescription); if (len>127) len = 127; wcsncpy(catinfo.szDescription, catDescription, len); // Make sure the description is null terminated catinfo.szDescription[len] = '\0'; hr = pcr->RegisterCategories(1, &catinfo); pcr->Release(); return hr; } // Helper function to register a CLSID as belonging to a component // category HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid) { // Register your component categories information. ICatRegister* pcr = NULL ; HRESULT hr = S_OK ; hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr); if (SUCCEEDED(hr)) { // Register this category as being "implemented" by // the class. CATID rgcatid[1] ; rgcatid[0] = catid; hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid); } if (pcr != NULL) pcr->Release(); return hr; }
コントロールを安全としてマークするように
DllRegisterServer
を変更します。 プロジェクト内の.cpp ファイルでDllRegisterServer
の実装を見つけます。 この.cpp ファイルに複数のものを追加する必要があります。CreateComponentCategory
とRegisterCLSIDInCategory
を実装するファイルを含めます。#include "CatHelp.h"
安全コンポーネントカテゴリに関連付けられている GUID を定義します。
const CATID CATID_SafeForScripting = {0x7dd95801,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4 }} ; const CATID CATID_SafeForInitializing = {0x7dd95802,0x9882,0x11cf,{0x9f,0xa9,0x00,0xaa,0x00,0x6c,0x42,0xc4 }} ;
コントロールに関連付けられている GUID を定義します。 わかりやすくするために、コントロールのメイン .cpp ファイルの
IMPLEMENT_OLECREATE_EX
マクロから GUID を借用できます。 次のように書式を少し調整します。const GUID CDECL BASED_CODE _ctlid = { 0x43bd9e45, 0x328f, 0x11d0, { 0xa6, 0xb9, 0x0, 0xaa, 0x0, 0xa7, 0xf, 0xc2 } };
コントロールをスクリプトと初期化の両方で安全としてマークするには、
DllRegisterServer
関数を次のように変更します。STDAPI DllRegisterServer(void) { AFX_MANAGE_STATE(_afxModuleAddrThis); if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid)) return ResultFromScode(SELFREG_E_TYPELIB); if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE)) return ResultFromScode(SELFREG_E_CLASS); if (FAILED( CreateComponentCategory( CATID_SafeForScripting, L"Controls that are safely scriptable"))) return ResultFromScode(SELFREG_E_CLASS); if (FAILED( CreateComponentCategory( CATID_SafeForInitializing, L"Controls safely initializable from persistent data"))) return ResultFromScode(SELFREG_E_CLASS); if (FAILED( RegisterCLSIDInCategory( _ctlid, CATID_SafeForScripting))) return ResultFromScode(SELFREG_E_CLASS); if (FAILED( RegisterCLSIDInCategory( _ctlid, CATID_SafeForInitializing))) return ResultFromScode(SELFREG_E_CLASS); return NOERROR; }
通常は、次の 2 つの理由から、
DllUnregisterServer
関数を変更しません。他のコントロールがコンポーネント カテゴリを使用している可能性があるため、コンポーネント カテゴリを削除したくない場合があります。
UnRegisterCLSIDInCategory
関数が定義されていますが、既定ではDllUnregisterServer
レジストリからコントロールのエントリを完全に削除します。 そのため、コントロールの登録からカテゴリを削除することはほとんど使用できません。
コントロールをコンパイルして登録すると、レジストリに次のエントリが表示されます。
HKEY_CLASSES_ROOT\Component Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}
HKEY_CLASSES_ROOT\Component Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}
HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}
HKEY_CLASSES_ROOT\CLSID\{"your controls GUID"}\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}
関連情報
インターネット クライアント SDK - コンポーネント開発 - ActiveX コントロールの安全な初期化とスクリプト作成