Adobe AIR右键菜单和系统托盘(Tray)功能以及实现方法

Posted by ms-adobe on 六月 30th, 2009

右键菜单:

  1. var mainMenu:NativeMenu = new NativeMenu();
  2. var minimizeMenu:NativeMenuItem = new NativeMenuItem("Minimize");
  3. var maximizeMenu:NativeMenuItem = new NativeMenuItem("Maximize");
  4. var sepMenu:NativeMenuItem = new NativeMenuItem("",true);
  5. var restoreMenu:NativeMenuItem = new NativeMenuItem("Restore");
  6. var closeMenu:NativeMenuItem = new NativeMenuItem("Close");
  7. minimizeMenu.addEventListener(Event.Select, handleMenuClick);
  8. maximizeMenu.addEventListener(Event.Select, handleMenuClick);
  9. restoreMenu.addEventListener(Event.Select, handleMenuClick);
  10. closeMenu.addEventListener(Event.Select, handleMenuClick);
  11. mainMenu.addItem(minimizeMenu);
  12. mainMenu.addItem(maximizeMenu);
  13. mainMenu.addItem(sepMenu);
  14. mainMenu.addItem(restoreMenu);
  15. mainMenu.addItem(closeMenu);
  16. this.contextMenu=mainMenu;

系统托盘:

  1. var sysTray:SystemTrayIcon =
  2.    NativeApplication.nativeApplication.icon as SystemTrayIcon;
  3.    sysTray.tooltip = "测试tray";
  4.    //
  5.    sysTray.menu = this.contextMenu;
  6.    sysTray.addEventListener(MouseEvent.CLICK,trayClick);

如何将应用程序最小化到托盘,然后给托盘图标加右键菜单以及添加相应的事件,来激活应用程序窗体.

整个流程:

1. 初始化应用时改变系统默认情况下以系统X事件的处理.

2. 定义新处理逻辑(本文是弹出对话框)

3. 生成托盘图标并置于状态栏

4. 给托盘图标加上右键菜单(本文是exit,和open两项)

5. 给菜单加上相应的事件

6. 大功告成

主要方法:

  1. private var dockImage:BitmapData;   
  2.  
  3.               
  4.  
  5.         //初始化Application里调用此方法,完成上面的第一步:   
  6.  
  7.             public function initApplication():void{   
  8.  
  9.                 var loader:Loader=new Loader();   
  10.  
  11.                 loader.contentLoaderInfo.addEventListener(Event.COMPLETE,prepareForSystray);//这里就是完成第一步的任务须,这个prepareForSystray就是对托盘的生在和菜单的控制   
  12.  
  13.                 loader.load(new URLRequest("assets/images/32.png"));//这里先要加载托盘图标的小图片   
  14.  
  15.                 this.addEventListener(Event.CLOSING,closingApplication);//设置关闭体的事件   
  16.  
  17.             }   
  18.  
  19.               
  20.  
  21.         //关闭窗体的事件   
  22.  
  23.             public function closingApplication(event:Event):void{   
  24.  
  25.                 event.preventDefault();//阻止默认的事件   
  26.  
  27.                 Alert.yesLabel="Close";   
  28.  
  29.                 Alert.noLabel="Mini";   
  30.  
  31.                 Alert.show("Close or Minimize?", "Close?", 3, this, alertCloseHandler);//弹出自定义的选择框, 关于Alert的详细用法,参考官方文档或我前面的相关文章.   
  32.  
  33.             }   
  34.  
  35.         //根据用户的选择来判断做什么,这里选择是就是关闭,选择否(Mini)就是最小化到托盘.   
  36.  
  37.         private function alertCloseHandler(event:CloseEvent):void{   
  38.  
  39.             if(event.detail==Alert.YES){   
  40.  
  41.                 closeApp(event);   
  42.  
  43.             }else{   
  44.  
  45.                 dock();//最小化到托盘   
  46.  
  47.             }   
  48.  
  49.         }   
  50.  
  51.           
  52.  
  53.     //生成托盘   
  54.  
  55.         public function prepareForSystray(event:Event):void{   
  56.  
  57.             dockImage=event.target.content.bitmapData;   
  58.  
  59.             if(NativeApplication.supportsSystemTrayIcon){   
  60.  
  61.                 setSystemTrayProperties();//设置托盘菜单的事件   
  62.  
  63.                 SystemTrayIcon(NativeApplication.nativeApplication.icon).menu=createSystrayRootMenu();//生成托盘菜单   
  64.  
  65.             }     
  66.  
  67.         }   
  68.  
  69.           
  70.  
  71.         public function createSystrayRootMenu():NativeMenu{   
  72.  
  73.             var menu:NativeMenu = new NativeMenu();   
  74.  
  75.             var openNativeMenuItem:NativeMenuItem = new NativeMenuItem("Open");//生成OPEN菜单项   
  76.  
  77.             var exitNativeMenuItem:NativeMenuItem = new NativeMenuItem("Exit");//同理   
  78.  
  79.             openNativeMenuItem.addEventListener(Event.SELECT, undock);   
  80.  
  81.             exitNativeMenuItem.addEventListener(Event.SELECT, closeApp);//添加EXIT菜单项事件   
  82.  
  83.             menu.addItem(openNativeMenuItem);   
  84.  
  85.             menu.addItem(new NativeMenuItem("",true));//separator   
  86.  
  87.             menu.addItem(exitNativeMenuItem);//将菜单项加入菜单   
  88.  
  89.  
  90.  
  91.             return menu;   
  92.  
  93.  
  94.  
  95.         }   
  96.  
  97.         //设置托盘图标的事件   
  98.  
  99.         private function setSystemTrayProperties():void{   
  100.  
  101.             SystemTrayIcon(NativeApplication.nativeApplication .icon).tooltip = "TurboSquid squidword";   
  102.  
  103.             SystemTrayIcon(NativeApplication.nativeApplication .icon).addEventListener(MouseEvent.CLICK, undock);   
  104.  
  105.             stage.nativeWindow.addEventListener(NativeWindowDisplayStateEvent.DISPLAY_STATE_CHANGING, nwMinimized);   
  106.  
  107.         }   
  108.  
  109.           
  110.  
  111. //最小化窗体   
  112.  
  113.         private function nwMinimized(displayStateEvent:NativeWindowDisplayStateEvent):void {   
  114.  
  115.             if(displayStateEvent.afterDisplayState == NativeWindowDisplayState.MINIMIZED) {   
  116.  
  117.                 displayStateEvent.preventDefault();//阻止系统默认的关闭窗体事件   
  118.  
  119.                 dock();//将程序放入托盘   
  120.  
  121.             }   
  122.  
  123.         }   
  124.  
  125.  
  126.  
  127.         //将本地应用程序放到托盘   
  128.  
  129.         public function dock():void {   
  130.  
  131.             stage.nativeWindow.visible = false; //设置本地程序窗体不可见   
  132.  
  133.             NativeApplication.nativeApplication.icon.bitmaps = [dockImage];//设置托盘的图标   
  134.  
  135.         }   
  136.  
  137.           
  138.  
  139.         //激活程序窗体   
  140.  
  141.         public function undock(evt:Event):void {   
  142.  
  143.         stage.nativeWindow.visible = true;//设置本地程序窗体可见   
  144.  
  145.         stage.nativeWindow.orderToFront();//设置本地程序窗体到最前端   
  146.  
  147.         NativeApplication.nativeApplication .icon.bitmaps = [];将托盘图标清空   
  148.  
  149.         }   
  150.  
  151.           
  152.  
  153.         //关闭程序窗体   
  154.  
  155.         private function closeApp(evt:Event):void {   
  156.  
  157.             stage.nativeWindow.close();   
  158.  
  159.         }

