你的程序需要操纵一类设备, 设备有多种, 需要不同的程序来驱动, 但是大概都是同样的功能.
我遇到的东西是语音卡, 有各种不同的语音卡, 如dialogic, tw等, 甚至还有我自己写来用于测试的一个demo假设备.不同的设备需要有不同的方式来放音, 录音, 拨号等等. 但是都是录音, 放音, 拨号, 收号. 你的程序需要支持这些不同的设备, 而且必须在用户那里选择硬件类型. 怎么办?
我这里采用了一个办法, 就是抽象出一个虚设备基类来, 定义纯虚方法录放音什么的功能, 然后不同的设备都从这里个基类里派生出子类做为驱动程序, 根据客户的要求创建不同的子类对象来, 重载这些统一功能的各由实现, 而在你的主应用程序里实现时, 则只采用基类的抽象方法.
如我就定义了一个基类叫: VCtiDriver, 里面都是一些abstract方法, 还有的就是一些事件的定义, 如:设备打开了呀! 关闭了呀! 等等. 这里不写了呀!
然后其他实际操作不同种设备的子类都从这个类里派生出来, 如drvDialogic, drvDemo之类的, 在各自的实现里override基类里的abstract方法. 这些代码也不用多说了.
关键点在以下两点:
一, 用户选择时, 如何得到所有可以用的设备类型, 也就是从VCtiDriver里派生的全部子类.
二, 用户选择了, 如何从这个已经选择的内容里建立一个实际的对象.
下面是我用的方法:
一, 用户选择时, 如何得到所有可以用的设备类型, 也就是从VCtiDriver里派生的全部子类.
下面就是办法.注意:this是一个form, cmbDrivers是一个combox, 这段代码我放在form_load里,init里也可以.
在combox里放的是驱动程序的类名和程序集名, 必须要用: 全类名 + "," + 程序集的格式才好.
得到一个类的所有派生的子类:
Type typeVCtiDriver = typeof(VCtiDriver);
Assembly asm = typeVCtiDriver.Module.Assembly;
Module [] arMds = asm.GetModules();
foreach(Module md in arMds)
{
Type [] arTypes = md.GetTypes();
foreach(Type t in arTypes)
{
if (t.IsSubclassOf(typeVCtiDriver))
{
this.cmbDrivers.Items.Add(t.FullName + "," + t.Assembly.FullName);
}
}
}
Assembly asm = typeVCtiDriver.Module.Assembly;
Module [] arMds = asm.GetModules();
foreach(Module md in arMds)
{
Type [] arTypes = md.GetTypes();
foreach(Type t in arTypes)
{
if (t.IsSubclassOf(typeVCtiDriver))
{
this.cmbDrivers.Items.Add(t.FullName + "," + t.Assembly.FullName);
}
}
}
用户选择了一个驱动程序项之后, 你可以把那个类名+","+程序集名的字串保存下来, 下次就别让用户再选了, 直接默认比较友好, 这是后话.
二, 用户选择了一个设备, 如何从这个已经选择的内容里建立一个实际的对象.
选择完成之后, 这还只是一个字符串, 需要把这个串变得一个类的对象. 更简单, 下面是代码.
从类名字符串创建该类的实例:
Type typeDrv = Type.GetType(this.cmbDrivers.SelectedItem, false, true);
if (typeDrv == null)
{
MessageBox.Show(this, "没有找到指定的驱动程序, 请用选项菜单重新设置驱动程序类型.");
return;
}
// 用设备驱动程序名来新建程序类。无论什么子类, 都抽象为基类.
VCtiDriver drv = (VCtiDriver) Activator.CreateInstance(typeDrv);
if (typeDrv == null)
{
MessageBox.Show(this, "没有找到指定的驱动程序, 请用选项菜单重新设置驱动程序类型.");
return;
}
// 用设备驱动程序名来新建程序类。无论什么子类, 都抽象为基类.
VCtiDriver drv = (VCtiDriver) Activator.CreateInstance(typeDrv);
好了, 拿drv来用吧, 这个对象就是你的实际的子类对象.
打完收功, 你可以再美化一下, 把类名什么对用户HIDE起来, 想办法用中文的说明来显示之类的都不是问题.