基于Mozilla平台的扩展开发(续)----XPCOM组件篇

<link rel="File-List" href="file:///C:%5CDOCUME%7E1%5Cdyk%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><style> <!-- /* Font Definitions */ &#64;font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} &#64;font-face {font-family:Verdana; panose-1:2 11 6 4 3 5 4 4 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:536871559 0 0 0 415 0;} &#64;font-face {font-family:"/&#64;宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} a:link, span.MsoHyperlink {color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {color:purple; text-decoration:underline; text-underline:single;} /* Page Definitions */ &#64;page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} &#64;page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} --> </style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]-->

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="ProgId" content="Word.Document"><meta name="Generator" content="Microsoft Word 11"><meta name="Originator" content="Microsoft Word 11"><link rel="File-List" href="file:///C:%5CDOCUME%7E1%5Cdyk%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml"><!--[if gte mso 9]><xml> <w:WordDocument> <w:View>Normal</w:View> <w:Zoom>0</w:Zoom> <w:PunctuationKerning/> <w:DrawingGridVerticalSpacing>7.8 磅</w:DrawingGridVerticalSpacing> <w:DisplayHorizontalDrawingGridEvery>0</w:DisplayHorizontalDrawingGridEvery> <w:DisplayVerticalDrawingGridEvery>2</w:DisplayVerticalDrawingGridEvery> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:Compatibility> <w:SpaceForUL/> <w:BalanceSingleByteDoubleByteWidth/> <w:DoNotLeaveBackslashAlone/> <w:ULTrailSpace/> <w:DoNotExpandShiftReturn/> <w:AdjustLineHeightInTable/> <w:BreakWrappedTables/> <w:SnapToGridInCell/> <w:WrapTextWithPunct/> <w:UseAsianBreakRules/> <w:DontGrowAutofit/> <w:UseFELayout/> </w:Compatibility> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--><style> <!-- /* Font Definitions */ &#64;font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} &#64;font-face {font-family:Verdana; panose-1:2 11 6 4 3 5 4 4 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:536871559 0 0 0 415 0;} &#64;font-face {font-family:"/&#64;宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋体; mso-font-kerning:1.0pt;} a:link, span.MsoHyperlink {color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {color:purple; text-decoration:underline; text-underline:single;} /* Page Definitions */ &#64;page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} &#64;page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} --> </style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:普通表格; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0cm 5.4pt 0cm 5.4pt; mso-para-margin:0cm; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-fareast-font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]-->

源代码下载:HelloWorld示例.rar


在《浅谈基于Mozilla ThunderBird的扩展开发》这篇入门文章中简单介绍了基于Mozllia平台进行扩展开发的基础知识,但仍然欠缺最为重要的一种武器---没错,XPCOM!这篇文章就是为它准备的。

XPCOM是什么?

这个问题不多做解释了,相信XPCOM对于了解COM技术的人来说很快就可以上手开发了,下列是Mozilla官方给出的一些XPCOM知识的入门资源:

个人尤其推荐IBM developerworks上那5篇文章。

使用已有的XPCOM

XPCOM的使用十分简单,Mozilla平台已经为我们提供了许多功能强大的XPCOM组件了,如果你需要某方面功能的组件,请先看看Mozilla平台下是不是已经有对应的了,别再自己造轮子了

关于这方面也不打算再多说了,有兴趣的朋友可以阅读IBM developerworks下面这篇文章,《实战 Firefox 扩展开发》,相信通过这样一个图片批量下载工具的开发,就会对于Mozilla平台下已有的XPCOM组件的使用有所了解的。


So,what's next?

没错,自己如何开发XPCOM组件并在扩展中使用。网上对于这方面的资料不是很多,而且没有特别完整的示例,这就是我写这篇文章的目的所在,通过一个简单的XPCOM组件的开发全过程,展示XPCOM组件的内部细节。

项目目标:

组件要实现的功能非常简单,就只提供一个做加法的接口供客户调用。

long Add(in long a, in long b);

然后在扩展中调用这个加法接口。

准备工作

0,按照《浅谈基于Mozilla ThunderBird的扩展开发》这篇文章建立起开发扩展的基本环境。

1、下载Gecko SDK

http://ftp.mozilla.org/pub/mozilla.org/mozilla/releases/mozilla1.8b1/gecko-sdk-i586-pc-msvc-1.8b1.zip ,我们需要使用它来对IDL定义进行解释。

2、创建GUID

使用微软的的guidgen 生成GUID,例如b7b04070-45fc -4635- b219<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="True" hasspace="False" sourcevalue="7" unitname="a"><span style="font-size: 10pt; font-family: Verdana;" lang="EN-US">-</span><span style="font-size: 10pt; font-family: Verdana;" lang="EN-US">7a</span></chmetcnv><chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="172" unitname="F"><span style="font-size: 10pt; font-family: Verdana;" lang="EN-US">172f</span></chmetcnv>806bee

4,从C:/mozilla-build/moztools-180compat/bin下拷贝libIDL-0.6.dllglib-1.2.dll/gecko-sdk-i586-pc-msvc-1.8b1/gecko-sdk/bin下,否则运行xpidl会报错.