Adobe AIR — 创建多窗口以及弹出窗口与父窗口的通讯

Posted by ms-adobe on 六月 30th, 2009

转自:http://nlslzf.javaeye.com/blog/292990

今天说一下AIR中的window, 作为桌面应用,免不了会有多窗口存在的可能。所以这也是AIR于Flex web的另一区别。flex web应用的“窗口”都是内部窗口,不管你怎么拖拽它也不会超出flash player的范围。而我们今天说的air中的窗口,是没有范围限制的,任一窗口都可以说是一个“独立”的存在,不受主程序窗口的限制。

Demo主要有以下功能。

1. 简单继承window类创建MyWindow。加入parentWindow属性以及advOpen()方法, 设置MyWindow默认样式。
2. 从主程序中弹出窗口1,从窗口1中弹出窗口2。每个窗口里有image和button
3. 窗口1可以关闭主程序窗口,窗口2可以关闭窗口1。(关闭父窗口)

1. 简单继承window类创建MyWindow。加入parentWindow属性以及advOpen()方法, 设置MyWindow默认样式。

下面是我继承于WIndow的MyWindow,构造方法中设置了默认样式,parentWindow用于在打开窗口时保存父窗口对象。

public class MyWindow extends Window
{
public var parentWindow:Object;

public function MyWindow()
{
this.systemChrome = “none”; //不显示系统窗口
this.showStatusBar = false; //不显示底部状态栏
this.showGripper = false; //不显示底部大小控制按钮
}

/**
* 自定义open()打开窗口并且保存调用此方法的对象
*/
public function advOpen(parentWindow:Object,openWindowActive:Boolean = true):void{
this.parentWindow = parentWindow;
this.open(true)
}

}

2. 从主程序中弹出窗口1,从窗口1中弹出窗口2。每个窗口里有image和button
3. 窗口1可以关闭主程序窗口,窗口2可以关闭窗口1。(关闭父窗口)

下面是窗口1类,继承于MyWindow。在主程序中用了与下面相同的openWin打开窗口1,可以看倒在调用winX.advOpen时传入了当前对象作为被打开窗口的parentWindow. 下面的closeParent()中利用保存的 parentWindow关闭父窗口。



< ![CDATA[
import mx.core.Window;

//打开窗口2
private function openWin():void{
var win2:PicTwo = new PicTwo();
win2.advOpen(this);
win2.move(500,50)
}

//关闭父窗口
private function closeParent():void{
if(this.parentWindow.hasOwnProperty("close")){ //检查父窗口中是否有close方法。
this.parentWindow.close(); //调用父窗口的close方法
}
}
]]>






主程序



< ![CDATA[
import mx.core.Window;
private function openWin():void{
//新建window对象
var win:PicOne = new PicOne();
win.advOpen(this); //弹出窗口
win.move(50,50);

}
]]>




Adobe AIR 监测网络状态,离线/在线应用程序的实现

Posted by ms-adobe on 六月 30th, 2009

转自:http://www.flextheworld.com/2009/01/adobe-air-web-status.html

AIR与Flex web应用的另一区别在于可以动态监测网络状态,可以让开发者在网络连通或断线时用不同的方式处理程序,在Demo中我将用以下情况来表现AIR的离线与在线应用。

1. 用户在文本框中输入内容。文本框下方的保存按钮会动态显示当前网络状态: (在线)保存与(离线)保存.
2. 在用户点击保存按钮时如果网络在线,将对话框内容保存在服务器。
3. 如果保存时处于断线状态,将内容保存在本地文件中。
4. 当网络恢复时检查本地文件,如果有已经保存的内容,将内容传入服务器。

源代码很简单,不到100行,大家可以在最下方下载。现在我开始讲解

Demo操作方法
1. 按装运行demo,如果网络连接正常,你会看到文本框下的按钮为 (在线) 保存。
2. 输入任意信息,点击 (在线)保存 。你会看倒信息 “内容已上传服务器”。
3. 切断网络。大概3-5秒后你会看到文本框下方按钮变为(离线)保存。
4. 点击保存,你会看倒信息“内容已经在本地保存,会在下次连线时自动上传到服务器”。
5. 接痛网络,大概3--5秒后你会看倒信息 “缓存内容已上传服务器”。
6. Demo结束。

1. 启动应用程序后监控网络状态。
我们在 App的CreationComplete()中调用netWorkSyc来监控网络状态。

