C#加载VB的ActiveX.exe 和StdPicture,IPicture
平时很少写心得,研究好几天的东西分享给各位
1. C#如何加载VB6的ActiveX.exe
(1)把ActiveX.exe引用到C#里,调用ActiveX属性为Public公开类,即可引用ActiveX.exe相关功能
(2)C#生成的程序要想运行,需要把引用加载的ActiveX.exe放到<bin>同一目录,并注册ActiveX.exe
(3)注册方式 ActiveX.exe /regserver,可做成bat批处理执行
(4)此时bin内C# exe程序可运行
(5)运行后加载ActiveX.exe会作为新的进程独立运行
(6)C#程序与ActiveX.exe程序之间的通信通过ActiveX.exe开放出来的Function,Event,Property等实现
2. C#进程如何加载VB6进程的StdPicture,IPictureDisp图片
两进程都是自己编写,方法仅做参考
一开始想到StdPicture,IPictureDisp图片存到文件或clipbrd.exe剪切板,再用C#程序加载,功能虽然实现,到不理想
(1)C#引用VB运行库msvbvm60.dll ,会自动生成stdole.dll
(2)VB6中用到PropertyBag把StdPicture,IPicture序列化成Byte数组
(3)C#调用ActiveX.exe相应方法获取此Byte数组,当然也可两进程间SendMessage,Socket,跨进程内存共享传数据,
个人认为这个最简单
(4)C#创建VBRUN.PropertyBag类,参考VB的PropertyBag反序列化成StdPicture,IPicture
附上介绍
程序代码:
'假设Form 上已经存在Picture1的控件,并已经设置好图片
Dim PBag As New PropertyBag
Dim B() As Byte
PBag.WriteProperty "Picture", Picture1.Picture '读取Picture1.Picture 图片并写到 Pbag 容器中
B = PBag.Contents '获取容器Byte 到 B() 数组中,这时 B 就时我们想要获得的Byte数组
'读取 Byte() 数组内容到 Picture
PBag.Contents = B '指定 PBag容器的内容,
'读取容器中的图片
Set Picture1.Picture = PBag.ReadProperty("Picture")
简单的几句代码就可以完成从图片到Byte() ,从Byte()到图片的转换。而且其保存和读取的格式都是使用了原始格式,
即:如果你的图片框读入的是Jpg图片格式,则保存的Byte()数组也是该Jpg格式的数组,而非普通位图的数组,所以你也不用担心转换后的数组很没有压缩,很大。
其实:PropertyBag对象并不止于读取保存图片,它就象一个大麻袋,可以藏任何东西,并放到你想放的地方,具体藏什么 ,是由你决定的。你可以将任何对象保存为Byte(),并在需要的时候读出来
(5)创建AxHost的子类,调用GetPictureFromIPicture方法,把stdole.IPictureDisp转换成Image,之后可加载到 Picture.Box 内
internal class AxHostConverter : AxHost
{
private AxHostConverter() : base("") { }
static public stdole.IPictureDisp ImageToPictureDisp(Image image)
{
return (stdole.IPictureDisp)GetIPictureDispFromPicture(image);
}
static public Image PictureDispToImage(stdole.IPictureDisp pictureDisp)
{
return GetPictureFromIPicture(pictureDisp);
}
static public Image ObjectpToImage(object o)
{
stdole.IPictureDisp pictureDisp = o as stdole.IPictureDisp;
return GetPictureFromIPicture(pictureDisp);
}
}