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:
Background
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协议
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;
…………
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 + ")");
}
}
e.stopPropagation();
e.preventDefault();
string result = (string) svgWindow.InvokeMethod("sayHello", "Billy");
MessageBox.Show("C#: result = " + result);
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");
}
}
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"?>
//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#右键菜单,而左键不仅能够拖动,而且能够在属性窗口中显示选中图形的属性。
Element elem = svgDocument.getElementById(newId);
if(elem == null)
break; //Never happen
正确方法:
if(elem.Object == null)
break;