中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
在Dashboard Widget中嵌入Cocoa(图片贴不上去T_T)
作者:未知 时间:2005-07-27 23:24 出处:CSDN 责编:chinaitpower
              摘要:在Dashboard Widget中嵌入Cocoa(图片贴不上去T_T)

Dashboard Widget中嵌入Cocoa

Author: Michael Marmarou

译者:欧嘉蔚

对牛弹吉他翻译练习 Ver 1.0

 

l         导言

你是否需要在Dashboard widget中嵌入Cocoa对象呢?如果答案是需要的话,那么你就读对了文章了。这篇文章还会让你了解到Dashboard的内部是怎么工作的。通常来说,Widget是以 HTMLCSSJavaScript的结合的形式展示的,你所看到的只是这些技术所联合起来显示的一些图像。 JavaScript建立一些控件,而他们的消息会被传回一个可以使用系统功能的Cocoa束(Cocoa Bundle)。而这个教程会为你展示一种直接访问Dashboard背后的Cocoa内核的方法。

尽管你是可以把Cocoa对象添加到Widget里面,但是我们的行为和普通的Cocoa程序会有差异。作为免责声明,这个我写这个文档是为了纯粹的教学目的,如果出了什么问题,我不会负任何责任的。Dashboard不是一个被保护的环境,我也曾经让它崩溃过很多次。我个人并不认为这些方法是“Hacks”,因为Dashboard的设计者看来是有意而且直接的开放了这能力。

因为所有的层次的程序员都可以做Dashboard Widget,所以这里会提供一点基础知识。我假设阅读这个文档的程序员都懂得Objective-C并且可以熟练地使用XCode

 

l         Dashboard是怎么工作的:

       对于用户和程序员来说Dashboard进程是被隐藏的。真实的应用程序位置是在Dock.app包里面(/System/Library/CoreServices),它是Dock的子进程。对于程序员来说,如果你的Dashboard崩溃了,你必须重新启动Dock来重置它。在后面会有一些关于调试的章节。

       最好的方式是把Dashboard看成一个巨大的浏览器。或者,很好的描述是:在一个灰色背景上的一堆浏览器。每个widget是一个被封装在一个WebFrameView(DBFrameView)里面的WebView(实际上是一个子类叫做DashboardWebView)。这些类的实际名字并不重要因为他们是私有类。因为我们没有那些头文件,我们不能知道有什么方法可调用。当然,在Cocoa中和Widget协同工作并不就是修改DashboardView那么简单。有很多东西你不能做,随着我们一步一步地研究在一个Widget里面我们有什么能够做有什么不能做,很多的限制会被讨论到。

 

镜像TextView的例子

l         目标:

       这个例子会展示一些基本原理,如何加入一个子视图,放置一个子视图,访问它的代理。两个NSTextView会被加进一个空白的画布(canvas),并且设置一个代理,其中的一个Textview会通过代理来更新。这个例子只是为了展示如何加入Cocoa对象,并且让你了解从它们那里获取事件是十分简单的。如果你不知道怎么在通过代码(译者:不是使用Interface Builder)创建Cocoa对象,我强力建议你先花点时间在上面,因为这个工具在所有的Cocoa编程中都非常有用。

 

l         基础:

       Widget能被显示之前,有几样东西是必须的。缺少一个或者是一个错误的值都回让你的Widget不能显示,或者显示不正常(还会让你郁闷几个小时)。所以,在开始构建插件(plugin)之前,在Widget的目录下有一个符合标准的基础结构,是非常重要的。在这个例子里面,我们会从零开始建立一个新的Widget。尽管在开发者文档的例子里(/Developer/Examples/Dashboard/Sample Code)有一个空白的Widget。为了更好的理解一个Widget的每一部分,并且确保没有东西被忽略掉,我们还是从零开始建立一个Widget   进入你的工作文件夹(就是你想把你要建立的那个最终会变成Widget的文件夹所放置的地方)。建立一个新的文件夹,命名为“embeddedCocoa.widget”。你可能会想:“那个扩展名不是‘.wdgt’吗?”是的,没错。但是为了避免经常要使用终端,鉴别,或者按着control点击再选显示包内容。我们还是让扩展名继续为‘.widget’。直到我们要开始使用我们的Widget

       每个Widget都需要两个plistinfo.plist version.plist。打开‘Property List Editor.app (/Developer/Applications/Utilities/),建立一个新的文件。建立一个新的根(Root),建立下面的子节点,和下面的相关联的值。

 

BundleVersion

String

219

CFBundleShortVersionString

String

1.0

CFBundleVersion

String

1.0

ProjectName

String

DashboardSDK

SourceVersion

String

20000

 

现在,并不要在意这些值的意义,但是他们是必须存在的。把文件保存为version.plist并且放置在embeddedCocoa.widget里面。建立一个新文件,建立一个根,再加入下面的子节点:

 

AllowMultipleInstances

Boolean

No

CFBundleIdentifier

String

com.apple.widget.embeddedcocoa

CFBundleName

String

embeddedCocoa

CFBundleShortVersionString

String

1.0

CFBundleVersion

String

1.0

DefaultImage

String

Default

Height

Number

205

MainHTML

String

embeddedCocoa.html

Plugin

String

