閱讀957 返回首頁    go 阿裏雲 go 技術社區[雲棲]


C#實現vb6和html都可以調用的ActiveX,

新建控件庫 項目,AssemblyInfo.cs 修改為
程序代碼 程序代碼
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;

// 有關程序集的常規信息通過下列屬性集
// 控製。更改這些屬性值可修改
// 與程序集關聯的信息。
[assembly: AssemblyTitle("ORRSG")]
[assembly: AssemblyDescription("ActiveX控件")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("麥殼餅小屋")]
[assembly: AssemblyProduct("ORRActiveX")]
[assembly: AssemblyCopyright("版權所有 (C) MysticBoy Limited 2007")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: AllowPartiallyTrustedCallers()]
// 將 ComVisible 設置為 false 使此程序集中的類型
// 對 COM 組件不可見。如果需要從 COM 訪問此程序集中的類型,
// 則將該類型上的 ComVisible 屬性設置為 true。
[assembly: ComVisible(true )]

// 如果此項目向 COM 公開,則下列 GUID 用於類型庫的 ID
[assembly: Guid("f49a066c-1a61-4d05-8041-cb6948a85f72")]
  

// 程序集的版本信息由下麵四個值組成:
//
//      主版本
//      次版本
//      內部版本號
//      修訂號
//
// 可以指定所有這些值,也可以使用“修訂號”和“內部版本號”的默認值,
// 方法是按如下所示使用“*”:
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyFileVersion("1.0.0.0")]



新建一個接口 名為 IObjectSafety
添加
using System.Runtime.InteropServices;

/// <summary>
/// 這個guid不要更改
/// </summary>
[Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsDual)]

public interface IObjectSafety
{
    //    
    /// <summary>
    ///
    /// </summary>
    /// <param name="riid"></param>
    /// <param name="pdwSupportedOptions"></param>
    /// <param name="pdwEnabledOptions"></param>
    void GetInterfacceSafyOptions(
       System.Int32 riid,
       out System.Int32 pdwSupportedOptions,
       out System.Int32 pdwEnabledOptions);
    /// <summary>
    ///
    /// </summary>
    /// <param name="riid"></param>
    /// <param name="dwOptionsSetMask"></param>
    /// <param name="dwEnabledOptions"></param>
    void SetInterfaceSafetyOptions(
       System.Int32 riid,
       System.Int32 dwOptionsSetMask,
       System.Int32 dwEnabledOptions);
  

}



新建一個控件
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;

namespace orRActiveX
{

    /// <summary>
    /// 用戶控件。
    /// </summary>
    [ProgId("ORRActiveX.ORRShowGlass")] //我們的控件名
    [Guid("E6DB4C0C-4B29-4806-89B5-17DE7BB79C54")] //guid.
    [ClassInterface(ClassInterfaceType.AutoDual)] //必須的,否則你無法調用 。
    public partial class orRShowGlass : UserControl, IObjectSafety //集成用戶控件和安全接口。  
    {
    
        /// <summary>
        /// 設置父對象。
        /// </summary>
        /// <param name="hWndChild">在這裏應該是本窗體本身</param>
        /// <param name="hWndNewParent">要顯示該窗體的對象。 </param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        private static extern int SetParent(IntPtr hWndChild, int hWndNewParent);

    

        /// <summary>
        ///
        /// </summary>
        public orRShowGlass()
        {
            InitializeComponent();
        }
        ///<summary>
        ///</summary>
        public  void LoadMe(Int32 hWnd)
        {
            SetParent(this.Handle, hWnd);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="top"></param>
        /// <param name="left"></param>
        public void SetLoc(Int32 top, Int32 left)
        {
            Left = left;
            Top = top;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        //[ComEventInterface() ]
        public void SetSize(Int32 width, Int32 height)
        {
            Width = width;
            Height = height;
        }

        ///<summary>
        /// 注冊函數,假如你能實現標準dll的方式的話,我們就可以做到完全的標準ocx了。
        ///</summary>
        ///<param name="key">鍵值,這個是注冊時,注冊程序給程序傳的。 </param>
        [ComRegisterFunction()]
        public static void RegisterClass(string key)
        {
            // 去掉這個, 我們不需要他 HKEY_CLASSES_ROOT/
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT/", "");
            // 打開 CLSID/{guid}
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
            // 創建'Control'鍵
            //ActiveX 控件容器
            RegistryKey ctrl = k.CreateSubKey("Control");
            ctrl.Close();
            // 創建CodeBase入口,- 這裏是必須的.
            RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
            inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
            inprocServer32.Close();
            k.Close();
        }

        ///    <summary>
        ///    調用反注冊控件
        ///    </summary>
        ///    <param name="key">Tke registry key</param>
        [ComUnregisterFunction()]
        public static void UnregisterClass(string key)
        {
            StringBuilder sb = new StringBuilder(key);
            sb.Replace(@"HKEY_CLASSES_ROOT/", "");

            // 打開HKCR/CLSID/{guid}
            RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
            // 刪除'Control'如果不存在,不要拋出錯誤
            k.DeleteSubKey("Control", false);
            // 下一步,打開InprocServer32
            k.OpenSubKey("InprocServer32", true);
            //刪除 CodeBase鍵,如果不存在,不要拋出錯誤
            k.DeleteSubKey("CodeBase", false);
            k.Close();
        }

        #region 為 html調用提供的接口。 IObjectSafety

        /// <summary>
        ///
        /// </summary>
        /// <param name="riid"></param>
        /// <param name="pdwSupportedOptions"></param>
        /// <param name="pdwEnabledOptions"></param>
        void IObjectSafety.GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
        {
            pdwSupportedOptions = 1;
            pdwEnabledOptions = 2;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="riid"></param>
        /// <param name="dwOptionsSetMask"></param>
        /// <param name="dwEnabledOptions"></param>
        void IObjectSafety.SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
        {
        }

        #endregion
    }
}


然後需要給程序集添上 簽名 。 在項目屬性中的 生成菜單中選擇 為 com  Interop 注冊 .


要在html中使用 使用下麵的方法。
<body >  
<object   
   class >  
</object>  
</body>
classid 是程序中的控件前麵的guid中的內容。
在vb6中調用時先引用生成的 tlb文件,和你的項目名相同。  
程序中可以使用下麵的方法。



Dim x As New orRShowGlass.ORRShowGlass


Private Sub Form_Load()
x.LoadMe hWnd
' x.SetLoc 1, 1 使用這個也可以
x.Top = 0
x.Left = 0
x.Width = Me.Width / 15
x.Height = Me.Height / 15
x.Refresh
End Sub

Private Sub Form_Resize()
x.Top = 0
x.Left = 0
x.Width = Me.Width / 15
x.Height = Me.Height / 15
x.Refresh
End Sub

InteropFormTools中有更好的實現。
建議采用InteropFormTools,但是他是vb代碼的。 c#的目前沒有,因為InteropFormTools是微軟為vb用戶做的!


 

最後更新:2017-04-02 00:06:23

  上一篇:go Lotus 8.0基於Eclipse平台,IBM的產品線都向Eclipse靠緊了?
  下一篇:go HHP格式解析!