C#写ActiveX控件总结
1.问题的提出。
我们公司的系统一开始是用VC6.0开发的,现在的程序是用C#2.0 vs2005开发的,两个程序之间要进行互相调用。
为了好写命名VC6的com叫 mark.ocx C#的ActiveX叫npr.dll
mark.ocx 要调npr.dll来得到一个文件,当文件打开的时候,文件菜单上就会出现mark.ocx,像批注一样的功能,
批注完成以后,npr.dll要把mark.ocx产生的批注信息放到DataBase里面,就是这样一个调用过程。
2.下面是代码片段
//接口
[Guid("BC5969B4-518A-4590-B332-94BAAAF1C24A")]
public interface IProofRead
...{
PDF接口属性#region PDF接口属性
/**//// <summary>
/// 当前正在校对的报纸
/// </summary>
string PaperCode ...{get;set;}
/**//// <summary>
/// 获取sequence的校次的pdf路径。
/// </summary>
/// <param name="sequence">当前校次</param>
/// <param name="path">路径</param>
/// <returns>得到路径是否成功</returns>
bool GetPdfPath(int sequence, out string path);
#endregion
}
//接口实现
[Guid("EB4CF432-0286-4ec1-9889-8BF3BDCB0882")]
public class ProofRead : IProofRead, IObjectSafety
...{
/**//// <summary>
/// 当前正在校对的报纸
/// </summary>
public string PaperCode
...{
get ...{ return _papercode; }
set ...{ _papercode = value; }
}
/**//// <summary>
/// 获取sequence的校次的pdf路径。
/// </summary>
/// <param name="sequence">校次</param>
/// <param name="path">路径</param>
/// <returns>得到路径是否成功</returns>
public bool GetPdfPath(int sequence, out string path)
...{
//some to do
}
}
[Guid("BC5969B4-518A-4590-B332-94BAAAF1C24A")]
public interface IProofRead
...{
PDF接口属性#region PDF接口属性
/**//// <summary>
/// 当前正在校对的报纸
/// </summary>
string PaperCode ...{get;set;}
/**//// <summary>
/// 获取sequence的校次的pdf路径。
/// </summary>
/// <param name="sequence">当前校次</param>
/// <param name="path">路径</param>
/// <returns>得到路径是否成功</returns>
bool GetPdfPath(int sequence, out string path);
#endregion
}
//接口实现
[Guid("EB4CF432-0286-4ec1-9889-8BF3BDCB0882")]
public class ProofRead : IProofRead, IObjectSafety
...{
/**//// <summary>
/// 当前正在校对的报纸
/// </summary>
public string PaperCode
...{
get ...{ return _papercode; }
set ...{ _papercode = value; }
}
/**//// <summary>
/// 获取sequence的校次的pdf路径。
/// </summary>
/// <param name="sequence">校次</param>
/// <param name="path">路径</param>
/// <returns>得到路径是否成功</returns>
public bool GetPdfPath(int sequence, out string path)
...{
//some to do
}
}
下面是VC6调用的代码:
#if 0
#include <iostream.h>
#import "..ProofPdfCom/ProofPdfCom.tlb" no_namespace
#pragma comment(lib, "comsupp.lib")
#include "comutil.h"
void main(void)
{
// 声明HRESULT和Simple_ATL接口指针
HRESULT hr;
IProofPdfProxy *IFirstATL = NULL;
// 初始化COM
hr = CoInitialize(0);
// 使用SUCCEEDED 宏并检查我们是否能得到一个接口指针
if(SUCCEEDED(hr))
{
hr = CoCreateInstance( CLSID_ProofPdfProxy, NULL, CLSCTX_INPROC_SERVER,
IID_IProofPdfProxy, (void**) &IFirstATL);
// 如果成功,则调用AddNumbers方法,否则显示相应的出错信息
if(SUCCEEDED(hr))
{
string b;
IFirstATL->Getpdf(1,&b);
IFirstATL->Release();
}
else
{
cout << "CoCreateInstance Failed." << endl;
}
// cin.get();
}
// 释放COM
CoUninitialize();
}
#endif
3.关于调试
用C#写的com由于与系统不是同一直进程,没法调试,现在给大家介绍一个好用的调试信息工具;
Dbgview.exe
用法:
[DllImport("KERNEL32.DLL", CharSet = CharSet.Auto, SetLastError = true)]
private static extern void OutputDebugString(char[] lpText);
public static void SpellerViewLog(string errorPlace)
{
#if DEBUG
errorPlace = "调试信息:" + errorPlace;
OutputDebugString(errorPlace.ToCharArray());
#endif
}
public void load()
{
SpellerViewLog("xxx");
}
private static extern void OutputDebugString(char[] lpText);
public static void SpellerViewLog(string errorPlace)
{
#if DEBUG
errorPlace = "调试信息:" + errorPlace;
OutputDebugString(errorPlace.ToCharArray());
#endif
}
public void load()
{
SpellerViewLog("xxx");
}
在运行程序的时候,就打开Dbgview.exe,就可以看到:调试信息:xxx了。
哈哈,就写到这里了,关于源码,我会放到一个专业的控件开发论坛:
小强控件开发论坛。欢迎大家成为一员,为控件开发排疑解惑。