用VB调用C#写的NET控件.doc

上传人:hw****26 文档编号:3116352 上传时间:2019-05-21 格式:DOC 页数:16 大小:316KB
下载 相关 举报
用VB调用C#写的NET控件.doc_第1页
第1页 / 共16页
用VB调用C#写的NET控件.doc_第2页
第2页 / 共16页
用VB调用C#写的NET控件.doc_第3页
第3页 / 共16页
用VB调用C#写的NET控件.doc_第4页
第4页 / 共16页
用VB调用C#写的NET控件.doc_第5页
第5页 / 共16页
点击查看更多>>
资源描述

1、 虽然 IT 开发技术日新月异,不过业界仍然运行着大量的 VB 系统,这些系统凝聚了不少客户的投资,应当要一定程度的保护和利用。因此也就产生了一种 需求,也就是使用旧的开发技术仍然可以使用新技术的产出。本文就讨论如何在 VB6.0 开发中使用上 WinForm.NET 控件。袁永福版权所有二软件原理:运行 VB IDE,打开或创建一个 EXE 工程,打开窗体设计器,如下图所示:为了能在窗体上添加控件,需要往窗体左边的工具箱上添加项目,需要点击菜单项目“Project-Components”,此时会弹出如下图所示的对话框: 点击“Browse”按钮,弹出文件选择对话框,这个对话框中优先选择 OC

2、X文件,而 C#编译结果绝不可能是 OCX 文件的,此时即使选择一 个.NET 程序集DLL 文件,无论如何必然会报错“This file not registerable as an ActiveX Component”。袁永福版权所有因此也就是说,使用 C#开发的 WinForm.NET 控件是不可能直接通过传统的模式放置在 VB 窗体上。不过 VB 仍然可以通过 COM 方式调用.NET 程序集中的对 COM 公开的类型。此时就可以想出一种曲线实现方式,那就是 VB 创建 C#组件,该组件 是一个WinForm.NET 控件,然后调用 Win32API SetParent 函数,将 Wi

3、nForm.NET 控件硬塞入 VB 窗体中。这样在用户界面上,用户能看到和使用 WinForm.NET 控件;在后台,VB 代码能访问.NET 组件提供的公开的属性、方法和事件,实现了 VB全方位的调用 WinForm.NET 控件。 三C#开发C#控件开发根据上述的软件原理,笔者开发一个 WinForm.NET 控件并成功的应用于VB6.0 的开发中,现对软件进行说明。这个 WinForm.NET 控件名为 MyWinFormControl,派生自 System.Windows.Forms.UserControl 类型,它包含在一个名为DCWinFormControlLib 的 C#项目中

4、,项目输 出类型为类库,目标框架为.NET2.0,添加了对 System.Windows.Forms.dll 的引用。界面设计:MyWinFormControl 控件的用户界面设计如下: 在界面上放置一个名为“btnAction”的按钮,一个名为“myTextBox”的文本框。定义公开属性和方法:打开该控件的 C#代码文件,可以看到声明该类型的 C#代码如下:System.Runtime.InteropServices.ComVisible(true)System.Runtime.InteropServices.Guid(“60550064-C97F-4306-A8B2-6908F50780E

