转:http://www.codeproject.com/cs/miscctrl/exposingdotnetcontrols.asp?df=100&forumid=2373&exp=0&select=1359005

  • Download demo project - 15 Kb

This article will describe how to utilise Windows Forms controls outside of .NET. In a recent MSDN magazine article on .NET Interop available here, various ways of exposing .NET objects to 'legacy' environments are discussed, including the exposure of Windows Forms controls as ActiveX controls.

The problem is that the goalposts have moved since the article was written as Beta 2 is now available, and unfortunately this support has been removed - see this posting on the .NET list at http://discuss.develop.com.

The following image shows a control, written purely within .NET, hosted within an ActiveX control container - in this instance tstcon32.exe.

As Beta1 supported this facility, and being somewhat inquisitive, I decided to see if I could find a way to expose controls anyway. The attached project creates the 'Prisoner' control, which won't set the world on fire but does show the main things you need to do in order to get a .NET control up & running within VB6.

CAVEAT: As this support has been dropped from Beta2 of .NET, don't blame me if it fries your PC or toasts the cat.

Now that's out of the way, how's it done?.

Writing the control

  1. Create a new control project from within Visual Studio - my examples are all in C# but VB.NET could also be used.
  2. Add controls etc to the form, put in the code etc.
  3. Add in the following using clauses...
    using System.Runtime.InteropServices;using System.Text;using System.Reflection;using Microsoft.Win32;
  4. Attribute your class so that it gets a ProgID. This isn't strictly necessary as one will be generated, but it's almost always best to be explicit.
    [ProgId("Prisoner.PrisonerControl")][ClassInterface(ClassInterfaceType.AutoDual)]

    This assigns the ProgID, and also defines that the interface exposed should be 'AutoDual' - this crufts up a default interface for you from all public, non-static members of the class. If this isn't what you want, use one of the other options.

  5. Update the project properties so that your assembly is registered for COM interop.

    If you're using VB.NET, you also need a strong named assembly. Curiously in C# you don't - and it seems to be a feature of the environment rather than a feature of the compiler or CLR.

  6. Add the following two methods into your class.
    Collapse
    [ComRegisterFunction()]public static void RegisterClass ( string key ){// Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need itStringBuilder sb = new StringBuilder ( key ) ;sb.Replace(@"HKEY_CLASSES_ROOT\","") ;// Open the CLSID\{guid} key for write accessRegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);// And create the 'Control' key - this allows it to show up in // the ActiveX control container RegistryKey ctrl = k.CreateSubKey ( "Control" ) ;ctrl.Close ( ) ;// Next create the CodeBase entry - needed if not string named and GACced.RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true ) ;inprocServer32.SetValue ( "CodeBase" , Assembly.GetExecutingAssembly().CodeBase ) ;inprocServer32.Close ( ) ;// Finally close the main keyk.Close ( ) ;}

    The RegisterClass function is attributed with ComRegisterFunction - this static method will be called when the assembly is registered for COM Interop. All I do here is add the 'Control' keyword to the registry, plus add in the CodeBase entry.

    CodeBase is interesting - not only for .NET controls. It defines a URL path to where the code can be found, which could be an assembly on disk as in this instance, or a remote assembly on a web server somewhere. When the runtime attempts to create the control, it will probe this URL and download the control as necessary. This is very useful when testing .NET components, as the usual caveat of residing in the same directory (etc) as the .EXE does not apply.

    [ComUnregisterFunction()]public static void UnregisterClass ( string key ){StringBuilder sb = new StringBuilder ( key ) ;sb.Replace(@"HKEY_CLASSES_ROOT\","") ;// Open HKCR\CLSID\{guid} for write accessRegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(),true);// Delete the 'Control' key, but don't throw an exception if it does not existk.DeleteSubKey ( "Control" , false ) ;// Next open up InprocServer32RegistryKey inprocServer32 = k.OpenSubKey ( "InprocServer32" , true ) ;// And delete the CodeBase key, again not throwing if missing k.DeleteSubKey ( "CodeBase" , false ) ;// Finally close the main key k.Close ( ) ;}

    The second function will remove the registry entries added when (if) the class is unregistered - it's always a good suggestion to tidy up as you go.

Now you are ready to compile & test your control.

Testing the Control

For this example I have chosen tstcon32.exe, which is available with the installation of .NET. The main reason I've used this rather than VB6 is that I don't have VB6 anymore.

Inserting the Control

First up you need to insert your control, so to do that choose Edit -> Insert New Control, and choose your control from the dropdown...

This will result in a display as shown at the top of the article, if you're following along with my example code.

Testing Methods

The example control only includes one method, 'Question'. To test this within TstCon32, choose Control -> InvokeMethods from the menu, and select the method you want to call. Note that because I defined the interface as AutoDual, I get gazillions of methods. If you implement an interface and expose this as the default interface then the list of methods will be more manageable.

Click on the 'Invoke' button will execute the method, which in this instance displays the obligatory message box.

Wrap Up

Dropping support for creating ActiveX controls from Windows Forms controls is a pain, and one decision I wish Microsoft had not made.

This article presents one way of exposing .NET controls as ActiveX controls, and seems to work OK. Having said that, I've not exhaustively tested this and who knows what bugs might be lurking in there. I haven't delved into events yet, nor property change notifications, so there's some fun to be had there if you like that sort of thing.

The .NET framework truly is the best thing since sliced bread, but the lack of support for creating ActiveX controls from Windows Forms controls is inconvenient. There are many applications out there (ours included) which can be extended with ActiveX controls. It would be nice given the rest of the support in the framework to be able to expose Windows Forms controls to ActiveX containers, and maybe someday the support will be available.

About Morgan Skinner

Now working in Microsoft Developer Services, based in the UK.

I loved .NET so much I had to join the company!.

Click here to view Morgan Skinner's online profile.

Exposing Windows Forms Controls as ActiveX controls相关推荐

  1. System.Windows.Forms.DataVisualization.Charting.Chart

    //创建圖形式的ChartSystem.Windows.Forms.DataVisualization.Charting.Chart chart1 = new System.Windows.Forms ...

  2. ystem.Windows.Forms.SplitContainer : ContainerControl, ISupportInitialize

    1 #region 程序集 System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e08 ...

  3. c#使用System.Windows.Forms.DataVisualization.Charting.dll绘制图表实例

    首先下载System.Windows.Forms.DataVisualization.Charting.dll,然后引用到项目中 手动在代码中创建chart类型并将其添加到某个控件中(control. ...

  4. System.Windows.Forms.ListView

    呈现一个 Windows 列表视图控件,并且能够以四种不同的视图中的任何一种来显示一个子项集合. 命名空间:System.Windows.Forms 汇编集:System.Windows.Forms( ...

  5. Windows Forms 2.0 Programming 花边(002)——失算!第一章的下马威

    突然发现译书的感觉就像五小强打十二宫一样--译完一章又一章,没完没了的.不过,圣殿山底下躺着的是Athena,我这儿不一样-- 书堆儿里躺着的是咱们的编辑.(>_<) 译完前言和序言,直奔 ...

  6. Windows Forms(二)

    导读 1.用VS创建一个Windows Forms程序 2.分析上面的程序 3.Mediator pattern(中介者模式) 4.卡UI怎么办--BackgroundWorker组件 用VS创建一个 ...

  7. c#+AE开发中,System.Windows.Forms.AxHost.InvalidActiveXStateException 在 ESRI.ArcGIS.AxControls.dll 中发生

    问题描述图 //目标框架由3.5改为4.5后会出现无法启动的错误,System.Windows.Forms.AxHost+InvalidActiveXStateException"的异常, ...

  8. Rules to Better Windows Forms Applications

    Do you agree with them all? Are we missing some? Email me your tips, thoughts or arguments. Let me k ...

  9. Spread for Windows Forms高级主题(3)---单元格的编辑模式

    理解单元格的编辑模式 通常情况下,当终端用户双击单元格时,编辑控件将允许用户在该单元格中输入内容.在一个单元格中编辑的能力被称为编辑模式.一些属性和方法可以用来自定义编辑模式的使用. 当一个单元格处于 ...

最新文章

  1. 成为Java高手的25个学习要点
  2. Android应用开发基础篇(9)-----SharedPreferences
  3. iPhone 查看万能钥匙连接的 WiFi 密码
  4. 2.15 更改所有者和所属组chown
  5. datatables 获取筛选后的数据
  6. leetcode1082. 销售分析 I (SQL)
  7. unity3d 剧情制作_游戏设计作品集干货:跨专业如何入门 Unity3D 游戏引擎?
  8. 微信小程序 - 展开收缩列表
  9. MySQL怎么导出用户权限表_导出MySQL用户权限_MySQL
  10. 关于主窗体与子窗体之间的通信以及面向对象思想的一些应用
  11. 基于JSP+Servlet的旅游景点服务平台(旅游网站)
  12. EEE(Energy Efficient Ethernet)-节能以太网
  13. 家政维修小程序+上门预约小程序+VUE前后端分离+uniapp(附近师傅+门店入驻+在线抢单服务APP、小程序、公众号、H5)
  14. 性能测试入门,其实很简单,看看这篇,好好学习
  15. MacBook 安装固态硬盘
  16. Kafka(八)----Kafka Tool 2.0.7(最新)版本超详细使用指北
  17. Win10怎么隐藏磁盘分区
  18. TWS耳机哪款好用?2022TWS耳机推荐
  19. WebSocket接口测试方法
  20. zbb20180930 java,nio,netty Netty5.0用法

热门文章

  1. debian 删除mysql数据库_Debian中完全卸载MySQL的方法
  2. 如何清理和维护计算机,电脑的优化与维护操作教程
  3. 蚁群算法matlab vrp问题车辆限重,蚁群算法MATLAB解VRP问题
  4. 定时执行java程序_如何让Java程序定时运行
  5. java8 stream index_Java8的stream用法整理
  6. 平衡二叉树AVL删除
  7. java成员初始化顺序_Java成员初始化顺序
  8. mysql修改表的字段_mysql修改表字段学习笔记
  9. vs写c语言能用scanf,【PAT编写代码时遇到的问题】vs中使用scanf(%c,x);
  10. 室内定位算法_001:室内定位算法技术咨询服务工作室简介(更新)