private function networkSyc():void{
//创建一个联接,使用HEAD表示不需要加载玩全部的页面。
var request:URLRequest = new URLRequest( “http://www.google.com”);
request.method = “HEAD”;

//用url创建监测对象,每3秒检查一次网络状态,如果网络状态发生变化,将结果返回到netWorkStatusHandle()
urlMonitor = new URLMonitor(request);
urlMonitor.pollInterval = 3000;
urlMonitor.addEventListener(StatusEvent.STATUS,netWorkStatusHandle);
urlMonitor.start();
}

//网络状态改变时响应该事件
private function netWorkStatusHandle(e:StatusEvent):void{
if(urlMonitor.available){
//如果有本地文件,假装上传服务器
if(this.checkLoaclFile()){
//Kevin TODO 上传服务骑
this.showAlert(”缓存内容已上传服务器”);
}
saveBtn.label = “(在线)保存”
}else{
saveBtn.label = “(离线)保存”
}
}

上面的networkSyc()方法中我使用了两个类的对象来实现网络监控,URLRequest 和 URLMonitor。我用URLRequest来建立一个连接对象request,连接的地址是www.google.com。然后已request作为构造参数创建URLMonitor对象。我就是靠它来完成对网络状态的监控。

监控原理很简单,当第一次执行networkSyc()时,urlMonitor会尝试连接www.google.com,然后将连接的结果发回到 netWorkStatusHandle(), 如果连接成功,urlMonitor.available会为true,反之为false。接下来每3秒检查一次网络状态,如果发生改变(连接成功变为连接失败或者连接失败变为连接成功),那么将再度触发StatusEvent.STATUS事件,调用netWorkStatusHandle()返回网络状态。

以上就是AIR监控网络的方式,大家如果感兴趣想知道更多URLMonitor的内容,可以在Help中搜索ServiceMonitor,它的sub class就是URLMonitor和SockterMonitor。

Demo中并没有真正在本地保存文件,保存与读取文件的方法我会在下一篇教程–“AIR的文件操作”中教给大家。

AIR APIs详解-文件系统访问(3)读取文本类型文件到文本框

Posted by ms-adobe on 六月 30th, 2009
  1. //打开类型为txt和xml的文件。
  2. private function openFile():void{
  3. var file:File = File.documentsDirectory;
  4. var openFileFilter:FileFilter = new FileFilter(”Text/XML”, “*.txt;*.xml”); //过滤文件
  5. file.browseForOpen(”请选择要打开的文件”,[openFileFilter]); //打开文件选择器
  6. file.addEventListener(Event.SELECT,fileSelectHandle) //监听文件选择事件
  7. }
  8.  
  9. //将打开文件内容写入文本框
  10. private function fileSelectHandle(e:Event):void{
  11. var file:File = e.target as File;
  12. fileStream.open(file,FileMode.READ);
  13. this.content.text = fileStream.readUTFBytes(fileStream.bytesAvailable) //只读方式打开文件,将内容放到TextArea
  14. this.updateBtn.enabled = true;
  15. this.saveNew.enabled = false;
  16. fileStream.open(file,FileMode.WRITE); //以Write方式重新打开文件,这样我们就可以更新它
  17.  
  18. }
  19.  
  20. //重新以文本框的内容更新打开的文件。
  21. //更新打开的文件
  22. private function saveOpenFile():void{
  23. fileStream.writeUTFBytes(this.content.text); //更新打开的文件
  24. fileStream.close() Alert.show(”文件更新成功”,”提示”)
  25. this.updateBtn.enabled = false;
  26. this.saveNew.enabled = true;
  27. }

AIR APIs详解-文件系统访问(2)保存文本内容到指定路径

Posted by ms-adobe on 六月 30th, 2009

没什么好看的.直接来代码

  1. //打开文件选择器 private function saveFileTo():void{
  2. var file:File = File.documentsDirectory; //默认为文档文件夹
  3. file.browseForDirectory("请选择保存路径"); //打开文件夹选择器
  4. file.addEventListener(Event.SELECT,directoySelectHandle) //监听文件夹选择事件
  5. }
  6.  
  7. //用文本框内容创建文件
  8. private function directoySelectHandle(e:Event):void{
  9. var file:File = new File(e.target.nativePath).resolvePath("saveFileDemo.xml"); //创建名为saveFileDemo.xml的文件
  10. fileStream.open(file,FileMode.WRITE); //Write方式打开
  11. var content:XML =
  12. {this.content.text}
  13.  
  14. fileStream.writeUTFBytes(content.toXMLString()); //将内容写入文件
  15. fileStream.close()
  16. Alert.show(”文件创建成功”,”提示”)
  17.  
  18. }

Flex,AIR读取本地XML文件

Posted by ms-adobe on 六月 30th, 2009

读取外部 XML 文档
可以使用 URLLoader 类从 URL 加载 XML 数据。要在应用程序中使用以下代码,请将示
例中的 XML_URL 值替换为有效的 URL:
var myXML:XML = new XML();
var XML_URL:String = “http://www.example.com/Sample3.xml”;
var myXMLURL:URLRequest = new URLRequest(XML_URL);
var myLoader:URLLoader = new URLLoader(myXMLURL);
myLoader.addEventListener(”complete”, xmlLoaded);
function xmlLoaded(event:Event):void
{
myXML = XML(myLoader.data);
trace(”Data loaded.”);
}
还可以使用 XMLSocket 类设置与服务器的异步 XML 套接字连接。有关详细信息,请参阅
《ActionScript 3.0 语言和组件参考》。

AIR APIs详解-文件系统访问(1)

Posted by ms-adobe on 六月 30th, 2009

AIR最大的特点是利用开发人员掌握的Web技术来开发桌面应用。桌面应用有一个最为显著的特点,就是可以访问操作用户的文件系统,AIR也内置了访问用户文件系统的API集合。在我开始讲解这部分API前,你需要先知道一些创作应用的原则,这样可以保证你开发的AIR应用不被大多数用户反感。

原则1:AIR访问文件系统API具备了操作用户文件系统的强大能力,是一把双刃剑,请谨慎使用,不是每个用户都会因为你的AIR应用可以操作他们的本地文件系统而去体验下载和安装它,恰恰相反,他们极有可能对你的应用避而远之。
原则2:在你的应用文档和各方面描述中加入对于用户文件系统访问的具体描述,个人免费应用是为了确保用户知道这些功能的存在,而商业AIR应用更应该将这部分写入EULA中,否则极有可能在某一天收到法院的传票。
原则3:在应用中,当有事件触发访问用户文件系统的操作时,先给与用户必要的信息提示,待用户确认操作后再执行文件系统访问的功能,这样会非常友善,不至于你的应用遭到某些用户的强烈反感。

好了,原则说完了,开始解析技术的部分。
AIR访问文件系统的功能类全部来自一个扩展的API集合,flash.filesytem,其中包含了3个类File,FileStream和FileMode。这个文章没有对于这3个类的详细描述,你可以从下面的链接找到中文版本的类库参考:

AIR中文语言参考-访问文件系统部分

