用C#编写ActiveX控件的一些操作

本文是接红马天下  用C#编写ActiveX控件(二)http://www.cnblogs.com/homer/archive/2005/01/08/88780.html

我做了一个控件里可以调用页面的JS的示例。步骤如下:
1、在HelloWorld项目里添加Com引用。 文件是MSHTML.TLB ,
2、添加一个方法Init
public void InitFCO(object obj)
        
{
            mshtml.HTMLWindow2Class html 
= (mshtml.HTMLWindow2Class)obj;
            html.execScript(
"test();""javascript");
        }

3、页面上的操作是:
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
<SCRIPT LANGUAGE="JavaScript">
<!--
function test()
{
    alert(
"成功了!!!");
}

//-->
</SCRIPT>
</HEAD>

<BODY>
<OBJECT ID="helloworld"  name="helloworld"
WIDTH
="900" HEIGHT="120" 
CLASSID
="CLSID:05B2AE76-0666-4abd-8D68-3E79A67D3F90" 
codebase
="http://10.168.188.5/debug/HelloWorld.dll#Version=5,0,0,0"
align
="baseline"
style
="position:absolute; left:0; top:0; "
VIEWASTEXT
>
    
<SPAN STYLE="color:red">ActiveX 控件下载失败!-- 请检查浏览器的安全设置。<br><br>
                ActiveX control failed to load! -- Please check browser security settings.
</SPAN>
</OBJECT>
<BR><BR><BR><BR><BR><BR><BR>
<input type='button' onclick='helloworld.ShowMessage("Hello World!")' value='Hello World!'> <BR>
<INPUT TYPE="button" onclick='helloworld.InitFCO(window)' value='InitFCO' >
</BODY>
</HTML>


这样就可以实现控件调用JS或VBS了。很方便。

下面讲一下发布的问题:
1、数字签名。使用SignCode.exe进行数字签名,步骤如下:
首先要有工具包,包括以下几个软件:(c:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Tools\Bin目录下都有)
makecert.exe  制作cer格式的证书,即X.509证书,同时可以创建私钥
cert2spc.exe  将cer格式证书转换成spc格式证书,即PKCS #7证书
signcode.exe  将证书签署到ocx上去
chktrust.exe  检查签署证书后的ocx是否正确
还有一个certmgr.exe,是管理证书用的。可以从这里面导出root.cer来,
网上很多文章写到这个证书,但是在VC的安装盘中却找不到。其实,没
有也没关系的。这几个软件可以从VC的安装盘中找到。

下面是具体的步骤:
1、创建一个自己的证书文件:
makecert /sv "Record.PVK" /n "CN=test" test.cer
这里,Record.PVK表示新创建的私人密钥保存文件名
      DreamCaptial是你想显示的公司名
      test.cer是你创建最后的证书文件名
这些根据你自己的要求填写,最后得到Record.PVK和test.cer两个文件。
其中,运行过程中需要输入私人密钥的保护密码,一定要输入一致,不要
出错。

2、转换cer格式为spc格式(可以省略)
cert2spc test.cer test.spc
得到test.spc文件。

3、给ocx进行签名
运行signcode,命令行的我没有试验通过,我是通过界面实现的。
signcode运行后会出现数字签名向导,首先选择你要签名的ocx,
下一步后会出现签名选项,一种是典型,一种是自定义。选择自定义,
这样才能从文件选择证书,选择前面制作的dream.spc,再下一步是
选择私钥文件,选择Record.PVK,输入私人密钥的保护密码,选择散
列算法,一般用md5就可以了,下一步是选择其他证书,直接下一步,
填写一下这个控件的声明,用户用ie浏览的时候,会弹出证书说明,
再下一步是加盖时间戳,如果需要,用以下地址:
http://timestamp.verisign.com/scripts/timstamp.dll
要求已经上网并能出国,然后直接下一步就完成了。

4、用chktrust检查是否正确
chktrust -v RecordProj.ocx

就这样,得到了一个测试证书,恩,虽然只是一个测试证书,但至
少保证这个ocx在ie浏览的时候能够弹出来一个窗口,问你是否安装,
而不是直接禁止了。

增加控件的事件

Handling Events

      The last hurdle is to add event notifications to my Windows Forms control, so that it can inform its container when downloading has started, stopped, or aborted due to an internal error.
      In the COM/ActiveX world, you add events by defining an event interface (also called a source interface). Controls that want to throw these events implement the interface, and their callers sink the interface—to register themselves as event handlers—using the Advise method of the IConnectionPoint corresponding to the control's default source interface. Regular .NET classes simplify this task greatly. Events no longer need to be grouped into interfaces, and listeners are provided for individual events using a type-safe function pointer called a delegate.
      As of version 6.0, Internet Explorer provides no seamless translation between these two mechanisms. The best you can do is to use COM Interoperability to define a default source interface. Internet Explorer will sink a control's default source interface and expose event handlers through an IDispatch interface based on a dispid assigned to the events. This requires you to define, COM-style, an interface that implements the events:

[Guid("A59B958D-B363-454b-88AA-BE8626A131FB")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IMultiUploadCtrlCOMEvents
{
    [DispId(0x60020000)]
    void UploadComplete();

    [DispId(0x60020001)]
    void BeginUpload();
}

      It also requires you to define all of the control's public methods and properties on a separate interface, otherwise, Internet Explorer will attempt to resolve all method and property calls made by script against the source interface, with obvious bad consequences.

public interface IMultiUploadCtrlCOMIncoming
{
    void UploadFiles();
    bool FilesPending {get;}
    int MaxSessionUpload {get; set; }
    int BytesUploaded {get;}
    string FileUploadURL {get; set; }
}

From there, you define and raise an event just as you would any regular .NET event. To sink, you must use the DHTML <SCRIPT> tag with the FOR attribute:

<SCRIPT FOR="upload1" EVENT="BeginUpload">
    window.status = "Uploading files...please wait";
</SCRIPT>

<SCRIPT FOR="upload1" EVENT="UploadComplete">
    window.alert("Upload complete");
    window.status = "";
</SCRIPT>

Hence the reason for requiring unmanaged code execution permissions for my control: when I raise an event, I am calling unmanaged listeners written in JScript or VBScript.

posted @ 2005-01-16 13:50  小草  阅读(7920)  评论(0编辑  收藏
Google+