当前位置:职场发展 > vs2010包控制_VS2010控制集中介绍

vs2010包控制_VS2010控制集中介绍

  • 发布:2023-10-01 10:02

VS2010控制集中介绍

在使用VS的过程中,熟悉其相关控件的使用非常重要。接下来简单列出VS的控件并简单介绍一下它们的用途:

BackgroundWorker 组件:使表单或控件能够异步运行操作。

BindingNavigator 控件(Windows 为绑定到数据的控件提供导航和操作用户界面 (UI)。

BindingSource 组件:封装数据源以绑定到控件。

按钮控件(Windows 窗体):显示用户可以单击以执行操作的标准按钮。

CheckBox 控件(Windows 窗体):指示条件是打开还是关闭。 CheckedListBox 控件(Windows 窗体):显示项目列表,每个项目旁边都有一个复选框。 ColorDialog 组件(Windows 窗体):允许用户从调色板中选择颜色,并将自定义颜色添加到预配置对话框中的调色板中。 ComboBox 控件(Windows 窗体):在下拉组合框中显示数据。 ContextMenu 组件(Windows 窗体):为用户提供易于访问的菜单,其中包含与所选对象关联的常用命令。尽管 ContextMenuStrip 替换并添加了早期版本的 ContextMenu 控件的附加功能,但如果需要,可以保留 ContextMenu 以实现向后兼容和将来使用。 ContextMenuStrip控件:代表快捷菜单。尽管 ContextMenuStrip 替换并添加了早期版本的 ContextMenu 控件的附加功能,但如果需要,可以保留 ContextMenu 以实现向后兼容和将来使用。 DataGrid 控件(Windows 窗体):显示数据集中的表格数据并允许更新数据源。 DataGridView 控件(Windows 窗体):提供灵活、可扩展的系统来显示和编辑表格数据。 DateTimePicker 控件(Windows 窗体):允许用户从日期或时间列表中选择单个项目。对话框控件和组件(Windows 窗体):描述一组允许用户与应用程序或系统执行标准交互的控件。 DomainUpDown 控件(Windows 窗体):显示用户可以浏览和选择的文本字符串。 ErrorProvider 组件(Windows 窗体):以非侵入式方式向用户显示错误信息。 FlowLayoutPanel 控件(Windows 窗体):表示水平或垂直动态布局其内容的面板。 FolderBrowserDialog 组件(Windows 窗体):显示一个界面,用户可以通过该界面浏览和选择目录或创建新目录。 • FontDialog 组件(Windows 窗体):显示系统上当前安装的字体。格罗upBox 控件(Windows 窗体):为其他控件提供可识别的分组。 HelpProvider 组件(Windows 窗体):将 HTML 帮助文件与基于 Windows 的应用程序相关联。 HScrollBar 和 VScrollBar 控件(Windows 窗体):提供通过在应用程序或控件中水平或垂直滚动​​来导航项目列表或大量信息的能力。 ImageList 组件(Windows 窗体):在其他控件之上显示图像。标签控件(Windows 窗体):显示用户无法编辑的文本。 LinkLabel 控件(Windows 窗体):允许您将 Web 样式链接添加到 Windows 窗体应用程序。 ListBox 控件(Windows 窗体):允许用户从预定义列表中选择一项或多项。 ListView 控件(Windows 窗体):以 Windows 资源管理器的方式显示带有图标的项目列表。 MainMenu 组件(Windows 窗体):在运行时显示菜单。虽然 MenuStrip 取代了早期版本的 MainMenu 控件并添加了功能;您可以选择保留 MainMenu 以实现向后兼容和将来使用。 MaskedTextBox 控件(Windows 窗体):限制窗体中用户输入的格式。 MenuStrip 控件(Windows 窗体):为窗体提供菜单系统。虽然 MenuStrip 取代了早期版本的 MainMenu 控件并添加了功能;您可以选择保留 MainMenu 以实现向后兼容和将来使用。 MonthCalendar 控件(Windows 窗体):显示直观的图形界面,供用户查看和设置日期信息。 NotifyIcon 组件(Windows 窗体):显示在后台运行且没有用户界面的进程的图标。 NumericUpDown 控件(Windows 窗体):显示用户可以浏览和选择的数字。 OpenFileDialog 组件(Windows 窗体):允许用户使用预配置的对话框打开文件。 PageSetupDialog 组件(Windows 窗体):通过预配置的对话框设置用于打印的页面详细信息。面板控制(Windows 窗体):为其他控件提供可识别的分组并允许滚动。 PictureBox 控件(Windows 窗体):以位图、GIF、JPEG、图元文件或图标格式显示图形。 PrintDialog 组件(Windows 窗体):选择打印机、选择要打印的页面以及确定其他与打印相关的设置。 PrintDocument 组件(Windows 窗体):设置描述在基于 Windows 的应用程序中打印内容和打印文档的属性。 PrintPreviewControl 控件(Windows 窗体):允许您创建自己的 PrintPreview 组件或对话框,而不是使用预配置的版本。 PrintPreviewDialog 控件(Windows 窗体):显示将要打印的文档。 ProgressBar 控件(Windows 窗体):以图形方式指示操作的完成进度。 RadioButton 控件(Windows 窗体):向用户显示一组两个或多个互斥选项。 RichTextBox 控件(Windows 窗体):允许用户通过格式设置输入、显示和操作文本。 SaveFileDialog 组件(Windows 窗体):选择要保存的文件以及文件的保存位置。 SoundPlayer 类:使您能够轻松地将声音包含在应用程序中。 SplitContainer 控件(Windows 窗体):允许用户调整停靠控件的大小。拆分器控件(Windows 窗体):允许用户调整停靠控件的大小(.NET Framework 版本 1.x)。 StatusBar 控件(Windows 窗体):显示与具有焦点的控件相关的状态信息。尽管 StatusStrip 替换并扩展了 StatusBar 控件的早期版本,但您可以选择保留 StatusBar 以实现向后兼容和将来使用。 StatusStrip控件:代表Windows状态栏控件。尽管 StatusStrip 替换并扩展了 StatusBar 控件的早期版本,但您可以选择保留 StatusBar 以实现向后兼容和将来使用。 TabControl 控件(Windows 窗体)?显示可包含的多个图像切片或其他控件的选项卡。 TableLayoutPanel 控件(Windows 窗体):表示在行和列的网格中动态布局其内容的面板。 TextBox 控件(Windows 窗体):允许用户进行可编辑的多行输入的文本框。定时器组件(Windows 窗体):您可以定义时间中断并定期触发事件。工具栏控件(Windows 窗体):显示激活命令的菜单和位图按钮。您可以扩展控件的功能并修改其外观和行为。虽然 ToolStrip 取代了早期版本的 ToolBar 控件并添加了功能;您可以选择保留工具栏以实现向后兼容和将来使用。 ToolStrip 控件(Windows 窗体):在 Windows 窗体应用程序中创建自定义工具栏和菜单。虽然 ToolStrip 取代了早期版本的 ToolBar 控件并添加了功能;您可以选择保留工具栏以实现向后兼容和将来使用。 ToolStripContainer 控件:在窗体的四个侧面提供面板,用于停靠、浮动和排列 ToolStrip 控件,并为传统控件提供中央 ToolStripContentPanel。 ToolStripPanel 控件:提供用于停靠、浮动和排列 ToolStrip 控件的面板。 ToolStripProgressBar控件概述:以图形方式指示操作的完成进度。 ToolStripProgressBar 通常包含在 StatusStrip 中。 ToolStripStatusLabel 控件:代表 StatusStrip 控件中的一个面板。工具提示组件(Windows 窗体):当用户指向其他控件时显示文本。 TrackBar 控件(Windows 窗体):允许您浏览大量信息或直观地调整数字设置。 TreeView 控件(Windows 窗体):显示可以展开或折叠的节点层次结构。 WebBrowser 控件(Windows 窗体):托管网页并向应用程序提供 Internet Web 浏览功能。控制有两个概念。上面介绍的主要是VS自带的控件。另一种方式是根据自己的要求自己写一个定义好的控件,加载到系统中即可。多于这是按字母顺序简单介绍了VS的大部分控件。后面会介绍这些控件的相关属性的介绍和使用。

? ?

功能介绍:

1。支持下拉、文件打开、文本输入、点击项显示描述内容。

以下业务代码调用封装的类。

类别:属性类

显示名称:名称

描述符:描述内容

编辑:编辑

私有 PropertyManage _pmc=new PropertyManage();

///

/// 绑定PropertyGrid

///

///

公共对象 GetPropertyObject()

{

#区域方案配置

属性 pp = new Property("SchemeName", "test.xml", false, true);

pp.Category =“程序配置”;

pp.DisplayName = "计划";

pp.Editor = new PropertyGridFileEditor();

_pmc.Add(pp);

#endregion

#region 仪表规格

pp = new Property("MeterType", "1S");

pp.Category =“仪表规格”;

pp.DisplayName = "仪表类型";

字符串[] s = 新字符串[] { "1S", "2S", "3S" };

pp.Converter = new DropDownListConverter(s);

_pmc.Add(pp);

pp = new Property("RatedVolt","220");

pp.Category =“仪表规格”;

pp.DisplayName = "额定电压";

pp.Descriptor = "V";

_pmc.Add(pp);

pp = new Property("额定电流", "0");

pp.Category =“仪表规格”;

pp.DisplayName = "额定电流";

pp.Descriptor = "A";

_pmc.Add(pp);

pp = new Property("RatedFreq", "60");

pp.Category =“仪表规格”;

pp.DisplayName = "额定频率";

pp.Descriptor = "Hz";

_pmc.Add(pp);

pp = new Property("相","三相四线");

pp.Category =“仪表规格”;

pp.DisplayName = "接线方式";

s=new string[]{"三相四线","三相三相","单相"};

pp.Converter = new DropDownListConverter(s);

_pmc.Add(pp);

#endregion

返回_pmc;

}

//最后PropertyGrid控件调用

www.sychzs.cnedObject = GetPropertyObject();

以下封装代码可以直接复制。错误信息是没有引用相关的命名控件。右键分析会自动添加。 (PS:修改别人的结果)

region封装了PropertyGrid属性方法

? ? //属性管理类

? ?公共类 PropertyManage :CollectionBase、ICustomTypeDescriptor

? ? {

? ? ? ? public void Add(属性值)

? ? ? ? {

? ? ? ? ? ? int 标志 = -1;

? ? ? ? ? ? if(值!= null)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if (base.List.Count > 0)

? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? IList mList = 新列表();

? ? ? ? ? ? ? ? ? ? for (int i = 0; i < base.List.Count; i++)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ?属性 p = base.List[i] 作为属性;

? ? ? ? ? ? ? ? ? ? ? ? if (www.sychzs.cn == www.sychzs.cn)

? ? ? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? ? ?标志=我;

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? ? mList.Add(p);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? if (标志==-1)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? mList.Add(值);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? base.List.Clear();

? ? ? ? ? ? ? ? ? ? foreach(mList 中的属性 p)

? ? ? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? ? ? base.List.Add(p);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ?不然

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? base.List.Add(值);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? public void 删除(属性值)

? ? ? ? {

? ? ? ? ? ? if (value != null && base.List.Count > 0)

? ? ? ? ? ? ? ? base.List.Remove(value);

? ? ? ? }

? ? ? ?公共属性 this[int index]

? ? ? ? {

? ? ? ? ? ?得到

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return (Property)base.List[索引];

? ? ? ? ? ? }

? ? ? ? ? ?套装

? ? ? ? ? ? {

? ? ? ? ? ? ? ? base.List[索引] = (属性)值;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? #region ICustomTypeDescriptor 成员

? ? ? ?公共 AttributeCollection GetAttributes()

? ? ? ? {

? ? ? ? ? ? return TypeDescriptor.GetAttributes(this, true);

? ? ? ? }

? ? ? ?公共字符串 GetClassName()

? ? ? ? {

? ? ? ? ? ? return TypeDescriptor.GetClassName(this, true);

? ? ? ? }

? ? ? ?公共字符串 GetComponentName()

? ? ? ? {

? ? ? ? ? ? return TypeDescriptor.GetComponentName(this, true);

? ? ? ? }

? ? ? ? public TypeConverter GetConverter()

? ? ? ? {

? ? ? ? ? ? return TypeDescriptor.GetConverter(this, true);

? ? ? ? }

? ? ? ?公共事件描述符 GetDefaultEvent()

? ? ? ? {

? ? ? ? ? ? return TypeDescriptor.GetDefaultEvent(this, true);

? ? ? ? }

? ? ? ?公共 PropertyDescriptor GetDefaultProperty()

? ? ? ? {

? ? ? ? ? ? return TypeDescriptor.GetDefaultProperty(this, true);

? ? ? ? }

? ? ? ?公共对象 GetEditor(Type editorBaseType)

? ? ? ? {

? ? ? ? ? ? return TypeDescriptor.GetEditor(this, editorBaseType, true);

? ? ? ? }

? ? ? ? public EventDescriptorCollection GetEvents(Attribute[] 属性)

? ? ? ? {

? ? ? ? ? ? return TypeDescriptor.GetEvents(this, 属性, true);

? ? ? ? }

? ? ? ?公共 EventDescriptorCollection GetEvents()

? ? ? ? {

? ? ? ? ? ? return TypeDescriptor.GetEvents(this, true);

? ? ? ? }

? ? ? ? public PropertyDescriptorCollection GetProperties(Attribute[] 属性)

? ? ? ? {

? ? ? ? ? ? PropertyDescriptor[] newProps = new PropertyDescriptor[this.Count];

? ? ? ? ? ? for (int i = 0; i < this.Count; i++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ?属性 prop = (属性)this[i];

? ? ? ? ? ? ? ? newProps[i] = new CustomPropertyDescriptor(ref prop, 属性);

? ? ? ? ? ? }

? ? ? ? ? ?返回新的 PropertyDescriptorCollection(newProps);

? ? ? ? }

? ? ? ?公共 PropertyDescriptorCollection GetProperties()

? ? ? ? {

? ? ? ? ? ? return TypeDescriptor.GetProperties(this, true);

? ? ? ? }

? ? ? ?公共对象 GetPropertyOwner(PropertyDescriptor pd)

? ? ? ? {

? ? ? ? ? ?返回此;

? ? ? ? }

? ? ? ? #endregion

? ? }

? ? // 属性类 ?

? ?公共类属性

? ? {

? ? ? ?私有字符串_name = string.Empty;

? ? ? ?私有对象_value = null;

? ? ? ?私人布尔_readonly = false;

? ? ? ?私人布尔_visible = true;

? ? ? ?私有字符串_category = string.Empty;

? ? ? ?私有字符串_descriptor = string.Empty;

? ? ? ?类型转换器_converter = null;

? ? ? ?对象_editor = null;

? ? ? ?私有字符串_displayname = string.Empty;

? ? ? ?公共属性(字符串sName,对象sValue)

? ? ? ? {

? ? ? ? ? ? this._name = sName;

? ? ? ? ? ? this._value = sValue;

? ? ? ? }

? ? ? ? public Property(string sName, object sValue, bool sReadonly, bool sVisible)

? ? ? ? {

? ? ? ? ? ? this._name = sName;

? ? ? ? ? ? this._value = sValue;

? ? ? ? ? ? this._readonly = sReadonly;

? ? ? ? ? ? this._visible = sVisible;

? ? ? ? }

? ? ? ? public string Name ?//获得属性名 ?

? ? ? ? {

? ? ? ? ? ?获取{return_name;}

? ? ? ? ? ?设置{_名称 = 值;}

? ? ? ? }

? ? ? ?公共字符串显示名称? // 属性显示名称 ?

? ? ? ? {

? ? ? ? ?获取{return_displayname;}

? ? ? ? ? ?设置{_显示名称 = 值;}

? ? ? ? }

? ? ? ? public TypeConverter Converter ?//类型转换器,制作下拉列表时需要吗?

? ? ? ? {

? ? ? ? ?获取{return_converter;}

? ? ? ? ? ?设置{_converter =值;}

? ? ? ? }

? ? ? ? public string Category ?//属性所属的类别 ?

? ? ? ? {

? ? ? ? ?获取{return_category;}

? ? ? ? ? ?设置{_category = 值;}

? ? ? ? }

? ? ? ? public object Value ?//属性值?

? ? ? ? {

? ? ? ? ?获取{返回值;}

? ? ? ? ? ?设置{_value = 值;}

? ? ? ? }

? ? ? ?公共字符串描述符

? ? ? ? {

? ? ? ? ? ?获取{返回_描述符; }

? ? ? ? ? ?设置 { _descriptor = 值; }

? ? ? ? }

? ? ? ? public bool ReadOnly ?//是否是只读属性?

? ? ? ? {

? ? ? ? ?获取{return _readonly;}

? ? ? ? ? ?设置{_readonly =值;}

? ? ? ? }

? ? ? ? public bool Visible ?//是否可见? ?

? ? ? ? {

? ? ? ? ?获取{return_visible;}

? ? ? ? ? ?设置{_visible =值;}

? ? ? ? }

? ? ? ?公共虚拟对象编辑器? //属性编辑器?

? ? ? ? {

? ? ? ? ? ?获取{返回_editor; }

? ? ? ? ? ?设置{_editor =值;}

? ? ? ? }

? ? }

? ? //属性描述类

? ?公共类 CustomPropertyDescriptor : PropertyDescriptor

? ? {

? ? ? ?属性 m_Property;

? ? ? ?公共 CustomPropertyDescriptor(ref Property myProperty, Attribute[] attrs): base(www.sychzs.cn, attrs)

? ? ? ? {

? ? ? ? ? ? m_Property = myProperty;

? ? ? ? }

? ? ? ? #region PropertyDescriptor 重写方法

? ? ? ? public override bool CanResetValue(对象组件)

? ? ? ? {

? ? ? ? ? ?返回错误;

? ? ? ? }

? ? ? ?公共覆盖类型 ComponentType

? ? ? ? {

? ? ? ? ?获取{返回null;}

? ? ? ? }

? ? ? ?公共覆盖对象GetValue(对象组件)

? ? ? ? {

? ? ? ? ? ?返回m_Property.Value;

? ? ? ? }

? ? ? ? public override string Description

? ? ? ? {

? ? ? ? ? ? get{ return m_Property.Descriptor;}

? ? ? ? }

? ? ? ? public override string Category

? ? ? ? {

? ? ? ? ? ? get{return m_Property.Category;}

? ? ? ? }

? ? ? ? public override string DisplayName

? ? ? ? {

? ? ? ? ? ? get{return m_Property.DisplayName != "" ? m_Property.DisplayName : m_www.sychzs.cn;}

? ? ? ? }

? ? ? ? public override bool IsReadOnly

? ? ? ? {

? ? ? ? ? ? get{return m_Property.ReadOnly;}

? ? ? ? }

? ? ? ? public override void ResetValue(object component)

? ? ? ? {

? ? ? ? ? ? //Have to implement ?

? ? ? ? }

? ? ? ? public override bool ShouldSerializeValue(object component)

? ? ? ? {

? ? ? ? ? ? return false;

? ? ? ? }

? ? ? ? public override void SetValue(object component, object value)

? ? ? ? {

? ? ? ? ? ? m_Property.Value = value;

? ? ? ? }

? ? ? ? public override TypeConverter Converter

? ? ? ? {

? ? ? ? ? ? get{return m_Property.Converter;}

? ? ? ? }

? ? ? ? public override Type PropertyType

? ? ? ? {

? ? ? ? ? ? get { return m_Property.Value.GetType(); }

? ? ? ? }

? ? ? ? public override object GetEditor(Type editorBaseType)

? ? ? ? {

? ? ? ? ? ? return m_Property.Editor == null ? base.GetEditor(editorBaseType) : m_Property.Editor;

? ? ? ? }

? ? ? ? #endregion

? ? }

? ? //文件对话框编辑类

? ? public class PropertyGridFileEditor : UITypeEditor ?

? ? { ?

??

? ? ? ? public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context) ?

? ? ? ? { ?

? ? ? ? ? ? return UITypeEditorEditStyle.Modal; ?

? ? ? ? } ?

??

? ? ? ? public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value) ?

? ? ? ? { ?

? ? ? ? ? ? IWindowsFormsEditorService edSvc=(IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); ?

? ? ? ? ? ? if (edSvc != null) ?

? ? ? ? ? ? { ?

? ? ? ? ? ? ? ? // 可以打开任何特定的对话框 ?

? ? ? ? ? ? ? ? OpenFileDialog dialog = new OpenFileDialog(); ?

? ? ? ? ? ? ? ? dialog.AddExtension = false; ?

? ? ? ? ? ? ? ? if (dialog.ShowDialog().Equals(DialogResult.OK)) ?

? ? ? ? ? ? ? ? { ?

? ? ? ? ? ? ? ? ? ? return dialog.FileName; ?

? ? ? ? ? ? ? ? } ?

? ? ? ? ? ? } ?

? ? ? ? ? ? return value; ?

? ? ? ? } ?

??

? ? }

? ? //文件下拉转换类

? ? public class DropDownListConverter : StringConverter

? ? {

? ? ? ? object[] m_Objects;

? ? ? ? public DropDownListConverter(object[] objects)

? ? ? ? {

? ? ? ? ? ? m_Objects = objects;

? ? ? ? }

? ? ? ? public override bool GetStandardValuesSupported(ITypeDescriptorContext context)

? ? ? ? {

? ? ? ? ? ? return true;

? ? ? ? }

? ? ? ? public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) ?

? ? ? ? { ?

? ? ? ? ? ? return true;

? ? ? ? }

? ? ? ? public override

? ? ? ? System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)