该文档是一个Language Reference,更加适合做为语言手册,随时查询。

File,FileStream和FileMode这三个类提供了用户通过AIR应用执行对于文件系统(文件和文件夹)的读,写,移动,拷贝和删除等任务,注意,AIR API中没有专门针对文件夹访问操作的类。为什么?很简单,我们对于文件系统的访问操作过程里,对于文件的操作,无时无刻都在牵扯到与之相关的文件夹操作(开发人员经常称为Directory Path或者Content Path)。你的操作可以使用File类的只读属性isDirectory来判断File对象实例是否指向文件夹还是文件。

在我们这个系列的API详解的文章中,我本人不会把Language Reference中与这三个类有关的所有属性和方法都讲一遍,实在是没有那个必要,所以在此再次强调Language Reference的重要性,那就是当你看懂我的文章后,你动手还是需要像Language Reference这样的帮助,我认为没有任何文档可以替代它。

File类的衍生关系相当清晰:File->FileReference->EventDispatcher-> Object,注意,FileReference就不是AIR独有的类了,而是来自于Flash Player的flash.net包。回到文件访问的API上来,有了上述的三个类,你可以通过他们实现在Windows,MACOSX和Linux上同样的操作,这就是跨平台。 文件类File有几个public标识符的属性非常重要,也是作为开发人员经常用到的,比如:

1. 只读属性exist,表示文件或文件夹是否存在,返回值是true或者false
2. 文件对象的路径url,字符串格式
3. 文件对象是否隐藏isHidden,布尔类型,返回值是true或者false
4. 文件对象是否是文件夹isDirectory,布尔类型,返回值是true或者false,对于这个属性,各位一定要牢记,以我的经验,用到次数最多的就是它。

此外,File类还有一些其他有用的静态属性,也值得提一下:

File.applicationStorageDirectory — 每个已安装的 AIR 应用程序独有的存储目录文件夹
File.applicationDirectory — 安装应用程序的只读目录(其中包括所有已安装的资源)
File.desktopDirectory — 用户的桌面目录
File.documentsDirectory — 用户的文档目录
File.userDirectory — 用户目录

语言参考对于上面的属性解释相当详细,而且很容易懂。文件类此外还有一些方法,比如copyTo,moveTo,deleteDirectory等等,我们以后的文章会单独进行解释。FileMode类和FileStream类,我们也在以后的文章中陆续讲解。一句话,分来了慢慢讲,贪多嚼不烂,:)

现在将告诉各位如何创建一个文件夹,借此来直接激发刚刚接触此部分API开发人员的积极性。简单而言,基于文件系统创建一个文件夹非常简单,一般来说分成2步:

1. 创建一个File对象,赋予一个不存在的文件夹路径
2. 基于该对象使用createDirectory()方法

通过上面的2个步骤,我们直接来看一段代码:

< ?xml version="1.0" encoding="utf-8"?>


< ![CDATA[
import flash.filesystem.File;
private function createDirectory():void{
var newDirectory:File =File.desktopDirectory.resolvePath("我的AIR文件夹");
newDirectory.createDirectory();
}
]]>

你尝试在FlexBuilder3里创建一个Flex Project,类型是AIR Desktop,之后,将上面的代码粘贴到你的MainApplication中,运行,看看你的桌面上是否多了一个叫做“我的AIR文件夹”的目录。这个例子中的中文文件夹名称完全没问题,只是建议你最好使用英文和数字来合理命名你的文件夹,以确保可以运行在其他语言的操作系统上,这里仅仅是为了测试直观方便才使用中文的。这里使用了desktopDirectory来将要创建的文件夹对象指向了你的桌面,请不要担心是windows还是MACOS,只管记住这个属性就好了。resolvePath这个方法将一个当前叫做“我的AIR文件夹”的命名附加到File对象上去来决定文件夹的命名,然后使用createDirectory方法来创建。

好了,现在你会通过AIR API创建一个新的文件夹了。当然你可能有更多需求,比如创建前检测一下之类的小功能,这也是完全可行的,那么我们下篇文章继续。

我们用到了File类的desktopDirectory这个内置属性,听这个名字,就知道是直接将AIR应用的File对象路径指向用户桌面。我们在前面就轻轻地提及了其他几个静态属性:

File.applicationStorageDirectory — 每个已安装的 AIR 应用程序独有的存储目录文件夹
File.applicationDirectory — 安装应用程序的只读目录(其中包括所有已安装的资源)
File.documentsDirectory — 用户的文档目录
File.userDirectory — 用户目录

我认为有必要进一步做个解释了,因为有人可能会在这里有疑问。且看下面:

开发者疑问:为什么File类就要带这几个静态属性,如果我的AIR应用是要访问用户C盘或者D盘路径下的某个文件夹呢,是不是不允许?
我的回答是,AIR在File类提供这几个静态属性,是为了保证开发人员使用这些静态属性的值去访问用户文件系统时,能够高度保持应用跨平台的一致性。就像前面的例子里的这部分代码:

var newDirectory:File =File.desktopDirectory.resolvePath(”我的AIR文件夹”);
newDirectory.createDirectory();

当Windows用户执行AIR应用时,desktopDirectory会自动帮你映射到Windows系统的桌面路径;而同样的应用,当被MACOSX用户执行时,desktopDirectory也同样会自动帮你映射到MACOSX的桌面上去,这就通过了desktopDirectory保证了跨平台应用访问路径的一致性。再深究一下,desktopDirectory属性在我的Windows下指的是:

C:\Documents and Settings\zma\Desktop\

而在我的MACOSX下则指向:

/Users/zma/Desktop/

如果按照开发者说的,随意指定一个系统路径来访问文件系统,未尝不可。假定前面随意路径就是指向我windows系统的桌面,我就可以这样去定义:

var newDirectory:File =new File(”C:\\Documents and Settings\\zma\\Desktop\\我的AIR文件夹”);
//或者你使用正斜杠
//var newDirectory:File=new File(”C:/Documents and Settings/zma/Desktop/我的AIR文件夹”);
newDirectory.createDirectory();

