在 .NET Compact Framework 中宿主 ActiveX 控件(翻译)

使用 AxImp.exe 生成一个完整的控件类定义

能够最终获益当然好 - 按照 Visual Studio 在桌面计算机窗体项目中处理的方式处理 ActiveX 控件。您只需向工具栏添加一个控件,方法是浏览到该控件或从注册组件列表中选择它。虽然 Visual Studio 设计器主动阻止任何将 ActiveX 控件添加到设备项目的企图,但您可以避免该限制。与前面描述的方法(将 TLBIMP 工具用作添加对类型库引用的命令行功能)类似,当将一个 ActiveX 控件放在窗体上时,可以使用 AXIMP 工具(也是 .NET Framework SDK 的一部分),该工具创建与 Visual Studio IDE 所创建的库相同的一组库。正如 TLBIMP 工具具有比集成开发环境 (IDE)(在导入类型库方面)更丰富的功能集一样,AXIMP 工具能够完成更多的任务。对于您的项目而言,最重要的是能够以其源格式产生 Interop 代码。如果运行以下命令行 AxImp.exe C:\WINDOWS\system32\wmp.dll /source,将产生三个文件: 

AxWMPLib.cs 

AxWMPLib.dll 

WMPLib.dll 

还有一个 .pdb 文件,但它现在已经不重要了。AxWmpLib.cs 是 Interop 库 AxWMPLib.dll 的源代码。仔细看一下,您会发现它定义了一个从 System.Windows.Forms.AxHost 派生的类 AxWindowsMediaPlayer。这 1663 行代码告诉明示了手动编写该代码是多么地令人不快。

您为什么想要源代码呢?如果您在 ILDAsm 工具中查看 AxWMPLib.dll,就会发现,它是针对 MSCORLIB 和 System.Windows.Forms 的桌面计算机版本编译的。显然,您不能使用 AXIMP 生成的 AxWMPLib.dll 版本。但是,您可以针对 .NET Compact Framework 库编译源代码文件,获得可以在设备上使用的程序集。

试图编译 Interop 库的源代码时,您会发现由于 MSCORLIB 和 System.Windows.Forms 的设备版本而导致产生了相当多的错误。幸运的是,您可以忽略所有这些缺失的引用,并用生成方法存根 (stub) 替换它们。您可以在本文的下载代码示例的 AxImpSupport.cs 模块中找到这些 stub。

使用 AXIMP 工具生成包装的好处是:快速、简单,并且可以创建一个具有完全事件和设计器支持的控件类。当然,其他两个方法也可以产生带有完全设计器支持的代码,但它们会需要大量的工作。

一些开发人员更喜欢将这样的类编译到一个单独的库中。因为不需要编写任何额外的代码,即使不熟悉 C# 的开发人员也可以构建此控件库。控件库构建完成后,您可以轻松地将其用于 Visual Basic .NET 项目中,如本文的下载代码示例所示。

设计器支持

因为 AxHost 类是从 Control 类派生的,所以 Visual Studio 设计器直接获得 AxHost 类,并将其显示为可以插入到您的项目窗体中。对于从 AxHost 类派生的类也如此。所有宿主的控件在设计器中均可自动使用,如图 4 所示。


 4. Visual Studio 工具箱中出现的包装 ActiveX 控件

此外,由于生成的 ActiveX 控件类通过 .NET Compact Framework 属性和事件公开了调度属性和事件接口,因此它们在设计器中也可用。您可以通过控件清单进一步自定义设计器中的控件外观,但这不属于本文的讨论范围。

图 5 显示一个宿主 ShockWave Flash 控件的设计器 Properties 窗格。


 5. 宿主 ActiveX 控件事件


 6. 宿主 ActiveX 控件属性

从 Control 类派生 AxHost 类的一个意外结果是 AxHost 类也在设计器工具箱中显示。因为对开发人员而言,它作为一个独立的控件是没用的,所以您需要用以下内容向项目添加一个控件清单文件来阻止它。

<?xml version="1.0" encoding="utf-16"?>
            <Classes xmlns="http://schemas.microsoft.com/VisualStudio/2004/03/SmartDevices/XMTA.xsd">
                <Class Name="System.Windows.Forms.AxHost">
                <DesignTimeVisible>false</DesignTimeVisible>
                </Class>
            </Classes>
            

需要改进的内容

总有一些内容可以改进。我们这些 OpenNETCF.org 的员工正计划将来添加或增强一些 AxHost 类功能。

下面列出一些不具备的功能: 

键盘支持
尚未通过使用键盘的设备对该代码进行测试。我很肯定快捷键、焦点和按键处理存在一些问题。 

无窗口激活
目前不支持该类型的激活。幸运的是,大部分支持无窗口激活的控件也支持窗口激活。 

类似按钮和类似标签的控件
AxHost 类的当前版本很有可能不能正确地处理 OLEMISC 标志。利用诸如 Shockwave player 和 WMP 之类的控件,它实际上不是必需的,但我希望某些控件真正需要它。 

激活和停用
大部分控件开发人员都对具有一个简单的生命周期感兴趣:创建,激活,显示,停用,销毁。一些控件可能还有更复杂的要求,如多个激活或停用。 

如果您觉得此代码有用,请随时将您的意见和问题报告发送至 alexf@opennetcf.org。 

小结

您已经了解了通过使用 .NET Compact Framework 2.0 创建 ActiveX 控件的托管宿主这一过程。本文介绍了有关控件宿主的一些内容,并针对特别有用的 ActiveX 宿主对象,说明了一些问题和解决方案,并向您介绍了如何使用它以在您自己的应用程序中宿主控件。

此处说明的托管控件宿主框架由 OpenNETCF.org 提供。

参考文献

本文采用了以下参考文献中的信息: 

Introduction to ActiveX Controls

Introduction to ActiveX Control Containers

Developing Applications with OLE 2.0

关于作者

Alex Feinman 是 Corrigo Incorporated(一家位于北加利福尼亚州的技术公司,并且是 Microsoft 认证解决方案提供商)的一位软件工程师。Alex 还是 OpenNETCF.org 顾问委员会的成员。

转载于:https://www.cnblogs.com/abob/archive/2008/10/10/1308014.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
不用工具箱的话,自己手工添加,需要注意一个问题,就是要用Aximp.exe来包装一下ocx控件的类,然后再程序引用生成的dll就可以了。 aximp [options]{file.dll | file.ocx} The following command generates MediaPlayer.dll and AxMediaPlayer.dll for the Media Player control msdxm.ocx. aximp c:\systemroot\system32\msdxm.ocx 将 ActiveX 控件COM 类型库的类型定义转换为 Windows 窗体控件。 Windows 窗体只能承载 Windows 窗体控件,即从 Control 派生的类。Aximp.exe 生成可承载于 Windows 窗体上的 ActiveX 控件的包装类。这使您得以使用可应用于其他 Windows 窗体控件的同一设计时支持和编程方法论。若要承载 ActiveX 控件,必须生成从 AxHost 派生的包装控件。此包装控件包含基础 ActiveX 控件的一个实例。它知道如何与 ActiveX 控件通信,但它显示为 Windows 窗体控件。这个生成的控件承载 ActiveX 控件并将其属性、方法和事件公开为生成控件的属性、方法和事件。 如果不包装一下直接用,会出现 灾难性 错误。上面已经说明了原因。 在项目引用生成的ax开头的dll,在窗体代码增加: 声明一个公有的控件对象: public AxISPICRECLib.AxISPICREC AxISPICREC; 在InitializeComponent()方法内初始化控件: AxISPICREC = new AxISPICRECLib.AxISPICREC();//必须new对象,否则窗体设计器出问题 ((System.ComponentModel.ISupportInitialize)(this.AxISPICREC)).BeginInit();//初始化开始 this.Controls.Add(this.AxISPICREC);//添加控件 ((System.ComponentModel.ISupportInitialize)(this.AxISPICREC)).EndInit(); this.AxISPICREC.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("AxISPICREC.OcxState")));//设计控件状态 如果遇到“正试图在 os 加载程序锁内执行托管代码”这个错误,请设置“调试”--“异常” "----"Managed Debugging Assistants"勾掉"LoaderLock" 就可以了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值