开发XPCOM组件

1,创建接口文件定义

None.gif #include " nsISupports.idl "
None.gif[scriptable,uuid(b7b04070
- 45fc - 4635 - b219 - 7a172f806bee)]
None.gif
interface IMyComponent:nsISupports
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
longAdd(inlonga,inlongb);
ExpandedBlockEnd.gif}
;
None.gif

2、使用Gecko SDK xpidl.exe
进入xpidl所在目录,在CMD中输入命令

None.gif xpidl-mheader-I ../ idlIMyComponent . idl(这里应该是IDL定义文件的实际路径)
None.gifxpidl-mtypelib-I
../ idlIMyComponent . idl
None.gif

如果上面执行有问题的话,可以将

None.gif/gecko-sdk-i586-pc-msvc-1.8b1/gecko-sdk/bin;/gecko-sdk-i586-pc-msvc-1.8b1/gecko-sdk/idl;/gecko-sdk-i586-pc-msvc-1.8b1/gecko-sdk/include;

加入到环境变量的PATH里面去

如果上述命令执行通过,在/gecko-sdk-i586-pc-msvc-1.8b1/gecko-sdk/bin就会得到IMyComponent.hIMyComponent.xpt 2个文件。

2、创建新文件

根据IMyComponent.h创建文件MyComponent.hMyComponent.cppMyComponentModule.cpp

ExpandedBlockStart.gif ContractedBlock.gif /**/ /*MyComponent.h*/
None.gif
None.gif
#pragma once
None.gif
None.gif#ifndef_MY_COMPONENT_H_
None.gif
#define _MY_COMPONENT_H_
None.gif
None.gif#include
" IMyComponent.h "
None.gif
#define MY_COMPONENT_CONTRACTID"@mydomain.com/XPCOMSample/MyComponent;1"
None.gif
#define MY_COMPONENT_CLASSNAME"ASimpleXPCOMSample"
None.gif
#define MY_COMPONENT_CID{0xb7b04070,0x45fc,0x4635,{0xb2,0x19,0x7a,0x17,0x2f,0x80,0x6b,0xee}}
None.gif
None.gif
None.gif
class MyComponent: public IMyComponent
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
public:
InBlock.gifNS_DECL_ISUPPORTS
InBlock.gifNS_DECL_IMYCOMPONENT
InBlock.gifMyComponent(
void);
InBlock.gif
~MyComponent(void);
ExpandedBlockEnd.gif}
;
None.gif
#endif
None.gif

None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**/ /*MyComponent.cpp*/
None.gif#include
" StdAfx.h "
None.gif#include
" MyComponent.h "
None.gif
None.gifNS_IMPL_ISUPPORTS1(MyComponent,IMyComponent)
None.gif
None.gifMyComponent::MyComponent(
void )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}

None.gif
None.gifMyComponent::
~ MyComponent( void )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}

None.gif
None.gifNS_IMETHODIMPMyComponent::Add(PRInt32a,PRInt32b,PRInt32
* _retval)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
*_retval=a+b;
InBlock.gif
returnNS_OK;
ExpandedBlockEnd.gif}

None.gif


ExpandedBlockStart.gif ContractedBlock.gif /**/ /*MyComponentModule.cpp*/
None.gif#include
" StdAfx.h "
None.gif#include
" nsIGenericFactory.h "
None.gif#include
" MyComponent.h "
None.gif
None.gifNS_GENERIC_FACTORY_CONSTRUCTOR(MyComponent)
None.gif
None.gif
static nsModuleComponentInfocomponents[] =
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMY_COMPONENT_CLASSNAME,
InBlock.gifMY_COMPONENT_CID,
InBlock.gifMY_COMPONENT_CONTRACTID,
InBlock.gifMyComponentConstructor,
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}
;
None.gif
None.gifNS_IMPL_NSGETMODULE(
" MyComponentsModule " ,components)
None.gif

编译XPCOM组件

1、创建工程

使用VC2005,创建新的DLL工程,将IMyComponent.h MyComponent.hMyComponent.cppMyComponentModule.cpp添加到工程中。

2、工程配置

None.gif1)c/c++GeneralAdditionalIncludeDirectories中设置为/gecko-sdk-i586-pc-msvc-1.8b1/gecko-sdk/include
None.gif
2)c/c++PreprocessorPreprocessorDefinitions中加入MYCOMPONENT_EXPORTS,XPCOM_GLUE
None.gif
3)c/c++CodeGenerationRuntimeLibrary中设置为Multi-threadedDLL(/MD)
None.gif
,这里非常重要,否则编译会报错的!!。
None.gif
4)LinkerAdditionalLiberaryDirectoryse设置为/gecko-sdk-i586-pc-msvc-1.8b1/gecko-sdk/lib
None.gif
5)LinkerAdditionalDepenendies加入nspr4.libplds4.libplc4.libxpcomglue.lib
None.gif

3、编译生成MyComponent.dll

在扩展中使用XPCOM组件

