Exposing Windows Forms Controls as ActiveX controls

转: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.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/549765.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

知识碎片

JS 部分 基本类型 对于类型的进一步判断, 可以参考js类型判断 # typeof undefined – 未定义 object – 对象或null # null类型 如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为 null 而不是其他值。这样一来,只要直接检查…

梦之所寄,行之所为——地狱之门就此洞开(读梦断代码有感)

在博客园的精华区看到一篇名为“程序员,对自己好一点”的文章,颇有感触。我只是初涉这个圈子的一个小小的实习生,却也觉得对于程序员而言:累,加班工作,吃青春饭…。为什么要把自己弄得如此狼狈?…

MPLS-L3×××中的公网访问

1.在站点内配置一个代理服务器拥有公网IP做NAT,之后网关写到CE,CE上配置默认路由指向PE,之后PE上做静态的公网跳出路由,即在静态路由的下以跳写public关键字。之后做回程路由跳回,下一跳写站点地址即可,但是…

Vuetable-2使用全纪录

vuetable-2介绍 vuetable2是一款基于vuejs开发的table组件,支持表格加载和翻页、翻页信息展示的组件官方github | 官方API学习 | Tutorialvuetable-2包括三个部分: vuetablevuetablePagination vuetablePaginationDropdownvuetablePaginationMixinvue…

OCP-052考试题库汇总(26)-CUUG内部解答版

Which three of these must be accessible to keep a database open? A)Control file. B)All members of a redo log group. C)SYSTEM tablespace. D)SYSAUX tablespace. E)spfile Answer: ABC 赵: 1 nomount:实例已经启动,进程和内存已经分…

QT_C++

QT_C C 与 C 区别&#xff1a;  面向过程&#xff1a;吃&#xff08;狗&#xff0c;屎&#xff09; 面向对象&#xff1a;狗. 吃&#xff08;屎&#xff09; ^ . ^ 博客&#xff1a;https://www.runoob.com/cplusplus/cpp-tutorial.html 插入符&#xff1a;<< 控制符…

使用Nodejs搭建server

使用Nodejs搭建server&#xff08;MySQL MongoDB&#xff09; 环境 文件 版本号nodejs8.10.0mysql2.16.0express-generator4.16.0pm23.0.3ejs2.6.1 - 准备工作 安装上述环境依赖使用express-cli快速创建服务&#xff0c;资料 express project-name将express的默认引擎jade调…

静态路由的实现

在路由器A上做如下配置&#xff1a;router(config)#hostname AA(config)#interface f0/0A(config-if)#ip address 192.168.1.1 255.255.255.0 A(config-if)#no shutdownA(config)#interface f0/1A(config-if)#ip address 192.168.2.1 255.255.255.0 A(config-if)#no shutdownA(…

2019-08-09 纪中NOIP模拟赛B组

T1 [JZOJ1035] 粉刷匠 题目描述 windy有N条木板需要被粉刷。 每条木板被分为M个格子。 每个格子要被刷成红色或蓝色。 windy每次粉刷&#xff0c;只能选择一条木板上一段连续的格子&#xff0c;然后涂上一种颜色。 每个格子最多只能被粉刷一次。 如果windy只能粉刷 T 次&#x…

vue3实现打字机的效果

前言&#xff1a; vue3项目中实现打字机的效果。 实现效果&#xff1a; 实现步骤&#xff1a; 1、安装插件 npm i vue3typed 2、main.js中配置 import vuetyped from vue3typedconst app createApp(App) // 挂载打字机的全局方法 app.use(vuetyped) 3、界面使用 <vuet…

易中天与单田芳的区别在哪儿

单田芳先生是中国著名的评书演员&#xff0c;我非常喜欢听单田芒的评书&#xff0c;在那个没有电视机的时代&#xff0c;收听单田芳先生的评书对我来说就是一种最大的人生享受。所以&#xff0c;“单田芳”这三个字早就镌刻在我的脑海之中。一直到今天我还深深地敬仰着这位全国…

Express + Node 爬取网站数据

前言 因为自己写的demo需要历史天气的统计数据&#xff0c;但是国内很难找到免费的api接口&#xff0c;很多都需要付费和审核。而国外的网站虽然免费但需要提前知道观测站&#xff0c;城市id等信息。所以就有了这么一篇文章的诞生。 准备工作 库 作用superagent发送请求supera…

ajax省级联动 回发或回调参数无效

今天在做项目有个修改内容的&#xff0c;有个地方用到省级联动&#xff0c;现在一般都用ajax&#xff0c;很少用auto什么的那个属性了 想想ajax做省级联动也很简单&#xff0c;就开始做了&#xff0c;没想到在修改的时候提示回发或回调参数无效&#xff0c;然后去网上找了好久 …

虚拟局域网(VLAN)的管理

什么是虚拟局域网&#xff1f;虚拟局域网是一种用逻辑的定义方法&#xff0c;把两个或更多的连在交换网络上的终端规划在一起。 这种逻辑定义方法可以延伸到多个交换机。被规划在一起的终端&#xff0c;可以通过几种网络设置来规划。好像任何一种网络技术一样&#xff0c;了解…

学习antd-design-pro

学习使用react-antd-pro框架(一篇学习中的问题思考记录) 框架介绍 react-antd-pro 大体上等于 react antd pro。官网对于相关技术栈的描述如下&#xff1a; 我们的技术栈基于 ES2015、React、UmiJS、dva、g2 和 antd UmiJS: 可插拔的企业级 react 应用框架 dva: React and r…

SqlZoo.net习题答案:The Join 【Movie】

习题地址&#xff1a;http://sqlzoo.net/3.htm 表结构&#xff1a;  movie(id, title, yr, director)      actor(id, name)      casting(movieid, actorid, ord) 1b.Give year of Citizen Kane. select yr from movie where title Citizen Kane 1c.List all …

汉语编程++

没想到汉语编程又有人开始网上对骂了。一方指另一方骗人&#xff0c;一方吹自已伟大。今天群里头有人又把它翻出来了&#xff0c;刚好无聊&#xff0c;也就发明了一个汉语编程语言&#xff0c;集成到visual studio 2005的IDE中&#xff0c;名字就叫汉语编程&#xff0c;欢迎同样…

hightopo学习系列:hightopo介绍(一)

起因 新的软件主管来公司以后&#xff0c;有整整2周的时间没有搭理前端开发。就在这周一快下班的时候&#xff0c;突然和我说话了。问了我一些以前用的图形库&#xff0c;并让我开始了解hightopo。甩给了我一个全拼&#xff0c;就拂袖而去&#xff0c;留下一脸懵逼的我。 没办…

mongo指令

use admin db.runCommand({logRotate:1}) show dbs; db.currentOp(); db.serverStatus().connections db.killOp(26593769); use adbname db.tblname.ensureIndex({"sendtime":1}) db.tblname.getIndex() 转载于:https://www.cnblogs.com/ccgblog/p/8427972.html

女人,向《奋斗》中的夏琳米莱们学习什么

被称为赵宝刚导演的转型之作电视连续剧《奋斗》&#xff0c;看得我有些意犹未尽。据说佟大为与马伊俐都是本色表演&#xff0c;但是我却更喜欢剧中米莱的角色。 刚开始看《奋斗》的时候&#xff0c;以为夏琳是许晴演的呢&#xff0c;从长相性格表情连发型都像&#xff0c;像缩小…