结果一样,仍然会在Windows桌面上创建一个叫做我的AIR文件夹的目录,但是局限性就来了,因为你用这种方式只能工作在Windows操作系统里,假如你的应用中创建文件夹和文件是一个重要的工作(比如存储一个文件到某文件夹),你的应用在MACOSX系统里就完全不工作。有没有办法改正?有,用Flash Player API判断用户系统,然后用判断的结果值分开来写访问用户文件系统的逻辑,Win一套,MAC一套,Linux一套…乃至到未来的smartphone上一套,优点是灵活,缺点是代码工作量骤然提升。所以,推荐各位将访问文件系统的File对象尽量绑定在几个内置属性的映射路径上,既方便,又不用考虑目标系统,而且还友善,因为没有用户愿意你的AIR应用打开人家C盘windows文件夹去生成一个目录或新文件,MACOSX就好很多,因为要sudo才能获得某些文件夹的读写和创建删除权限。所以,AIR应用推荐使用File的几个默认内置静态属性,你好我好大家好,皆大欢喜。

比Flex Component Explorer更强大的“Tour de Flex”

Posted by ms-adobe on 六月 27th, 2009

转自:http://www.riahome.cn/?p=411

Tour de Flex

Tour de Flex

Flex的一整套组件的确是很庞大,要掌握不容易。Flex Component Explorer(这里下载)的存在,学会使用组件变得容易直观。今天早上,发现了这个好工具:Tour de Flex!不但具有前人没有的,它还多了很多乱七八糟的东西(当然,我这个“乱七八糟”是褒义的):

Flex核心组件 (这部分是对Flex Component Explorer的扩展,增加了一些如Data Binding等演示)
Flex数据访问 (包含HTTPService, WebService, RemoteObject等)
AIR特性
Cloud APIs (包含如Flicker, Google API等各种Cloud计算服务的案例)
数据可视化 (包含ILOG Elixir等组件库)
Mapping (包含Yahoo Map和Google Map等地图API的应用)
其他Component
它采用AIR技术,文件有51.7MB之大,我电脑的分辨率是1280×800,高度不够,使用此工具有点不方便,但它的功能的确很强大,不妨下载一试。

英文介绍:点击这里(在线安装也在此)
中文介绍:点击这里
.air下载:点击这里

tourDeFlex_screenshot

我想学习JAVA,弄一个自己的搜索引擎,方便大家使用的搜索引擎

Posted by ms-adobe on 六月 27th, 2009

我想学习JAVA,弄一个自己的搜索引擎,方便大家使用的搜索引擎,当然可能用到的技术会更多,像asp.net,jsp,php,C#,我觉得这是基本的了.一点一点开始吧.

转自:http://hi.baidu.com/skew/blog/item/6aa1be51f31a478f8d543044.html

搜索引擎发展史1990年以前,没有任何人能搜索互联网。
所有搜索引擎的祖先,是1990年由Montreal的McGill University学生Alan Emtage、Peter Deutsch、Bill Wheelan发明的Archie(Archie FAQ)。虽然当时World Wide Web还未出现,但网络中文件传输还是相当频繁的,由于大量的文件散布在各个分散的FTP主机中,查询起来非常不便,因此Alan Emtage等想到了开发一个可以用文件名查找文件的系统,于是便有了Archie。Archie是第一个自动索引互联网上匿名FTP网站文件的程序,但它还不是真正的搜索引擎。Archie是一个可搜索的FTP文件名列表,用户必须输入精确的文件名搜索,然后Archie会告诉用户哪一个FTP地址可以下载该文件。

由于Archie深受欢迎,受其启发,Nevada System Computing Services大学于1993年开发了一个Gopher(Gopher FAQ)搜索工具Veronica(Veronica FAQ)。Jughead是后来另一个Gopher搜索工具。

Robot(机器人)一词对编程者有特殊的意义。Computer Robot是指某个能以人类无法达到的速度不断重复执行某项任务的自动程序。由于专门用于检索信息的Robot程序象蜘蛛(spider)一样在网络间爬来爬去,因此,搜索引擎的Robot程序被称为spider(Spider FAQ)程序。世界上第一个Spider程序,是MIT Matthew Gray的World wide Web Wanderer,用于追踪互联网发展规模。刚开始它只用来统计互联网上的服务器数量,后来则发展为也能够捕获网址(URL)。

与Wanderer相对应,1993年10月Martijn Koster创建了ALIWEB(Martijn Koster Annouces the Availability of Aliweb),它相当于Archie的HTTP版本。ALIWEB不使用网络搜寻Robot,如果网站主管们希望自己的网页被ALIWEB收录,需要自己提交每一个网页的简介索引信息,类似于后来大家熟知的Yahoo。
随着互联网的迅速发展,使得检索所有新出现的网页变得越来越困难,因此,在Wanderer基础上,一些编程者将传统的Spider程序工作原理作了些改进。其设想是,既然所有网页都可能有连向其他网站的链接,那么从一个网站开始,跟踪所有网页上的所有链接,就有可能检索整个互联网。到1993年底,一些基于此原理的搜索引擎开始纷纷涌现,其中最负盛名的三个是:Scotland的JumpStation、Colorado 大学Oliver McBryan的The World Wide Web Worm(First Mention of McBryan’s World Wide Web Worm)、NASA的Repository-Based Software Engineering (RBSE) spider。JumpStation和WWW Worm只是以搜索工具在数据库中找到匹配信息的先后次序排列搜索结果,因此毫无信息关联度可言。而RBSE是第一个索引Html文件正文的搜索引擎,也是第一个在搜索结果排列中引入关键字串匹配程度概念的引擎。

Excite 的历史可以上溯到1993年2月,6个Stanford(斯坦福)大学生的想法是分析字词关系,以对互联网上的大量信息作更有效的检索。到1993年中,这已是一个完全投资项目Architext,他们还发布了一个供webmasters在自己网站上使用的搜索软件版本,后来被叫做Excite for Web Servers。(注:Excite后来曾以概念搜索闻名,2002年5月,被Infospace收购的Excite停止自己的搜索引擎,改用元搜索引擎Dogpile)

1994年1月,第一个既可搜索又可浏览的分类目录EINet Galaxy(Tradewave Galaxy)上线。除了网站搜索,它还支持Gopher和Telnet搜索。

1994年4月,Stanford University的两名博士生,美籍华人Jerry Yang(杨致远)和David Filo共同创办了Yahoo(Jerry Yang Alerts a Usenet group to the Yahoo Database ,1996年的Yahoo)。随着访问量和收录链接数的增长,Yahoo目录开始支持简单的数据库搜索。因为Yahoo!的数据是手工输入的,所以不能真正被归为搜索引擎,事实上只是一个可搜索的目录。Wanderer只抓取URL,但URL信息含量太小,很多信息难以单靠URL说清楚,搜索效率很低。Yahoo!中收录的网站,因为都附有简介信息,所以搜索效率明显提高。(注:Yahoo以后陆续使用Altavista、Inktomi、Google提供搜索引擎服务)

