您的位置:首页 > 编程语言 > C#

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

2009-01-14 09:48 531 查看

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

许可证问题:不能直接将SVG VIEWER捆绑发布,但可以要求用户自行下载安装。(另:好像某些公司可以从ADOBE获得独立许可)
<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />3.0.1的缺省安装目录为c:/windows/system32/adobe/svg viewer 3.0
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 

在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.adobe.com/support/techdocs/323585.html

Vulnerability Summary ID is: CAN-2005-0918

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

 

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

 

 

发布问题
l         将ADOBE SVG VIEW下的文件拷贝到发布机器(一般在C:/WINDOWS/system32/Adobe/SVG Viewer 3.0下, 包括所有动态库和说明文件)
l         注册COM组件, REGSVR32 NPSVG3.DLL
l         第一次使用时接受ADOBE协议
 

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

打开文件,ASV为控件名称
            ASV.setSrc(filename);

 

使用定时器控制文件的打开状态
            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;

              …………

 

使用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 + ")");

        }

}

 

屏蔽ASV缺省的右键菜单
            e.stopPropagation();

            e.preventDefault();

 

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

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

 

调用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");
            }
        }
 

显示右键菜单并屏蔽ASV缺省右键菜单
            MouseEvent e = new MouseEvent(evt);

            if (e.button == 2)

            {

                e.preventDefault();

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

            }

中文问题,
首先要注意的是字体问题,要在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"?>
 

可以在脚本使用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;
         }
  }
 

使用浏览器控件的脚本不能执行,例如
this.dom = new ActiveXObject("MSXML2.DOMDocument");
         this.dom.loadXML(data);
       建议使用C#中的功能实现
 

新增节点
            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);

 

 

多重消息处理
在JS和C#中可以同时定义消息处理函数,其处理流程待查。例如在JS中定义onmousedown="grab(evt)" onmousemove="drag(evt)" onmouseup="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#右键菜单,而左键不仅能够拖动,而且能够在属性窗口中显示选中图形的属性。
 

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

          if(elem == null)

            break; //Never happen

       正确方法:
              if(elem.Object == null)

           break;
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息