背景
因为公司架构落后,打印模板还是采用了10年的cell组件,二维码不支持,对行打印不支持,所以作为公司在项目上的研发人员,开始有替换公司打印插件的想法。来这个公司之前一直用的是fastreport,各种插件各种支持,再者fastreport有.net版本,可以直接封装为com+。也就理所当然的采用fastreport了。
我甚至还想过,如果com+做不成,我干脆搞成silverlight也行,反正能和js交互就行。
选择Windows 窗体控件库
添加一个label在窗体上,文字就打loaded。以代表你的控件被浏览器正确的识别
// 添加引用
using System.Security;
// 添加这句
[assembly: AllowPartiallyTrustedCallers()]
// 修改这句
[assembly: ComVisible(true)]
选择 工具-> 创建GUID ->复制
引用using System.Runtime.InteropServices;
并在头部加入这样的代码,XXXXXXXXX就代表你的GUID值
[Guid("XXXXXXXXXXXXXXXXXXXXX")]
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
扩展接口
复制如下接口,并且采用刚才生成GUID的方法,再次生成一次GUID,并放入下面的代码里。
[Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD063"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IObjectSafety
{
// methods
void GetInterfacceSafyOptions(
System.Int32 riid,
out System.Int32 pdwSupportedOptions,
out System.Int32 pdwEnabledOptions);
void SetInterfaceSafetyOptions(
System.Int32 riid,
System.Int32 dwOptionsSetMask,
System.Int32 dwEnabledOptions);
}
1. usercontrol需要继承接口
public partial class UserControl1 : UserControl, IObjectSafety
2. 书写接口的方法
// 直接拷贝下面的代码
#region IObjectSafety 成员
public void GetInterfacceSafyOptions(Int32 riid, out Int32 pdwSupportedOptions, out Int32 pdwEnabledOptions)
{
// TODO: 添加 WebCamControl.GetInterfacceSafyOptions 实现
pdwSupportedOptions = 1;
pdwEnabledOptions = 2;
}
public void SetInterfaceSafetyOptions(Int32 riid, Int32 dwOptionsSetMask, Int32 dwEnabledOptions)
{
// TODO: 添加 WebCamControl.SetInterfaceSafetyOptions 实现
}
#endregion
public void print(string xml, bool isDesign = true)
{
using (FastReport.Report report = new FastReport.Report())
{
if (!string.IsNullOrEmpty(xml))
{
report.LoadFromString(xml);
}
if (isDesign)
{
report.Design();
}
else
{
report.Show();
}
}
}
<html lang="zh-cn"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script>
function ddd(){
helloworld.print(null,true);
}
function cc(bb){
//console.log(bb);
debugger;
alert(bb);
}
script>
<body bgcolor='#223344'>
<object id="helloworld"
classid="clsid:1B68C08A-02F5-40B4-9213-FEC5CFB2DF18" Width="184" Height="96"
>
object>
<br>
<input type='button' onclick="ddd()" value='Click'>
body>
html>
其中classid为你usercontrol上面的guid
将VS2013关闭掉,然后以管理员身份运行vs,且加载刚刚我们做的项目。然后生成DLL
此过程中,vs会自动帮我们注册DLL为activex控件
点击允许加载后,如果没有报错,你会看到一个按钮,以及按钮位置上面有个loaded的字样,就代表activex已经加载成功,此时fastreport已经可以成功加载了
新增一个方法
// win为window对象,func为js的方法名字
public void demo(object win, string func)
{
try
{
var htmlWin = win as IHTMLWindow2;
htmlWin.GetType().InvokeMember(func,
BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public,
null, htmlWin, new object[] { "我可以弹出方法来了" });
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
<html lang="zh-cn"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script>
function ddd(){
helloworld.demo(window,"cc");
}
function cc(bb){
//console.log(bb);
debugger;
alert(bb);
}
script>
<body bgcolor='#223344'>
<object id="helloworld"
classid="clsid:1B68C08A-02F5-40B4-9213-FEC5CFB2DF18" Width="184" Height="96"
>
object>
<br>
<input type='button' onclick="ddd()" value='Click'>
body>
html>
如果不出意外,会弹出一个alert的对话框,内容为 “我可以弹出方法来了”
文章写的不够通顺,但以表我这几天心血来潮
文章参考
fastreport.net转BS
http://blog.csdn.net/nihao87224/article/details/46365597
C# 制作activex
http://www.cnblogs.com/homer/archive/2005/01/04/86473.html
http://www.cnblogs.com/homer/archive/2005/01/08/88780.html
http://www.cnblogs.com/homer/archive/2005/01/26/97822.html
activex调用js方法
http://blog.csdn.net/cds27/article/details/7533479
附上我的demo文件
http://download.csdn.net/download/u014577133/9785221