1994年初,Washington大学CS学生Brian Pinkerton开始了他的小项目WebCrawler(Brian Pinkerton Announces the Availability of Webcrawler)。1994年4月20日,WebCrawler正式亮相时仅包含来自6000个服务器的内容。WebCrawler是互联网上第一个支持搜索文件全部文字的全文搜索引擎,在它之前,用户只能通过URL和摘要搜索,摘要一般来自人工评论或程序自动取正文的前100个字。(后来webcrawler陆续被AOL和Excite收购,现在和excite一样改用元搜索引擎Dogpile)

Lycos(Carnegie Mellon University Center for Machine Translation Announces Lycos )是搜索引擎史上又一个重要的进步。Carnegie Mellon University的Michael Mauldin将John Leavitt的spider程序接入到其索引程序中,创建了Lycos。1994年7月20日,数据量为54,000的Lycos正式发布。除了相关性排序外,Lycos还提供了前缀匹配和字符相近限制,Lycos第一个在搜索结果中使用了网页自动摘要,而最大的优势还是它远胜过其它搜索引擎的数据量:1994年8月--394,000 documents;1995年1月--1.5 million documents;1996年11月--over 60 million documents。(注:1999年4月,Lycos停止自己的Spider,改由Fast提供搜索引擎服务)
Infoseek(Steve Kirsch Announces Free Demos Of the Infoseek Search Engine)是另一个重要的搜索引擎,虽然公司声称1994年1月已创立,但直到年底它的搜索引擎才与公众见面。起初,Infoseek只是一个不起眼的搜索引擎,它沿袭Yahoo!和Lycos的概念,并没有什么独特的革新。但是它的发展史和后来受到的众口称赞证明,起初第一个登台并不总是很重要。Infoseek友善的用户界面、大量附加服务(such as UPS tracking, News, a directory, and the like) 使它声望日隆。而1995年12月与Netscape的战略性协议,使它成为一个强势搜索引擎:当用户点击Netscape浏览器上的搜索按钮时,弹出Infoseek的搜索服务,而此前由Yahoo!提供该服务。(注:Infoseek后来曾以相关性闻名,2001年2月,Infoseek停止了自己的搜索引擎,开始改用Overture的搜索结果)

1995年,一种新的搜索引擎形式出现了??元搜索引擎(A Meta Search Engine Roundup)。用户只需提交一次搜索请求,由元搜索引擎负责转换处理后提交给多个预先选定的独立搜索引擎,并将从各独立搜索引擎返回的所有查询结果,集中起来处理后再返回给用户。第一个元搜索引擎,是Washington大学硕士生 Eric Selberg 和 Oren Etzioni 的 Metacrawler。元搜索引擎概念上好听,但搜索效果始终不理想,所以没有哪个元搜索引擎有过强势地位。

DEC的AltaVista(2001年夏季起部分网友需通过p-roxy访问,无p-roxy可用qbseach单选altavista搜索,只能显示第一页搜索结果)是一个迟到者,1995年12月才登场亮相(AltaVista Public Beta Press Release )。但是,大量的创新功能使它迅速到达当时搜索引擎的顶峰。Altavista最突出的优势是它的速度(搜索引擎9238:比较搞笑,设计altavista的目的,据说只是为了展示DEC Alpha芯片的强大运算能力)。
而Altavista的另一些新功能,则永远改变了搜索引擎的定义。
AltaVista是第一个支持自然语言搜索的搜索引擎,AltaVista是第一个实现高级搜索语法的搜索引擎(如AND, OR, NOT等)。用户可以用AltaVista搜索Newsgroups(新闻组)的内容并从互联网上获得文章,还可以搜索图片名称中的文字、搜索Titles、搜索Java applets、搜索ActiveX objects。AltaVista也声称是第一个支持用户自己向网页索引库提交或删除URL的搜索引擎,并能在24小时内上线。AltaVista最有趣的新功能之一,是搜索有链接指向某个URL的所有网站。在面向用户的界面上,AltaVista也作了大量革新。它在搜索框区域下放了“tips”以帮助用户更好的表达搜索式,这些小tip经常更新,这样,在搜索过几次以后,用户会看到很多他们可能从来不知道的的有趣功能。这系列功能,逐渐被其它搜索引擎广泛采用。1997年,AltaVista发布了一个图形演示系统LiveTopics,帮助用户从成千上万的搜索结果中找到想要的。
然后到来的是HotBot。1995年9月26日,加州伯克利分校CS助教Eric Brewer、博士生Paul Gauthier创立了Inktomi(UC Berkeley Announces Inktomi),1996年5月20日,Inktomi公司成立,强大的HotBot出现在世人面前。声称每天能抓取索引1千万页以上,所以有远超过其它搜索引擎的新内容。HotBot也大量运用cookie储存用户的个人搜索喜好设置。(Hotbot曾是随后几年最受欢迎的搜索引擎之一,后被Lycos收购)

Northernlight 公司于1995年9月成立于马萨诸塞州剑桥,1997年8月,Northernlight搜索引擎正式现身。它曾是拥有最大数据库的搜索引擎之一,它没有Stop Words,它有出色的Current News、7,100多出版物组成的Special Collection、良好的高级搜索语法,第一个支持对搜索结果进行简单的自动分类。(2002年1月16日,Northernlight公共搜索引擎关闭,随后被divine收购,但在Nlresearch,选中”World Wide Web only”,仍可使用Northernlight搜索引擎)

1998年10月之前,Google只是Stanford大学的一个小项目BackRub。1995年博士生Larry Page开始学习搜索引擎设计,于1997年9月15日注册了google.com的域名,1997年底,在Sergey Brin和Scott Hassan、Alan Steremberg的共同参与下,BachRub开始提供Demo。1999年2月,Google完成了从Alpha版到Beta版的蜕变。Google公司则把1998年9月27日认作自己的生日。
Google在Pagerank、动态摘要、网页快照、DailyRefresh、多文档格式支持、地图股票词典寻人等集成搜索、多语言支持、用户界面等功能上的革新,象Altavista一样,再一次永远改变了搜索引擎的定义。
在2000年中以前,Google虽然以搜索准确性备受赞誉,但因为数据库不如其它搜索引擎大,缺乏高级搜索语法,所以使用价值不是很高,推广并不快。直到2000年中数据库升级后,又借被Yahoo选作搜索引擎的东风,才一飞冲天。

