在C#中使用ASV封装编程实践中遇到的问题总结

C#中使用ASV封装编程实践中遇到的问题总结

  1. 许可证问题:不能直接将SVG VIEWER捆绑发布,但可以要求用户自行下载安装。(另:好像某些公司可以从ADOBE获得独立许可)

3.0.1 的缺省安装目录为c:/windows/system32/adobe/svg viewer 3.0

 

3.0.3 版本后,动态设置SVG文件,setSrc会导致内存保护问题,只能在设计阶段指定文件,以下为该问题的ADOBE的描述。

 

Known Issue: SVG 3.03 and later may limit embedding SVG to: Internet Explorer

 

Summary

As a consequence of changes in the ActiveX control needed to prevent security vulnerabilities when hosted by certain classes of applications, the functionality of the control may be impacted when hosted by other applications (Word, Excel, Frame, etc.).


Issue
I'm trying to use the Adobe SVG Viewer (ASV) as an ActiveX control. This works on Adobe SVG Viewer 3.02, but an error occurs and my application exits on Adobe SVG Viewer 3.03.
I use the parameter "C:/svg/mySVG.svg" to invoke method setSrc(string).

Why?

Solution
To fix a security vulnerability (CAN-2005-0918), ASV 3.03 added a test for and disallows cross-domain scripting. This broke the ActiveX control for use in Office and other applications.

The reason:

  • Internet Explorer supports the COM IHtmlDocument2 interface--Office products (and many other applications) do not. 
  • The cross-domain test requires that the host of the ActiveX control implement COM's IHtmlDocument2 interface in order for calls to the setSrc(string) method to succeed.
  • Anyone wanting to use the Adobe SVG Viewer ActiveX control within an application other than IE must somehow ensure the host implements the IHtmlDocument2 interface in order to call setSrc(string) successfully.


Background

http://www.us-cert.gov/cas/bulletins/SB05-131.pdf

 

因此我们只能使用 3.0.2 之前的版本。

 

 

  1. 发布问题

l         ADOBE SVG VIEW下的文件拷贝到发布机器(一般在C:/WINDOWS/system32/Adobe/SVG Viewer 3.0, 包括所有动态库和说明文件)

l         注册COM组件, REGSVR32 NPSVG3.DLL

l         第一次使用时接受ADOBE协议

 

  1. 新建项目的问题:不能动态增加SVG元素的事件处理器,不能通过ECMAScript调用C#对象函数。都是从ECMAScript调用C#存在问题。其它方法好像没有问题,例如增加新的SVG元素,得到或设置属性等。可能是项目配置引起的,使用DEMO项目作为模板建立新项目则没有这个问题。

 

  1. 打开文件,ASV为控件名称

            ASV.setSrc(filename);

 

  1. 使用定时器控制文件的打开状态

            loadDelay = new System.Windows.Forms.Timer();

            loadDelay.Tick += new EventHandler(SVGBegin);

            loadDelay.Interval = 100;

 

//在定时器事件中

private void SVGBegin(Object obj, EventArgs args)