对《浅谈基于Mozilla ThunderBird的扩展开发中的helloworld项目进行修改,加入一个文件夹components和一个安装文件install.js
2008042501.jpg

关于这两个东西具体的含义这里就不多做介绍了,简单点说
,intall.js就是把XPCOM组件注册到Mozilla平台中去,就类似于Windows的注册表一样,从而可以使用组件。

1Install.js的内容:

None.gif//Installscriptforhelloworld
None.gif

None.gif
varerr;
None.gifconstAPP_VERSION
="0.0.0.1";//版本号
None.gif

None.gif
//初始化安装
None.gif
err=initInstall("helloworld"+APP_VERSION,//nameforinstallUI
None.gif
"/helloworld",//registeredname
None.gif
APP_VERSION);//packageversion
None.gif
if(err!=0)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{//安装出错,取消安装
InBlock.gif
cancelInstall(err);
ExpandedBlockEnd.gif}

None.gif
None.gif
//标准目录
None.gif
varfProgram=getFolder("Program");//程序根目录
None.gif
varfChrome=getFolder("Chrome");//chrome目录
None.gif
varfComponents=getFolder("Components");//components目录
None.gif

None.gif
//workaroundforMozilla1.8a3andnewer,failingtoregisterenigmimecorrectly
None.gif
vardelComps=["compreg.dat"];//Componentsregistry
None.gif
for(varj=0;j<delComps.length;j++)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
vardelFile=getFolder(fComponents,delComps[j]);
InBlock.gif
if(File.exists(delFile))
InBlock.gifFile.remove(delFile);
ExpandedBlockEnd.gif}

None.gif
None.giferr
=getLastError();
None.gif
if(err==DOES_NOT_EXIST)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
//errorcode:filedoesnotexist
InBlock.gif
resetError();
ExpandedBlockEnd.gif}

None.gif
elseif(err!=SUCCESS)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifcancelInstall(err);
ExpandedBlockEnd.gif}

None.gif
None.gif
//addDirectory:blank,archive_dir,install_dir,install_subdir
None.gif
addDirectory("","components",fComponents,"");
None.gifaddDirectory(
"","chrome",fChrome,"");
None.gif
None.gif
None.giferr
=getLastError();
None.gif
if(err==ACCESS_DENIED)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifalert(
"Unabletowritetocomponentsdirectory"+fComponents+"./nYouwillneedtorestartthebrowserwithadministrator/rootprivilegestoinstallthissoftware.Afterinstallingasroot(oradministrator),youwillneedtorestartthebrowseronemoretime,asaprivilegeduser,toregistertheinstalledsoftware./nAfterthesecondrestart,youcangobacktorunningthebrowserwithoutprivileges!");
InBlock.gifcancelInstall(ACCESS_DENIED);
InBlock.gif
ExpandedBlockEnd.gif}

None.gif
elseif(err!=SUCCESS)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifcancelInstall(err);
InBlock.gif
ExpandedBlockEnd.gif}

None.gif
else
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
//Registerchrome
InBlock.gif
registerChrome(PACKAGE|DELAYED_CHROME,getFolder("Chrome","helloworld.jar"),"content/helloworld/");
InBlock.giferr
=getLastError();
InBlock.gif
if(err!=SUCCESS)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifcancelInstall(err);
ExpandedSubBlockEnd.gif}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifperformInstall();
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}

None.gif

2)在Componts文件夹中加入MyComponent.dllIMyComponent.xpt


3
)修改overlay.js如下:

None.gif // Thisisthemainfunction
None.gif
constENIG_C = Components;
None.gifconstENIG_ENIGMAIL_CONTRACTID
= " @mydomain.com/XPCOMSample/MyComponent;1 "
None.gif
var gEnigmailSvc = null ;
None.gif
None.gif
function helloWorld()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
try
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifalert(
"准备创建组件");
InBlock.gifgEnigmailSvc
=ENIG_C.classes[ENIG_ENIGMAIL_CONTRACTID].createInstance(ENIG_C.interfaces.IMyComponent);//创建实例
InBlock.gif
if(gEnigmailSvc!=null)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifalert(
"创建组件成功");
InBlock.gifgEnigmailSvc
=gEnigmailSvc.QueryInterface(ENIG_C.interfaces.IMyComponent);
ExpandedSubBlockEnd.gif}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifalert(
"创建组件失败");
InBlock.gif
return;
ExpandedSubBlockEnd.gif}

InBlock.gif
varres=gEnigmailSvc.Add(3,4);
InBlock.gifalert(
'Performing3+4.Returned'+res+'.');
InBlock.gifalert(
"创建结束");
ExpandedSubBlockEnd.gif}

InBlock.gif
catch(ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifalert(
"error");
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}

None.gif


好了,到此就完成了这个最简单的XPCOM组件的开发了,enjoy it!

Reference


1,VCXPCOM

2, http://enigmail.mozdev.org/home/index.php


需要完整代码的,请发email至 phinecos@163.com,也欢迎有兴趣的朋友们一起来交流Mozilla的扩展开发技术

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值