Xul调用Xpcom组件完整例子 这几天在研究Xul ,调试通过了一个Xul做界面,通过js调用c++开发的xpcom的例子。感觉步骤比较繁杂,以前没有用过VS200X工具,配置环境也颇费了点时间,所以就把整个开发过程作了一个记录。 总体过程分三步: 1,开发xpcom; 2,写xul界面; 3,调用编译好的xpcom组件。 下面详写每一步详细步骤。 第一步:使用c++开发xpcom。工具是visual studio 2005。1, 首先下载Gecko SDK,这个是xpcom的开发包,开发xpcom组件时要用到其中的资源:下载地址: 2, 另外Gecko SDK中需要用到wintools.zip中的资源。 下载地址:http://ftp.mozilla.org/pub/mozilla.org/mozilla/source/wintools.zip 3, 将wintools.zip解压,从wintools\buildtools\windows\bin\x86目录中复制glib-1.2.dll 、libIDL-0.6.dll ,拷贝到\gecko-sdk\bin目录下。 4, 创建idl。(例如:comp.idl,内容如下 #include "nsISupports.idl" [scriptable, uuid(A037CC48-2EF0-47ad-B59E-ACCC4B89AD2B)]interface ISpecialThing : nsISupports{ long add(in long a, in long b); attribute AString name;};注意:idl中的uuid需要修改一下,在vc++的菜单里面有一个工具可以生成guid.工具-〉创建guid,使用生成的这个guid填入idl文件中的uuid的括号里面。如图:file:///C:/Users/HECHEN~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg 5, 建立组件。 5.1 使用Gecko SDK编译idl文件。因为本人一向对路径问题头疼,所以直接将idl文件放到了\gecko-sdk\bin目录下。然后在“开始”—〉“运行”中输入cmd,打开命令行窗口后执行命令:xpidl.exe -m header-I..\idl comp.idl 执行后生成comp.h文件;再执行命令:xpidl.exe -m typelib -I..\idlcomp.idl 执行后生成comp.xpt文件. file:///C:/Users/HECHEN~1/AppData/Local/Temp/msohtmlclip1/01/clip_image004.jpg 5.2 建立一个头文件 comp-impl.h #ifndef __SPECIALTHING_IMPL_H__#define __SPECIALTHING_IMPL_H__ #include "comp.h"#include "nsStringAPI.h" #define SPECIALTHING_CONTRACTID "@starkravingfinkle.org/specialthing;1"#define SPECIALTHING_CLASSNAME "SpecialThing"#define SPECIALTHING_CID { 0x245626, 0x5cc1, 0x11db, { 0x96, 0x73, 0x0, 0xe0, 0x81, 0x61, 0x16, 0x5f } } class CSpecialThing : public ISpecialThing{public: NS_DECL_ISUPPORTS NS_DECL_ISPECIALTHING CSpecialThing(); private: ~CSpecialThing(); protected: /* additional members */ nsString mName;}; #endif 5.3建立一个cpp文件:comp-impl.cpp #include "comp-impl.h" NS_IMPL_ISUPPORTS1(CSpecialThing, ISpecialThing) CSpecialThing::CSpecialThing(){ /* member initializers and constructor code */ mName.Assign(L"Default Name");} CSpecialThing::~CSpecialThing(){ /* destructor code */} /* attribute AString name; */NS_IMETHODIMP CSpecialThing::GetName(nsAString & aName){ aName.Assign(mName); return NS_OK;}NS_IMETHODIMP CSpecialThing::SetName(const nsAString & aName){ mName.Assign(aName); return NS_OK;} /* long add (in long a, in long b); */NS_IMETHODIMP CSpecialThing::Add(PRInt32 a, PRInt32 b, PRInt32 *_retval){ *_retval = a + b; return NS_OK;}5.3建立模块代码。comp-module.cpp #include "nsIGenericFactory.h" #include "comp-impl.h" #include "stdafx.h" NS_GENERIC_FACTORY_CONSTRUCTOR(CSpecialThing) static nsModuleComponentInfo components[] = { { SPECIALTHING_CLASSNAME, SPECIALTHING_CID, SPECIALTHING_CONTRACTID, CSpecialThingConstructor, } }; NS_IMPL_NSGETMODULE("SpecialThingsModule",components) 6 建立dll工程 打开vs2005后,“新建”—〉“项目”,选择“其他语言”中的visual c++ ,然后选择“MFC DLL”,填写工程名称并选择路径。 file:///C:/Users/HECHEN~1/AppData/Local/Temp/msohtmlclip1/01/clip_image006.jpg 7 配置工程环境 7.1 加入Include文件夹。工程->属性-> 配置属性->C/C++ -> 常规 选项的“附加包含目录“中加入要包含的头文件的目录\gecko-sdk\include。例如:D:\gecko-sdk\include。 7.2 在工程属性设置的选项卡里面实现库的引用。 7.3 (1)工程->属性->配置属性->链接器-> 常规 选项里面进行下列设置: “附加库目录“设置库文件所在路径..\gecko-sdk\lib;链接库依赖项设置为Yes;使用库依赖项输入设置为Yes; file:///C:/Users/HECHEN~1/AppData/Local/Temp/msohtmlclip1/01/clip_image008.jpg 在工程->属性->配置属性->链接器-> 输入->附加依赖项中添加库的名称(nspr4.lib xpcom.lib xpcomglue_s.lib);多个库名称以空格隔开。 file:///C:/Users/HECHEN~1/AppData/Local/Temp/msohtmlclip1/01/clip_image010.jpg 7.4 工程->属性-> 配置属性->C/C++ -> 预处理器 修改预处理器定义,添加 XP_WIN;XP_WIN32 file:///C:/Users/HECHEN~1/AppData/Local/Temp/msohtmlclip1/01/clip_image012.jpg 7.5工程->属性-> 配置属性-> C/C++ ->预编译头-〉创建使用预编译头 改为不使用预编译头。 7.6为避免运行时报错:“error PRJ0003 : 生成 cmd.exe 时出错” 。 “工具”-〉“选项”->“项目和解决方案”->“VC目录“下添加 $(SystemRoot)\System32 $(SystemRoot) $(SystemRoot)\System32\wbem file:///C:/Users/HECHEN~1/AppData/Local/Temp/msohtmlclip1/01/clip_image014.jpg 8,将刚才建立的组件文件comp.h,comp-impl.h,comp-impl.cpp,comp-module.cpp添加到工程中。编译成功后开发xpcom组件的步骤完成。 第二步:开发xul界面,步骤在mozilla网站写的很清楚 第三步用自己写的xul界面调用xpom组件:1,部署组件:将第二步编译成功生成的dll文件和第一步编译idl文件生成的comp.xpt文件一同拷贝到自己的xul工程目录的components目录下(没有的话自己建一个,components目录和application.ini同级)。 2,更新注册:在你的 xul应用程序目录/application.ini中,找到BuildID后将值修改,改为原来的数字加1或加几都可以。 3,写javascript调用 这里有一个非常简单的只有一个按钮的mail.xul,其中红色字体部分是javascript调用组件的代码。 <?xml version="1.0"?> <?xml-stylesheet href="chrome://global/skin/"type="text/css"?> <window id="main" title="My App"width="300" height="300" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"xmlns:html="http://www.w3.org/1999/xhtml" persist="screenX screenYwidth height sizemode"> <vbox flex="1"> <hboxid="aContainer"> <html:table> <html:tr><html:td><buttonlabel="Normal"id="okbutton" /> <script> function buttonPressed(event){ //alert('Buttonwas pressed!'); try { const cid ="@starkravingfinkle.org/specialthing;1"; var obj =Components.classes[cid].createInstance(); obj =obj.QueryInterface(Components.interfaces.ISpecialThing); } catch (err) { alert(err); return; } var res =obj.add(3, 4); alert('3+4 = ' +res); var name =obj.name; alert('Name = ' +name); obj.name = 'NewName'; name = obj.name; alert('Name = ' +name); } var button =document.getElementById("okbutton"); button.addEventListener('command', buttonPressed, true); </script> </html:td><html:td>ok</html:td></html:tr> </html:table> </hbox> </vbox> </window> 运行结果如下 file:///C:/Users/HECHEN~1/AppData/Local/Temp/msohtmlclip1/01/clip_image016.jpg
|