Fast(Alltheweb)公司创立于1997年,是挪威科技大学(NTNU)学术研究的副产品。1999年5月,发布了自己的搜索引擎AllTheWeb。Fast创立的目标是做世界上最大和最快的搜索引擎,几年来庶几近之。Fast(Alltheweb)的网页搜索可利用ODP自动分类,支持Flash和pdf搜索,支持多语言搜索,还提供新闻搜索、图像搜索、视频、MP3、和FTP搜索,拥有极其强大的高级搜索功能。

Teoma 起源于1998年Rutgers大学的一个项目。Apostolos Gerasoulis教授带领华裔Tao Yang教授等人创立Teoma于新泽西Piscataway,2001年春初次登场,2001年9月被提问式搜索引擎Ask Jeeves收购,2002年4月再次发布。Teoma的数据库目前仍偏小,但有两个出彩的功能:支持类似自动分类的Refine;同时提供专业链接目录的Resources。
Wisenut 由韩裔Yeogirl Yun创立。2001年春季发布Beta版,2001年9月5日发布正式版,2002年4月被分类目录提供商looksmart收购。wisenut也有两个出彩的功能:包含类似自动分类和相关检索词的WiseGuide;预览搜索结果的Sneak-a-Peek。

Gigablast 由前Infoseek工程师Matt Wells创立,2002年3月展示pre-beta版,2002年7月21日发布Beta版。Gigablast的数据库目前仍偏小,但也提供网页快照,一个特色功能是即时索引网页,你的网页刚提交它就能搜索(注:这个spammers的肉包子功能暂已关闭)。

Openfind 创立于1998年1月,其技术源自台湾中正大学吴升教授所领导的GAIS实验室。Openfind起先只做中文搜索引擎,曾经是最好的中文搜索引擎,鼎盛时期同时为三大著名门户新浪、奇摩、雅虎提供中文搜索引擎,但2000年后市场逐渐被Baidu和Google瓜分。2002年6月,Openfind重新发布基于GAIS30 Project的Openfind搜索引擎Beta版,推出多元排序(PolyRankTM),宣布累计抓取网页35亿,开始进入英文搜索领域,此后技术升级明显加快。

北大天网 是国家”九五”重点科技攻关项目”中文编码和分布式中英文信息发现”的研究成果,由北大计算机系网络与分布式系统研究室开发,于1997年10月29日正式在CERNET上提供服务。2000年初成立天网搜索引擎新课题组,由国家973重点基础研究发展规划项目基金资助开发,收录网页约6000万,利用教育网优势,有强大的ftp搜索功能。

Baidu 2000年1月,超链分析专利发明人、前Infoseek资深工程师李彦宏与好友徐勇(加州伯克利分校博士)在北京中关村创立了百度(Baidu)公司。2001年8月发布Baidu.com搜索引擎Beta版(此前Baidu只为其它门户网站搜狐新浪Tom等提供搜索引擎),2001年10月22日正式发布Baidu搜索引擎。Baidu虽然只提供中文搜索,但目前收录中文网页超过9000万,可能是最大的的中文数据库。Baidu搜索引擎的其它特色包括:网页快照、网页预览/预览全部网页、相关搜索词、错别字纠正提示、新闻搜索、Flash搜索、信息快递搜索。2002年3月闪电计划(Blitzen Project)开始后,技术升级明显加快。

百度:中国版Google 神话能走多远
中国搜索引擎公司百度8月5日在美国纳斯达克上市,发行价为27美元。当日盘中一度突破150美元,最后以122.54美元收盘,涨幅高达353.85%。百度的出色表现使之成为在美国上市的外国公司中,上市首日表现最好的一只股票。

多种利好助涨股价百度上市首日如此强劲的表现,主要有两方面的原因:
首先,是google 的示范效应。投资者经常将百度和Google 相提并论,认为该公司是中国版的Google 。有分析师认为,百度之所以受到如此追捧,是因为它结合了“中国”和“搜索”这两大热点。
全球最大的搜索服务提供商Google 上市发行价也不足一百美元,但上市一年以来股价已经超过三百美元,显示搜索市场有巨大潜力。而中国互联网的迅速普及,网民数量急剧膨胀,中国市场的广阔性已被国外投资者普遍看好。
其次,中国概念股的魅力。中国已经是世界上最大的电脑市场并拥有世界上第二大的上网人数,中国网民数已经突破1亿。百度在这一市场占有很大的份额。加上人民币升值,国外投资者普遍看好中国,看好搜索市场,因此百度才会受到了投资者的偏爱。
创业之路回顾百度的发展史,公司和盛大类似,也是把握了互联网产业快速发展的时机,并找到了适合自身的快速发展途径。
百度于1999年底成立于美国硅谷,它的创始人,百度公司总裁李彦宏是资深信息检索技术专家、超链分析专利的唯一持有人。
百度创立初,公司选择了与其他专业搜索引擎略有区别的商业模式:即和门户网站合作,百度按照搜索访问量分成,这种付费模式在当时颇受门户网站的欢迎,包括新浪、网易在内的各大门户网站都采用了百度提供的服务。
但这种模式很快显示了局限性。门户网站数量的有限性决定了其需求的有限性。2001年初,李彦宏借用了Overtu r e 的“付费排名”搜索引擎商业模式,客户通过购买关键字并进行竞价,决定其在搜索结果中排名的先后,并通过上下文内容分析技术,将广告同时投放于其他顶尖级搜索引擎,与这些合作伙伴共同分享利益。2002至2003年,竞价排名迅速成为百度主要收入来源,2004年百度80%收入来自竞价排名。
目前百度是浏览量中国第二、世界第六的网站。数据显示,中国网络用户有48%的搜索请求是通过百度完成的,因此百度有全球最大中文搜索引擎之称。艾瑞咨询数据显示:2004年中国搜索引擎行业市场规模为12.5亿元,其中搜索引擎运营商收入规模为6.35亿,渠道代理商收入为6.2亿元,而百度占据了中国搜索引擎运营商收入市场份额的28%。独特的商业模式的成功,使百度迅速成为中文搜索引擎的老大。
由于中文的复杂性,百度的搜索技术非常复杂,公司开发了特殊的语言处理技术来处理相似搜索结果。截至到目前,百度已经链接了6.9亿页网页,8000万张图片以及1000万个媒体文件。它还包括新闻、贴吧和其他内容。
市盈率之忧对百度来说,首日上市的优异表现是良好的开端。但“良好的开端是成功的一半”,海外资本市场并非坦途。从新浪、网易等先行者身上可以发现,其股价表现并不乏大起大落之先例,以网易为例,2001年一度到达0.51美元最低价。资本的残酷逐利性决定了一家企业一旦未能达到华尔街的预期,股价出现暴跌极为正常。
百度上市首日的优异表现,股价的迅速拔高,已经迅速使市盈率水平脱离了市场平均水平。这成为今后股价表现之隐忧,一旦公司成长性跟不上市场预期,即有可能导致股价水平的迅速回落。
百度2004年的利润为1200万元,收入为1.11亿元,2003年则亏损890万元。05年第一季度的盈利猛增了140%,达到250万元。根据百度在招股说明书中公布的财务数据,百度股票发行价的市盈率达到540倍,周五收盘价的市盈率达到2450.8倍,颇为惊人。作为对比数据,Google 市盈率8月6日为85.66倍。在纳斯达克上市的其他兄弟网络概念股的市盈率也基本在30-50倍之间。即使百度仍然保持原200%以上的业绩增幅,其目前股价仍然有高估之嫌。
此外,百度在搜索领域并非无敌手,Google 对中国市场窥视已久,对百度的虎视眈眈也是路人皆知,Google 目前持有百度2.6%的股份,其进入中国市场选择并购还是单独发展,后续事态发展将影响到百度的市场表现。虽然中文搜索的复杂性以及本土文化的适应性,使国外资本想占领中国市场并非易事,但其资本实力雄厚,加上品牌优势,仍不可小视。
而对于百度的重要利润来源“竞价排名”也已经有质疑之声出现,这种以出价高低决定搜索排名的商业模式有损于搜索引擎保持公正客观。信息干扰的出现,将使网民对搜索的依赖程度降低。而百度目前的MP3、图片、电影搜索等服务也面临版权的法律纠纷,虽然不足以影响百度大局,但对于百度其他商业模式的推广仍然带来一定障碍。