{

               if ( ASV.ReadyState == 4 ) {

                loadDelay.Stop();

           

                // init globals

                svgWindow   = new ASVWindow(ASV);

                svgDocument = svgWindow.svgDocument;

                svgRoot     = svgDocument.rootElement;

              …………

 

  1. 使用ID得到元素,改变属性并增加C#事件处理函数

SVGCircleElement circle = new SVGCircleElement(svgDocument.getElementById("clickMe").Object);

          circle.setAttributeNS(null, "fill", "red");

          circle.addEventListener("mousedown", this, false);

 

public class SvgEventHandler : IEventListener

    {

        public object Object

        {

            get { return this; }

        }

 

        public void handleEvent(object evt)

        {

            MouseEvent e = new MouseEvent(evt);

            MessageBox.Show("C#: Clicked at (" + e.clientX + "," + e.clientY + ")");

        }

}

 

  1. 屏蔽ASV缺省的右键菜单

            e.stopPropagation();

            e.preventDefault();

 

  1. 调用ECMAScript

            string result = (string) svgWindow.InvokeMethod("sayHello", "Billy");

            MessageBox.Show("C#: result = " + result);

 

  1. 调用CSharp

         svgWindow.SetProperty("csharp", this);

              public string sayHello(string name) {

            MessageBox.Show( "C#: Hello, " + name );

            return "Hello, " + name;

        }

 

              //JS脚本中

              var csharp;

 

        function callCSharp(e) {

            if ( window.csharp != null ) {

                var result = csharp.sayHello("Johnny");

 

                alert("ECMAScript: result = " + result);

            } else {

                alert("Unable to call C# method: csharp object not defined");

            }

        }

 

  1. 显示右键菜单并屏蔽ASV缺省右键菜单

            MouseEvent e = new MouseEvent(evt);

            if (e.button == 2)

            {

                e.preventDefault();

                contextMenuStrip1.Show(ASV, e.screenX, e.screenY);

            }

  1. 中文问题,

首先要注意的是字体问题,要在svgviewer中显示中文字体,需要将中文字体名称进行“国际化”,即将汉字字体名称改为英文名称,如将“宋体”改为“Simsun",“黑体”改为"Simhei"等,下面是部分字体对照列表: 

  English Name    Localized Name  

  SimSun                宋体  

  SimHei                黑体  

  FangSong_GB2312       仿宋_GB2312  

  KaiTi_GB2312      楷体_GB2312  

  YouYuan       幼圆  

  STSong       华文宋体  

  STZhongsong      华文中宋  

  STKaiti    华文楷体  

  STFangsong   华文仿宋  

  STXihei    华文细黑  

  STLiti    华文隶书  

  STXingkai    华文行楷  

  STXinwei    华文新魏  

  STHupo    华文琥珀  

  STCaiyun    华文彩云  

  FZYaoTi    方正姚体简体  

  FZShuTi    方正舒体简体  

  NSimSun    新宋体  

LiSu     隶书

例如:

<text font-family="SimSun" x="50" y="190" text-anchor="middle">中文的情况</text>

 

  其次要注意文件编码问题:svg文件保存的时候要选择utf-8编码或者unicode编码,当然svg文件的encoding属性也应该是"utf-8"

例如:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

 

  1. 可以在脚本使用getURL得到数据,但注意文件必须放在有权限的目录下(范围?),不过建议只使用SVG作为显示,而C#中操作数据

//Load quiz data

         getURL("data.xml", fileLoaded);

  }

 

  function fileLoaded (data)

  {

               if(data.success)

               {

                      //alert("ok");

                //return;

                      quiz = new Quiz(data.content);

                      quiz.showCurrentQuestion();

         }

         else

         {

                alert("error");

                return;

         }

  }

 

  1. 使用浏览器控件的脚本不能执行,例如

this.dom = new ActiveXObject("MSXML2.DOMDocument");

         this.dom.loadXML(data);

       建议使用C#中的功能实现

 

  1. 新增节点

            Element elem = svgDocument.createElement("circle");

            String offset = pos.ToString();

            elem.setAttribute("id", name);

            elem.setAttribute("cx", offset);

            elem.setAttribute("cy", offset);

            elem.setAttribute("r", "60");

            elem.setAttribute("fill", "blue");

 

            //<animate attributeName="r" from="1" to="50" dur="5s" repeatCount="indefinite" />

            Element animate = svgDocument.createElement("animate");

            animate.setAttribute("attributeName", "r");

            animate.setAttribute("from", "1");

            animate.setAttribute("to", "60");

            animate.setAttribute("dur", "5s");

            animate.setAttribute("repeatCount", "indefinite");

            elem.appendChild(animate);

 

            svgDocument.rootElement.appendChild(elem);

 

            Text myData = svgDocument.createTextNode(name);

   

            elem = svgDocument.createElement("text");

            elem.setAttribute("x", offset);

            elem.setAttribute("y", offset);

            elem.appendChild(myData);

           

            svgDocument.rootElement.appendChild(elem);

 

            //Add new use

        //public static string svgNS = "http://www.w3.org/2000/svg";

        //public static string xlinkNS = "http://www.w3.org/1999/xlink";

        

            Element elem = svgDocument.createElement("use");

            elem.setAttribute("id", "m2");

            elem.setAttribute("x", "100");

            elem.setAttribute("y", "100");

            elem.setAttribute("width", "100");

            elem.setAttribute("height", "100");

            elem.setAttributeNS(xlinkNS, "href", "#message");

 

            SVGElement g1 = new SVGElement(svgDocument.getElementById("root").Object);

            g1.appendChild(elem);

 

 

  1. 多重消息处理

JSC#中可以同时定义消息处理函数,其处理流程待查。例如在JS中定义οnmοusedοwn="grab(evt)" οnmοusemοve="drag(evt)" οnmοuseup="drop(evt)",在C#

svgRoot.addEventListener("mousedown", this, false);

 

public void handleEvent(object evt) {

            MouseEvent e = new MouseEvent(evt);

            if (e.button == 2)

            {

                e.preventDefault();

                contextMenuStrip1.Show(ASV, e.screenX, e.screenY);

            }

            else if (e.button == 0)

            {

                SVGElement elem = new SVGElement(e.target.Object);

                String[] value ={"id", elem.getAttribute("id")};

                showProperty(value);

            }

以上代码能够实现屏蔽ASV缺省右键菜单,并显示C#右键菜单,而左键不仅能够拖动,而且能够在属性窗口中显示选中图形的属性。

 

  1. C#中使用getElementById判断是否存在重复元素时,不能使用elem == null作为判断条件,而应使用elem.Object == null

Element elem = svgDocument.getElementById(newId);

          if(elem == null)

            break; //Never happen

       正确方法:

              if(elem.Object == null)

           break;

 

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值