• C#下OCX控件的完美使用


    C#下OCX控件的完美使用

    上一篇C#下COM组件调用篇中,我当时没有把OCX的使用方法说清楚,主要原因是我那时有一个核心问题没有解决好,后来在CodeProject中看到一篇文章,一下解开了心中多年的疑惑,豁然开朗。在这里分享一下最新的研究成果。
    ocx解决方案图

    OCX使用的关键问题点

    其实OCX使用中,有两个关键点需要解决:

    • 1、如何获取到AxInterop文件
    • 2、Visual Studio 设计Form时,可以在工具箱位置找到OCX控件,且使用我们自己的Axinterop。

    只要大家亲身使用过OCX控件就会有体会,以前我都是直接在工具箱里面点击添加项,然后选COM页签,找到我想要的控件,最后选中确认。此时VS会进行一连串的TlbImp和AxImp操作,然后给你自动生成一大堆的Interop和AxInterop,简直是自动的不要不要的。但是以前文章中说过的COM Interop 拖家带口问题和ADODB问题,会造成你的项目引用非常混乱,2008系统会各种报错。
    加之U8的COM组件和OCX控件引用关键错终复杂,搞得我最后一听说要画控件在Form上就恶心。我也在网络上找了很多资料,不管是国内的还是国外的论坛,基本回答都是手工使用AxImp加上rcw参数,解决引用问题。然后都不说怎么在VS的工具箱里增加控件。后来我测试发现,rcw参数也解决不了ADODB错误。我也就没有在深入研究下去。有兴趣的可以看看我之前的文章,rcw参数和TlbImp的reference参数差不多。

    OCX止吐关键技术

    AxInterop引用关系解决

    第一个问题,AxInterop引用错误问题,还是建议使用IL工具进行编译修改。如果不会或者不明白看我之前的COM使用技巧第二章。换言之,我们必须先得到一个已经解决了引用关系的Axinterop。

    VS工具箱引用解决

    VS工具箱引用问题,其实并不难,这里仅仅需要使用到AxImp工具的一个参数,直接给大家看一下命令行

    C:ax>aximp /source "c:u8softufcomsqlvsflex8u.ocx"
    生成的源: C:axAxVSFlex8U.cs
    生成的程序集: C:axVSFlex8U.dll
    生成的程序集: C:axAxVSFlex8U.dll
    
    

    简单说,我们这里利用aximp的一个叫做srource的参数,搞出来一个C#版本的源码文件,引入项目,并通过修改这个文件的代码就可以让控件显示在工具箱里面了。
    这里有一点,需格外强调一下,我们虽然这里使用了aximp,但是他生成的其他文件我们都不用,比如后面两个DLL文件,或者说,就唯独使用那个cs源码文件。下面看看这个刚刚生成出来的CS文件,热乎的时候是什么样子,记住此时他是不正确的,需要进行下一步修改才可以。

    //------------------------------------------------------------------------------
    // <auto-generated>
    //     此代码由工具生成。
    //     运行时版本:4.0.30319.42000
    //
    //     对此文件的更改可能会导致不正确的行为,并且如果
    //     重新生成代码,这些更改将会丢失。
    // </auto-generated>
    //------------------------------------------------------------------------------
    [assembly: System.Reflection.AssemblyVersion("1.0.0.0")]
    [assembly: System.Windows.Forms.AxHost.TypeLibraryTimeStamp("09/30/2011 10:57:06")]
    namespace AxVSFlex8U {
        [System.Windows.Forms.AxHost.ClsidAttribute("{3705b4e2-8fcb-4a21-8cce-5d6a98c32456}")]
        [System.ComponentModel.DesignTimeVisibleAttribute(true)]
        [System.ComponentModel.DefaultEvent("SelChange")]
        [System.ComponentModel.DefaultProperty("Text")]
        public class AxVSFlexGrid : System.Windows.Forms.AxHost {
            private VSFlex8U.IVSFlexGrid ocx;
            private AxVSFlexGridEventMulticaster eventMulticaster;
            private System.Windows.Forms.AxHost.ConnectionPointCookie cookie;
            private msdatasrc.DataSource axDataSource;
            public AxVSFlexGrid() :
                    base("3705b4e2-8fcb-4a21-8cce-5d6a98c32456") {
                this.SetAboutBoxDelegate(new AboutBoxDelegate(About));
            }
            '后面代码一律省略,毛用没有,没必要看!!!
    
    
    代码修改1

    注意看这个文件的几个地方,第一个就是版本号,在上文的11行

    [assembly: System.Reflection.AssemblyVersion("1.0.0.0")]
    
    

    这行代码必须删除,放在这里就是报错用的。

    代码修改2
    namespace AxVSFlex8U {
    
    

    命名空间必须修改成你的项目中的命名空间

    代码修改3
    '必须增加ToolboxItem参数
    [System.ComponentModel.ToolboxItem(true)]
     public class AxVSFlexGrid : System.Windows.Forms.AxHost {
    
    

    这个非常非常重要,就因为有了这个才真正让VS识别出来是控件类。

    代码修改4

    最后添加 MSACAL.dll 和 Stdole.dll 两个引用,一般情况下VS会提示你的。

    最后我们看一下完美解决后的文件

    '删除垃圾代码
    [assembly: System.Windows.Forms.AxHost.TypeLibraryTimeStamp("09/30/2011 10:57:06")]
    namespace WindowsFormsApp1 '命名空间修改
    {
        [System.Windows.Forms.AxHost.ClsidAttribute("{3705b4e2-8fcb-4a21-8cce-5d6a98c32456}")]
        [System.ComponentModel.DesignTimeVisibleAttribute(true)]
        [System.ComponentModel.DefaultEvent("SelChange")]
        [System.ComponentModel.DefaultProperty("Text")]
        [System.ComponentModel.ToolboxItem(true)] '属性增加
        public class AxVSFlexGrid : System.Windows.Forms.AxHost {
    
    

    然后试着编译一下程序,用X86编译你的项目,64的编译后不能拖拽控件,去设计一下窗体,看看工具箱里面是不是出现了一个叫做AxVSFlexGrid的控件了,然后拖拽控件进入Form,版权提示后,就有一个美丽的控件嵌入Form中了。是不是很神奇!

    劳动成果的复用

    到此OCX问题完美解决了。如果你想让劳动成果最大化复用,并为后期的项目使用,完全可以把这个项目编译成类库,然后供给其他项目引用。我测试后发现是好用的,关键点在于需要到工具箱里面增加引用,如图
    OCX引用第一步
    OCX引用第二部
    然后就可以正常拖拽控件进入Form了,使用过程非常简单,记住你的项目必须X86。
    也就是说如果你愿意,可以把所有常用的控件都封装到一个DLL中,然后引用后直接使用,这操作简直666,比VB6引用控件方便太多了。

    大家有任何问题,可以在博客中留言,我会在平时进行回复。

  • 相关阅读:
    函数的对称性及其图像变换
    KMP 字符串匹配
    15 保护模式中的特权级(上)
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    2-26安卓自学
  • 原文地址:https://www.cnblogs.com/lothar/p/13335191.html
Copyright © 2020-2023  润新知