embeddedCocoa.widgetplugin

Width

Number

300

 

AllowMultipleInstances 的意义非常直接。CFBundleIdentifier 对我们来说并不重要,但是要确保它的值是正确的。如果多于一个Widget有相同的值就会有问题了。DefaultImage 很重要,如果没有默认图片Widget就不会被加载了。他不会一直显示(译者:实际上,它只在主HTML没有加载的时候显示),我希望在最终版本中不再需要这个了,不过现在你还是需要一个默认图片(PNG格式的)。MainHTML 是就是WebView会频繁地加载的页面,所以也是非常重要的。Plugin 标识了最终会被放在同一个文件夹里面的插件捆束(plugin bundle)。

这文档里面会包含一些范例代码,但是,这不是必需的。如果你确实有一些范例,在随便在其中的一个范例里面找一个Default.png 文件。如果你没有这些范例,没关系,就随便建立一个图像文件,并且重命名它。任何的PNG图像都可以用,不过我会避免让它大于4GB,尽管这样的文件真的有可能存在。

       现在,我们必须要建立一个HTML文件。用你手头上任意一个文本编辑器建立一个新的文件。有趣的是,这个文件可以是完全空白的。不过当前你可能会要加入一个简单的HTML和一个body标签来显示背景图片。

<html>

<body>

<img src=”Default.png”>

</body>

</html>

 

       现在我们需要测试这Widget来确保所有东西都正常的工作。把文件夹重命名为‘embeddedCocoa.wdgt’。这个文件夹会马上把自己的图标变为Dashboard Widget的图标。双击这个图标看看Widget是否加载。如果没有加载,可能是你打错了那些plist中的一个值,缺少了一个文件或者命名不正确,又或者就是Dashboard不喜欢你了。

 

l         创建捆束

打开Xcode (/Developer/Applications/)。创建一个新的Cocoa捆束,在菜单下选择“New Project…

在模版列表中,选择“Cocoa Bundle”。把捆束命名为“embeddedCocoa”。这个新建的捆束会没有基础的类,所以我们需要自己创建一个。选择类文件夹(Classes folder),双击它,然后选择‘Add’再选择‘New File…’。

从显示出来的表单中,选择‘Objective-C class’。这是一个从NSObject类派生的Objective-C类。

       请确保创建了两个文件(embeddedCocoa.h embeddedCocoa.m),并且他们被放置在‘Classes’文件夹。如果不是这样的,请把它们拖到那儿。有两个方法是必须被声明的,但是有一个现在还不会用到。尽管不被用到,他们必须在头文件和实现文件中出现。头文件应该像这样子的:

 

#import <Cocoa/Cocoa.h>

#import <WebKit/WebKit.h>

@interface embeddedCocoa : NSObject

{

WebView *webView;

NSTextView *textView;

 

NSTextView *textViewMirror;

}

- (id) initWithWebView:(WebView*)webView;

- (void) windowScriptObjectAvailable:(WebScriptObject* )windowScriptObject;

@end

 

                                                                                                                                        

       在这里,我们导入了CocoaWebKit两个框架。因为WebView是在WebKit框架中声明的,所以它必须被导入。WebView是一个WebView的引用,它在initWithWebView里被传入对象。我们还声明了两个NSTextView。我们会保留对这些对象的引用,这样我们就可以在进程的生命周期中的任何时间点修改他们的内容。为了使插件工作,那两个方法必须声明。

       在实现文件,有一个init方法。用户可以通过这个函数来初始化捆束、实例变量和做任何完成的工作。尽管这看来不是设计者的初衷,但是我们还是窃取它所接受的WebView,并且在上面耍小把戏。那个init函数应该像这样子的:

#import "embeddedCocoa.h"

@implementation embeddedCocoa

-(id) initWithWebView:(WebView*)wview

{

/* Top TextView */

textView = [[NSTextView alloc] initWithFrame:NSMakeRect(0,105,300,100)];

NSClipView *clipView = [[NSClipView alloc] init]; //Initialize ClipView

[clipView setDocumentView:textView]; //Add TextView as subview

[clipView setFrame:NSMakeRect(0,105,300,100)]; //Set frame

NSScrollView *scrollView = [[NSScrollView alloc] init];//Initialize ScrollView

[scrollView setDocumentView:clipView]; //Add ClipView as subview

[scrollView setFrame:NSMakeRect(0,105,300,100)]; //Set frame

/* Mirror TextView */

textViewMirror = [[NSTextView alloc] initWithFrame:NSMakeRect(0,0,300,100)];

NSClipView *clipViewMirror = [[NSClipView alloc] init];

[clipViewMirror setDocumentView:textViewMirror];

[clipViewMirror setFrame:NSMakeRect(0,0,300,100)];

NSScrollView *scrollViewMirror = [[NSScrollView alloc] init];

[scrollViewMirror setDocumentView:clipViewMirror];

[scrollViewMirror setFrame:NSMakeRect(0,0,300,100)];

[wview addSubview:scrollView]; //Adds the subview to the main WebView

[wview addSubview:scrollViewMirror]; //Adds the subview to the main Webview

[textView setString:@"Type here, and it will be mirrored..."];

[textViewMirror setString:@"...down here."];

[textView setDelegate:self];