? ? ? ? {

? ? ? ? ? ? return new StandardValuesCollection(m_Objects);//可以直接在内部定义一个数组,但并不建议这样做,这样对于下拉框的灵活 ? ? ? ? ? ? //性有很大影响 ?

? ? ? ? }

? ? }

? ? #endregion

?

最近做读卡器的B/S应用程序开发,由于读卡器厂商提供的手册都是C/S版本的,而且只有一个原始的Dll包,并没有web版的,那么就只好自己动手,丰衣足食了。 ?????????要开发Web版的读卡程序,大体思路如下:

1.???????使用C#对原始的Dll进行封装,这里要封装两部分内容,一部分是串口通信的功能,一部分是对卡读写的功能。

2.???????开发ActiveX控件调用封装后的Dll,使用串口通信来对卡进行读写。

3.???????打包并发布ActiveX控件。

4.? 使用ActiveX控件。

思路1中封装代码有2个类SerialInterfaceHelper,串口通信的帮助类,MifareOneHelper,M1卡的读写帮助类,我们放在了项目CardReader.Library中。

由于本文的重点是使用VS 2010(C#)进行ActiveX控件的开发,因此思路1中的内容就不进行详述了,后面会直接给出类库可以参考。本文的实例中演示C#开发

一个ActiveX读卡器控件,实现读取卡号并显示出卡号或异常信息的功能,分成三个大的步骤来实现:开发ActiveX控件、打包并发布ActiveX控件和使用

ActiveX控件。

?? 开发ActiveX控件

???? 常见的一些ActiveX大部分是使用VB、Delphi、C++开发,使用C#开发ActiveX要解决下面三个问题:

(1)使.NET组件可以被COM调用

(2)在客户机上注册后,ActiveX控件能通过IE的安全认证

(3)已在客户机上注册时,安装包能通过IE的签名认证

开发ActiveX步骤:

1.?创建Windows Forms Control Library项目CardReader.Controls,设置项目属性能够被COM调用。

右击CardReader.Controls,选择属性,设置项目的Assembly属性,如下图1所示:

?

图1

对Make Assembly Com-Visible选项划钩。

设置项目的编译选项,如图2所示:

图2

图2中对Register for COM Interop选中,对COM组件进行注册。(注意,此处如果实在debug状态下修改的,那在调到release状态下还需要再设置一次。)

设置应用程序的AssemblyInfo属性,右击项目的Properties,打开AssemblyInfo文件,Assembly:AllowPartiallyTrustedCallers,注意添加引用System.Security,代码如下:

using?System.Reflection;

using?System.Runtime.CompilerServices;

using?System.Runtime.InteropServices;

using?System.Security;

//?General?Information?about?an?assembly?is?controlled?through?the?following?

//?set?of?attributes.?Change?these?attribute?values?to?modify?the?information

//?associated?with?an?assembly.

[assembly:?AssemblyTitle("CardReader.Controls")]

[assembly:?AssemblyDescription("")]

[assembly:?AssemblyConfiguration("")]

[assembly:?AssemblyCompany("Microsoft")]

[assembly:?AssemblyProduct("CardReader.Controls")]

[assembly:?AssemblyCopyright("Copyright???Microsoft?2011")]

[assembly:?AssemblyTrademark("")]

[assembly:?AssemblyCulture("")]

?

[assembly:AllowPartiallyTrustedCallers()]

//?Setting?ComVisible?to?false?makes?the?types?in?this?assembly?not?visible?

//?to?COM?components.??If?you?need?to?access?a?type?in?this?assembly?from?

//?COM,?set?the?ComVisible?attribute?to?true?on?that?type.

[assembly:?ComVisible(true)]

?

//?The?following?GUID?is?for?the?ID?of?the?typelib?if?this?project?is?exposed?to?COM

[assembly:?Guid("15493d85-ec9e-4c75-a237-9009a997b780")]

?

//?Version?information?for?an?assembly?consists?of?the?following?four?values:

//

//??????Major?Version

//??????Minor?Version?

//??????Build?Number

//??????Revision

//

//?You?can?specify?all?the?values?or?you?can?default?the?Build?and?Revision?Numbers?

//?by?using?the?'*'?as?shown?below:

//?[assembly:?AssemblyVersion("1.0.*")]

[assembly:?AssemblyVersion("1.0.0.0")]

[assembly:?AssemblyFileVersion("1.0.0.0")]

?

?

2.?开发读卡器用户控件,这个用户控件包含三个部分:

一个TextBox,用以显示读出的卡号

一个Button,读卡

一个Label,显示错误信息

编写读卡按钮事件的代码,完成控件开发后,为了使该用户控件作为一个ActiveX控件进行使用,还需要做以下修改:

首先,为控件类创建一个唯一的GUID,这个编号将用于B/S系统的客户端调用时使用,注意这里的GUID不能和AssemblyInf中的GUID相同,生成GUID的方法如下,

在开始-》程序中打开Microsoft Windows SDK Tools,如下图3所示:?

?

?

?

图3

点击GUID Generator,生成GUID,如下图4所示:

?

图4

COPY生成的GUID到记事本,再拷贝GUID的字符串到控件类,代码如下所示:[Guid("E395359C-86F2-4D7B-A91A-5A64B9E3BA6C")] public?partial?class?ReadCardControl?:?UserControl

其次,为了让ActiveX控件获得客户端的信任,控件类还需要实现一个名为“IObjectSafety”的接口,要创建该接口(注意,不能修改该接口的GUID值),

IObjectSafety代码如下:

????[ComImport,?Guid("1D9AD540-F2C9-4368-8697-C4AAFCCE9C55")] ????[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] ????public?interface?IObjectSafety ????{ ????????[PreserveSig] ????????void?GetInterfacceSafyOptions( ????????int?riid, ????????out?int?pdwSupportedOptions, ????????out?int?pdwEnabledOptions); ? ????????[PreserveSig] ????????void?SetInterfaceSafetyOptions( ????????int?riid, ????????int?dwOptionsSetMask, ????????int?dwEnabledOptions); ????}

注意这里要添加引用:using?System.Runtime.InteropServices;

?

3.?修改控件类,使之继承IObjectSafety接口,代码清单如下:

[Guid("E395359C-86F2-4D7B-A91A-5A64B9E3BA6C")] ????public?partial?class?ReadCardControl?:?UserControl,IObjectSafety ????{ ????????public?int?icdev;?//?通讯设备标识符 ????????public?Int16?st; ????????public?int?sec; ? ????????public?ReadCardControl() ????????{ ????????????InitializeComponent(); ????????} ????????#region?IObjectSafety?成员 ? ????????public?void?GetInterfacceSafyOptions(int?riid,?out?int?pdwSupportedOptions,?out?int?pdwEnabledOptions) ????????{ ????????????pdwSupportedOptions?=?1; ????????????pdwEnabledOptions?=?2; ????????} ? ????????public?void?SetInterfaceSafetyOptions(int?riid,?int?dwOptionsSetMask,?int?dwEnabledOptions) ????????{ ????????????throw?new?NotImplementedException(); ????????} ? ????????#endregion }

?

?? 打包并发布ActiveX

???????? ActiveX控件开发完成后,我们要讲ActiveX控件打包和发布。ActiveX控件可以使用VS 2010的安装项目进行部署,使用VS 2010创建Windows Form的安装工程就可以将ActiveX的dll进行打包。在打包时注意将ActiveX控件项目作为主输出项目,并设置其Register属性为vsdrpCOM,创建打包项目如下图5所示:

图5

创建一个Windows 安装项目,并给项目添加项目输出,如下图6所示:

图6

在添加项目输出时,我们将ActiveX项目添加进来,在项目中选择ActiveX控件项目(CardReader.Controls),Primary Out(基本输出),如下图7所示:

图7

添加完项目输出以后,在Application Folder里已经有了三个文件:CardReader.Controls.tlb、CardReader.Libary.dll、Primary Output From CardReader.Controls,同时将mwrf32.dll也打进安装包里,右击添加文件,浏览到mwrf32.dll添加进来即可。注意首先要将mwrf32.dll拷贝到ActiveX控件

项目中的Bin中,添加文件时浏览到\\CardReader\CardReader.Controls\bin\Debug中的mwrf32.dll打包进去,否则会出现找不到mwrf32.dll的错误。

添加完文件后,设置Primary Output From CardReader.Controls的Register属性为vsdrpCOM。设置完成后右击安装工程SetupCardReader,

修改其属性,如下图8所示:

图8

?????????在上图中可以设置输出的文件名,这个文件名就是打包后安装文件.MSI的文件名。设置包文件、压缩方式,CAB size,这三项均选择默认值即可。

最后设置安装URL,这里的安装URL是用来发布或者测试ActiveX的URL地址的。上图中我们将在89端口下进行测试,因此URL设置为:

http://localhost:89/CardReader

这样打包文件就生成了,我们可以打开\\CardReader\SetupCardReader\Debug看到生成了2个文件,一个是setup.exe,一个是SetupCardReader.msi,

这里的Setup.exe就是我们在使用ActiveX时的codebase文件。

打包成exe文件以后,我们可以进一步对安装文件进行打包成.cab文件,安装隐藏了msi?安装界面,类似于cabarc?打包ocx?的效果

(点击install?之后其他的都后台做了),本文中暂不讨论,感兴趣的读者可以使用CAB SDK?中的工具CABARC.EXE (下载地址?http://www.sychzs.cn/kb/310618?)来进行。

?? 使用ActiveX

打包完成后,我们就可以在应用程序中使用打包好的ActiveX控件了,创建一个web项目(CardReader.Web),在测试页面的HTML代码中添加对ActiveX控件

的引用,修改default.aspx的代码如下:

???? ????

注意这里的clsid:E395359C-86F2-4D7B-A91A-5A64B9E3BA6C的值是我们在开发ActiveX控件时的GUID。

运行的效果图下图9所示:

?

图9

?????????图9中,我们演示了不调用串口通信和读卡程序下的效果,至于要调用串口通信和读卡程序,我将在另一篇帖子里进行详细说明。

?????????至此,使用VS 2010开发ActiveX控件的大部分功能已经完成了,在VS 2010环境中使用C#开发ActiveX控件,技术并不太困难,但是要求客户端需要安装.NET Framework。鉴于ActiveX控件一般都是实现一些简单单一的功能,所以建议使用.NET Framework 2.0/.NET Framework 4.0下开发,

本实例中我们使用了.NET Framework 4.0。

?

以上我们介绍了开发、打包、发布、使用ActiveX控件的全过程。在演示程序中,我们没有调用串口通信和读卡器Dll程序,由于我们读卡器的原始Dll是使用其它语言进行开发的,对C#来说,是非托管代码,因此我们还需要在代码级别进行非托管代码的安全性设置。

?

?其实如果我们不进行设置,只是修改了代码,运行程序以后,其出错界面如下图1所示:

?

图1

抛出异常如下:

************** Exception Text **************

System.MethodAccessException: Attempt by security transparent method 'Rare.Card.Libary.Controls.

ReadCardControl.btnRead_Click(System.Object, System.EventArgs)' to call native code through method 'Rare.Card.Libary.MifareOneHelper.rf_read(Int32, Int32, Byte[])' failed.?Methods must be security critical or

security safe-critical to call native code.

?

通过查阅MSDN,对异常的解释如下:

在?Microsoft .NET Framework 4?中,公共语言运行时?(CLR)?安全模型发生了不少变化。其中一项变化,即采用?Level2?透明性

(与?Silverlight?的安全模型非常相似)很可能影响?AllowPartiallyTrustedCallers (APTCA)?库的作者。透明性属性有三种:SecurityTransparent、SecuritySafeCritical?和?SecurityCritical。

?

SecurityTransparent:标记为?SecurityTransparent?的代码从安全性角度而言是可靠的。它不能完成任何危险操作,例如声明权限、

执行无法验证的代码或调用本机代码。它也不能直接调用?SecurityCritical?代码。

如上文所述,出于安全的考虑,所有部分受信任代码都强制为?SecurityTransparent。这也是?APTCA?库的默认透明性。

SecurityCritical:与?SecurityTransparent?不同,SecurityCritical?代码能够执行任何所需操作。它能够执行声明、

调用本机代码和其他操作。它能够调用其他方法,且不受透明性标记的限制。

只有完全受信任代码才能为?SecurityCritical。事实上,(非?APTCA)完全受信任代码默认情况下属于?SecurityCritical,

从而保护其免受透明的部分受信任调用方的调用。

SecuritySafeCritical:SecuritySafeCritical?代码起着桥梁的作用,它允许透明代码调用关键方法。SecuritySafeCritical

代码与?SecurityCritical?代码的权限相同,但它可由?SecurityTransparent?代码调用。因此,SecuritySafeCritical?代码必须以安全方式公开基础?SecurityCritical?方法(以避免一些部分受信任的恶意代码尝试通过?SecuritySafeCritical?层攻击这些方法),这一点极为重要。

与?SecurityCritical?代码一样,SecuritySafeCritical?代码必须完全受信任。

具体可以参考:

http://www.sychzs.cn/zh-cn/magazine/ee336023.aspx

?

根据MSDN的解释,问题出在了封装原始Dll的C#类库CardReader.Library上,我们可以在代码级别设置透明性属性可以解决问题。

具体解决办法如下:

1.???????设置ActiveX控件读卡代码的透明属性为:SecuritySafeCritical,设置以后的代码清单如下:

????? ?[SecuritySafeCritical]

????????///?

????????///?读卡

????????///?

????????///?

????????///?

????????private?void?btnRead_Click(object?sender,?EventArgs?e)

????????{

????????????int?i?=?0;

????????????byte[]?data?=?new?byte[16];

????????????byte[]?buff?=?new?byte[32];

?

????????????for?(i?=?0;?i?

????????????????data[i]?=?0;

????????????for?(i?=?0;?i?

????????????????buff[i]?=?0;

?

????????????st?=?MifareOneHelper.rf_read(icdev,?sec?*?4?+?1,?data);

????????????if?(st?==?0)

????????????{

????????????????SerialInterfaceHelper.hex_a(data,?buff,?16);

????????????????txtCardID.Text?=?System.Text.Encoding.ASCII.GetString(buff);

????????????????lblMsg.Text?=?"读取卡号成功!";

????????????}

????????????else

????????????????lblMsg.Text?=?"读取卡号失败!";

?

????????????//test?method

????????????//if?(string.IsNullOrEmpty(txtCardID.Text))

????????????//{

????????????//????lblMsg.Text?=?"读取数据失败!";

????????????//}

????????????//else

????????????//{

????????????//????lblMsg.Text?=?string.Format("读取数据:{0}!",?txtCardID.Text);

????????????//}

????????}

注意要添加引用:using?System.Security;

在这里注掉了测试代码,使用了串口通信和读卡代码。

2.?设置封装原始读卡器Dll的透明属性。

设置M1读卡器帮助类MifareOneHelper的透明属性为:[SecurityCritical],同时设置调用的方法MifareOneHelper.rf_read的

透明属性为[SecurityCritical]。

????设置串口通信帮助类SerialInterfaceHelper的透明属性为:[SecurityCritical],同时设置调用的方法SerialInterfaceHelper.hex_a的

透明属性为[SecurityCritical]。

?

完整代码已提供,还有2个地方需要注意的是,客户端如果安装ActiveX失败,则把运行ActiveX的地址加入到信任站点里,

信任站点的安全级别降低到最低或者设置信任站点关于ActiveX的选项。

/Files/yungboy/CardReader.7

0条大神的评论

发表评论

相关文章

最新资讯