5、3“)System.Runtime.InteropServices.ComSourceInterfaces(typeof(IComMyEvent)public partial class MyWinFormControl : UserControl这段代码中,第一行代码的 ComVisible 标记类型为 COM 公开的;第二行代码 Guid 标记了类型在 COM 中的唯一编号;第三行代码的 ComSourceInterfaces指明该类型实现了名为 IComMyEvent 的事件接口。袁永福版权所有VB 中无法直接绑定编译阶段未知的控件事件,同时也无法直接感应 C#中的事件,为此需要编写一个

6、接口通知 VB 存在若干事件,使得 VB 能绑定事件。因此在此定义了 IComMyEvent 接口,声明了 C#控件中的事件,IComMyEvent 接口定义如下using System.Runtime.InteropServices;Guid(“096EF9A6-24CB-4091-A18F-34DA38C9A6F1“)ComVisible( true )InterfaceType( ComInterfaceType.InterfaceIsIDispatch )public interface IComMyEvent/ / 按钮按下事件/ DispId(12340)void ComButto

7、nClick();/ / 文本内容修改事件 t/ DispId(12350)void ComTextChanged();/ / 无参数无返回值委托类型/ public delegate void VoidEventHandler();而后在控件的 C#代码中添加以下代码:#region 实现 IComMyEvent 中的成员/ / 按钮按下事件/ public event VoidEventHandler ComButtonClick = null;/ / 文本内容修改事件/ public event VoidEventHandler ComTextChanged = null;#endreg

8、ion这样 C#中定义的事件在 VB 中就能绑定了,以下代码就是触发这些事件的:private void btnAction_Click(object sender, EventArgs e)if (ComButtonClick != null)/ 触发 ComButtonClick 事件ComButtonClick();private void myTextBox_TextChanged(object sender, EventArgs e)if (ComTextChanged != null)/ 触发 ComTextChanged 事件ComTextChanged();对控件实现了 COM

9、 公开的事件后,就可以编写 COM 公开的属性和方法,其代码如下:/ / 公开的属性/ public string UserTextgetreturn myTextBox.Text;setmyTextBox.Text = value;/ / 公开的方法/ public double Calcute(double p)return Math.Sin(p);这个用户控件虽然能在 VB 代码中创建和访问,但还不能直接拖放到 VB 窗体上,此时还需要使用代码将 C#控件添加到 VB 窗体上:/ / 将控件添加到指定句柄的窗体中/ / 指定的窗体句柄对象/ 操作是否成功public bool Appen

10、dToContainerControl(int containerHandle)CrossPlatformControlHostManager man = new CrossPlatformControlHostManager();man.ContainerHandle = new IntPtr(containerHandle);man.ControlHandle = this.Handle;man.Dock = this.Dock;return man.UpdateLayout();在这个函数中,参数为 VB 窗体中某个控件的句柄,该控件用于承载 C#控件。这段代码使用了笔者编写的一个 Cr

11、ossPlatformControlHostManager 类型,该类型专业用于执行跨应用程序的控件承载,实现“乾坤大挪移”,该类型首先定义了 几个属性:袁永福版权所有private IntPtr _ControlHandle = IntPtr.Zero;/ / 操作的控件句柄对象/ public IntPtr ControlHandleget return _ControlHandle; set _ControlHandle = value; private IntPtr _ContainerHandle = IntPtr.Zero;/ / 容器元素对象/ public IntPtr Con

12、tainerHandleget return _ContainerHandle; set _ContainerHandle = value; private DockStyle _Dock = DockStyle.Fill;/ / 停靠样式/ public DockStyle Dockget return _Dock; set _Dock = value; 此外还定义了一个方法,其代码如下:/ / 更新排版/ / 操作是否成功public bool UpdateLayout()WindowInformation info = new WindowInformation(this.Control

13、Handle);WindowInformation container = new WindowInformation(this.ContainerHandle);if (info.CheckHandle() = false| container.CheckHandle() = false)return false;if (info.ParentHandle != container.Handle)if (info.SetParent(container.Handle) = false)return false;Rectangle clientRect = container.ClientBo

14、unds;Rectangle bounds = info.Bounds;Rectangle descBounds = bounds;switch (this.Dock)case DockStyle.Fill:descBounds = clientRect;break;case DockStyle.Bottom:descBounds = new Rectangle(0,clientRect.Height - bounds.Height, clientRect.Width,bounds.Height);break;case DockStyle.Left:descBounds = new Recta

15、ngle(0,0,bounds.Width, clientRect.Height);break;case DockStyle.Right:descBounds = new Rectangle(clientRect.Width - bounds.Width,0,bounds.Width,clientRect.Height);break;case DockStyle.Top:descBounds = new Rectangle(0,0,clientRect.Width,bounds.Height);break;if (descBounds != bounds)info.Bounds = descB

16、ounds;return true;这段代码中,用到了一个 WindowInformation 的类型,这个笔者编写的另外一个类型,实现了一些窗体相关的 Win32API 的封装。在 UpdateLayout 中,首先判断双方的窗体句柄是否有效,然后判断两个窗体控件的父子关系,若不是则设置控件的父子关系,底层调用的是 Win32API 函数 SetParent。袁永福版权所有然后根据对象的 Dock 属性值和父控件的客户区大小来计算出子控件应有的位置和大小,然后设置子控件的位置和大小。这样这个控件本身开发完毕了。设置程序集另外还需要对 C#项目进行一些设置来完成公开 COM 开发接口的工作。打

17、开工程文件中的 AssemblyInfo.cs 文件,该文件默认在 Properties 目录下,设置其代码内容为:using System.Reflection;using System.Runtime.CompilerServices;using System.Runtime.InteropServices;/ 有关程序集的常规信息通过以下/ 特性集控制。更改这些特性值可修改/ 与程序集关联的信息。assembly: AssemblyTitle(“袁永福的 COM 测试“)assembly: AssemblyDescription(“)assembly: AssemblyConfigura

18、tion(“)assembly: AssemblyCompany(“)assembly: AssemblyProduct(“DCWinFormControlLib“)assembly: AssemblyCopyright(“Copyright 2012“)assembly: AssemblyTrademark(“)assembly: AssemblyCulture(“)/ 将 ComVisible 设置为 false 使此程序集中的类型/ 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,/ 则将该类型上的 ComVisible 特性设置为 true。assembly: Com

19、Visible(true)/ 如果此项目向 COM 公开,则下列 GUID 用于类型库的 IDassembly: Guid(“c241537f-dfe8-4502-b43a-967f9437ee7c“)assembly: AssemblyVersion(“1.0.0.*“)这段代码中,重点之一是“ComVisible”,这是程序集允许向 COM 公开;还有一个“Guid”,这是为类型库提供一个编号;还有 “AssemblyVersion”设置程序集的版本号,这里有一个*表示这个版本号是累计的,袁永福版权所有每次编译生成的程序集的版本号都会增加 的。强名称要提供 COM 开发接口,.NET 程序

20、集必须是强名称的。要对.NET 程序集强名称,首先是要有一个 SNK 签名文件,若没有,则可以使用.NET SDK 中的 SN.EXE 工具生成一个 SNK 文件。打开 VS.NET 自带的.NET SDK 命令行界面,执行命令行“SN.EXE k d:dctest.snk”,即可生成一个强名称使用的 SNK 文件。则命令行输出文本为:Microsoft(R) .NET Framework 强名称实用工具 版本 4.0.30319.1版权所有(C) Microsoft Corporation。保留所有权利。密钥对写入到 d:dctest.snk在 VS.NET 中打开项目的属性页面,切换到“签名”页面,如下图所示:

展开阅读全文
相关资源
相关搜索
资源标签

当前位置:首页 > 教育教学资料库 > 精品笔记

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。