百度,2000年1月创立于北京中关村,是全球最大的中文搜索引擎。
2000年1月1日,公司创始人李彦宏、徐勇携120万美元风险投资,从美国硅谷回国,创建了百度公司。创立之初,百度就将自己的目标定位于打造中国人自己的中文搜索引擎,并愿为此目标不懈的努力奋斗。

2000年5月,百度首次为门户网站——硅谷动力提供搜索技术服务,之后迅速占领中国搜索引擎市场,成为最主要的搜索技术提供商。2001年8月,发布Baidu.com搜索引擎Beta版,从后台服务转向独立提供搜索服务,并且在中国首创了竞价排名商业模式,2001年10月22日正式发布Baidu搜索引擎。

2005年8月5日,百度在美国纳斯达克上市,成为2005年全球资本市场上最为引人注目的上市公司,百度由此进入一个崭新的发展阶段。

下午去看<变形金刚2>先看下网上怎么说的

Posted by ms-adobe on 六月 25th, 2009

gy0302714081hrv01-660-optimus-status

地球上的战争虽然结束,但变形金刚之间的战争并未告终。红蜘蛛飞回塞博坦星球,打算带着霸天虎军队再回地球与汽车人一决死战。汽车人发现威震天的尸体不见了,原来已被萨克巨人偷走,威震天随后被再次激活,决心反攻汽车人。与此同时,红蜘蛛也率领塞博坦的援军赶来。一直生活在地球人类之间的汽车人这时也已经增强了自己的战斗力,一场大战所难免。男孩儿山姆因为掌握了有关变形金刚的起源以及古老时期到访地球的线索而遭到霸天虎的追击。霸天虎为了获取这些信息,妄图生擒山姆。汽车人、美军和其它多国部队联合起来抵抗霸天虎的袭击。最后人类和汽车人战胜了霸天虎,地球恢复了和平。

缺点一:美军和《变形金刚1》时一样,前面很软弱,后面暴强。导演呀,你说你拍《变1》的时候没钱,要美军方赞助。但是,天下没有白吃的午餐,你因此要美化美军,这我们可以理解。但是拍本片时,你有钱了,干嘛还要这么做呢??一个毛病,犯两次,实在是……

缺点二:犯了和86版大电影一样的毛病。不知大家在看86版大电影时,有没有这样的感觉,OP挂了之后,大电影就不好看了。这句话放在本片这儿也同样适用。本片从开场到丛林大战,都是成功的。不知为什么,从OP挂了之后,到大力神出场这段时间,居然就没什么打戏,当然期间也有一些打戏,但这些打戏,加起来不会超过十分钟。用足球术语来,这段时间成了“垃圾时间”。而且,和《变1》相比,《变1》的打戏虽少,但很紧凑;本片打戏虽多,但很散!

缺点三:有些桥段,抄袭痕迹太明显。有一个镜头是直接抄袭《变1》的;沙漠里有一个桥段,就抄袭了《黑鹰坠落》;而学校里的那个女霸天虎感觉就是《终结者3》里的T-X。导演,你抄袭也就算了,可拜托你抄的有点水平好不好,别让观众一眼就看出来了。

当然,本片还是有亮点的。

亮点一:本片的特技水平比《变形金刚1》有了大幅度的提高。

亮点二:个人认为,丛林大战是两部《变形金刚》真人版中最经典的桥段!

亮点三:本片的搞笑水平也比《变形金刚1》高多了。

亮点四:天火爷爷也是蛮可爱的,他的表演很出彩。

《变形金刚1》里,我最喜欢的人类角色就是那个国防部长了,但是这次国防部长没有来,我很失望!

有人对大力神的没用感到失望,我不觉得,因为只要看过G1就知道,其实大力神本来就挺没用的!

我一直觉得《变形金刚1》是经典,而且我看了N次。但是本片我看过一次就没有想看第二次的欲望了!

总之,《变形金刚2》已无法达到《变形金刚1》的辉煌程度!

导演,我记得你说过,你想先去拍一部别的电影,再回来拍《变开金刚3》。你就把后半句话去掉算了——你别回来拍《变开金刚3》了吧!


Copyright © 2007 ms-adobe. All rights reserved.