首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++Builder ActiveX 控制項:設定「安全給指令碼」與「安全初始化」完整步驟

     編輯:關於C++

問題背景

在 C++Builder (BCB) 開發 ActiveX 控制項 (OCX) 並嵌入網頁時,Internet Explorer 預設會阻擋未標記為「安全給指令碼」與「安全初始化」的控制項,導致腳本無法存取控制項屬性/方法,或控制項無法載入。本文說明如何在 ATL 專案中透過 元件類別對應 (Category Map) 宣告這兩項安全類別,使控制項通過 IE 安全性檢查。

核心解決方案:實作元件類別對應

在控制項實作類別 (通常命名為 TxxxImpl) 內部,於 BEGIN_COM_MAP 之後、BEGIN_PROPERTY_MAP 之前加入以下巨集區塊:


// 安全類別宣告區塊
BEGIN_CATEGORY_MAP(TYourControlImpl)
    IMPLEMENTED_CATEGORY(CATID_SafeForScripting)      // 安全給指令碼
    IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)   // 安全初始化
END_CATEGORY_MAP()

完整類別定義範例


class ATL_NO_VTABLE TSignActiveFormXImpl :
    public VCLCONTROL_IMPL(TSignActiveFormXImpl, SignActiveFormX, TSignActiveFormX, ISignActiveFormX, DIID_ISignActiveFormXEvents)
{
    // ... 事件處理函數宣告 ...
    void __fastcall ActivateEvent(TObject *Sender);
    // ... 其他事件 ...

public:
    void InitializeControl()
    {
        m_VclCtl->OnActivate = ActivateEvent;
        m_VclCtl->OnClick = ClickEvent;
        // ... 綁定其他事件 ...
    }

    // COM 介面對應表
    BEGIN_COM_MAP(TSignActiveFormXImpl)
        VCL_CONTROL_COM_INTERFACE_ENTRIES(ISignActiveFormX)
    END_COM_MAP()

    // ★ 關鍵:安全類別宣告 ★
    BEGIN_CATEGORY_MAP(TSignActiveFormXImpl)
        IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
        IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)
    END_CATEGORY_MAP()

    // 屬性對應表
    BEGIN_PROPERTY_MAP(TSignActiveFormXImpl)
        // PROP_PAGE(CLSID_SignActiveFormXPage)
    END_PROPERTY_MAP()

    // VCL 控制項持久化宣告
    DECLARE_VCL_CONTROL_PERSISTENCE(TSignActiveFormXImpl, TSignActiveFormX);

    // ActiveX 控制項註冊資訊
    DECLARE_ACTIVEXCONTROL_REGISTRY("SignActiveFormProj1.SignActiveFormX", 1);

protected:
    // ... 介面方法宣告 (STDMETHOD) ...
    STDMETHOD(get_SignStr(BSTR* Value));
    STDMETHOD(set_SignStr(BSTR Value));
    STDMETHOD(test(BSTR str));
    // ... 其他方法 ...
};

原理說明

  • CATID_SafeForScripting:宣告控制項可被腳本 (JavaScript/VBScript) 安全呼叫,不會執行危險操作 (如存取檔案系統、登錄表等)。
  • CATID_SafeForInitializing:宣告控制項可透過 IPersistPropertyBag::InitNew 或 IPersistStreamInit::InitNew 安全初始化,不會因惡意參數導致系統損害。
  • 這兩個 CATID 定義於 <olectl.h>,對應 GUID 分別為:
    • CATID_SafeForScripting: {7DD95801-9882-11CF-9FA9-00AA006C42C4}
    • CATID_SafeForInitializing: {7DD95802-9882-11CF-9FA9-00AA006C42C4}
  • 註冊控制項時 (regsvr32),ATL 會自動在登錄表 HKCR\CLSID\{YourCLSID}\Implemented Categories 下建立這兩個類別的子鍵,IE 掃描到即視為安全。

驗證方法

  1. 編譯專案產生 .ocx。
  2. 以系統管理員身分執行 regsvr32 YourControl.ocx 註冊。
  3. 開啟 regedit,檢查 HKEY_CLASSES_ROOT\CLSID\{YourControlCLSID}\Implemented Categories 下是否存在上述兩個 GUID 子鍵。
  4. 建立測試 HTML 頁面,使用 <object classid="clsid:YourCLSID"></object> 嵌入控制項,並嘗試用 JavaScript 呼叫方法/存取屬性。

常見問題與注意事項

問題原因與解決
仍被 IE 阻擋確認專案設定 「啟用 ActiveX 控制項安全性」;清除 IE 快取;檢查登錄表類別是否正確寫入。
簽署控制項企業環境建議使用 signcode 或 SignTool 為 .ocx 加上數位簽章,並透過群組原則信任發行者,徹底解決安全提示。
VCL 控制項特有BCB 產生的 ActiveForm 專案預設不含 Category Map,需手動加入。若專案遷移至 BCB 4.0 以上,注意 DECLARE_VCL_CONTROL_PERSISTENCE 巨集相容性。

總結

在 C++Builder ATL ActiveX 專案中,只需在控制項實作類別加入 BEGIN_CATEGORY_MAP 區塊並宣告 CATID_SafeForScripting、CATID_SafeForInitializing 兩個巨集,重新編譯註冊即可讓控制項在 IE 中正常被腳本存取與初始化。這是發布網頁嵌入式 ActiveX 控制項的必要步驟。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved